Codebase list golang-google-appengine / ae884d2
Import upstream version 2.0.2+git20221116.1.504804f Debian Janitor 1 year, 5 months ago
159 changed file(s) with 36273 addition(s) and 431 deletion(s). Raw diff Collapse all Expand all
+0
-18
.travis.yml less more
0 language: go
1
2 go_import_path: google.golang.org/appengine
3
4 install:
5 - ./travis_install.sh
6
7 script:
8 - ./travis_test.sh
9
10 matrix:
11 include:
12 - go: 1.9.x
13 env: GOAPP=true
14 - go: 1.10.x
15 env: GOAPP=false
16 - go: 1.11.x
17 env: GO111MODULE=on
1818
1919 ## Running system tests
2020
21 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`.
22
2321 Set the `APPENGINE_DEV_APPSERVER` environment variable to `/path/to/go_appengine/dev_appserver.py`.
2422
25 Run tests with `goapp test`:
23 Run tests with `go test`:
2624
2725 ```
28 goapp test -v google.golang.org/appengine/...
26 go test -v google.golang.org/appengine/...
2927 ```
3028
3129 ## Contributor License Agreements
00 # Go App Engine packages
11
2 [![Build Status](https://travis-ci.org/golang/appengine.svg)](https://travis-ci.org/golang/appengine)
2 [![CI Status](https://github.com/golang/appengine/actions/workflows/ci.yml/badge.svg)](https://github.com/golang/appengine/actions/workflows/ci.yml)
33
44 This repository supports the Go runtime on *App Engine standard*.
55 It provides APIs for interacting with App Engine services.
7171 * `appengine/socket` is not required on App Engine flexible environment / Managed VMs.
7272 Use the standard `net` package instead.
7373
74 ## Key Encode/Decode compatibiltiy to help with datastore library migrations
74 ## Key Encode/Decode compatibility to help with datastore library migrations
7575
7676 Key compatibility updates have been added to help customers transition from google.golang.org/appengine/datastore to cloud.google.com/go/datastore.
7777 The `EnableKeyConversion` enables automatic conversion from a key encoded with cloud.google.com/go/datastore to google.golang.org/appengine/datastore key type.
0 //go:build appengine
01 // +build appengine
12
23 package aetest
1213 var aeOpts *aetest.Options
1314 if opts != nil {
1415 aeOpts = &aetest.Options{
15 AppID: opts.AppID,
16 AppID: opts.AppID,
1617 StronglyConsistentDatastore: opts.StronglyConsistentDatastore,
1718 }
1819 }
0 //go:build !appengine
01 // +build !appengine
12
23 package aetest
1617 "regexp"
1718 "time"
1819
19 "golang.org/x/net/context"
2020 "google.golang.org/appengine/internal"
2121 )
2222
5959 appDir string
6060 appID string
6161 startupTimeout time.Duration
62 relFuncs []func() // funcs to release any associated contexts
6362 }
6463
6564 // NewRequest returns an *http.Request associated with this instance.
7069 }
7170
7271 // Associate this request.
73 req, release := internal.RegisterTestRequest(req, i.apiURL, func(ctx context.Context) context.Context {
74 ctx = internal.WithAppIDOverride(ctx, "dev~"+i.appID)
75 return ctx
76 })
77 i.relFuncs = append(i.relFuncs, release)
78
79 return req, nil
72 return internal.RegisterTestRequest(req, i.apiURL, "dev~"+i.appID), nil
8073 }
8174
8275 // Close kills the child api_server.py process, releasing its resources.
8376 func (i *instance) Close() (err error) {
84 for _, rel := range i.relFuncs {
85 rel()
86 }
87 i.relFuncs = nil
8877 child := i.child
8978 if child == nil {
9079 return nil
189178 err = ioutil.WriteFile(filepath.Join(i.appDir, "app", "stubapp.go"), []byte(appSource), 0644)
190179 if err != nil {
191180 return err
181 }
182
183 datastorePath := os.Getenv("APPENGINE_DEV_APPSERVER_DATASTORE_PATH")
184 if len(datastorePath) == 0 {
185 datastorePath = filepath.Join(i.appDir, "datastore")
192186 }
193187
194188 appserverArgs = append(appserverArgs,
199193 "--skip_sdk_update_check=true",
200194 "--clear_datastore=true",
201195 "--clear_search_indexes=true",
202 "--datastore_path", filepath.Join(i.appDir, "datastore"),
196 "--datastore_path", datastorePath,
203197 )
204198 if i.opts != nil && i.opts.StronglyConsistentDatastore {
205199 appserverArgs = append(appserverArgs, "--datastore_consistency_policy=consistent")
3434 //
3535 // Main is designed so that the app's main package looks like this:
3636 //
37 // package main
37 // package main
3838 //
39 // import (
40 // "google.golang.org/appengine"
39 // import (
40 // "google.golang.org/appengine"
4141 //
42 // _ "myapp/package0"
43 // _ "myapp/package1"
44 // )
42 // _ "myapp/package0"
43 // _ "myapp/package1"
44 // )
4545 //
46 // func main() {
47 // appengine.Main()
48 // }
46 // func main() {
47 // appengine.Main()
48 // }
4949 //
5050 // The "myapp/packageX" packages are expected to register HTTP handlers
5151 // in their init functions.
5252 func Main() {
5353 internal.Main()
5454 }
55
56 // Middleware wraps an http handler so that it can make GAE API calls
57 var Middleware func(http.Handler) http.Handler = internal.Middleware
5558
5659 // IsDevAppServer reports whether the App Engine app is running in the
5760 // development App Server.
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package appengine
78
89 import (
9 "golang.org/x/net/context"
10
11 "google.golang.org/appengine/internal"
10 "context"
1211 )
1312
1413 // BackgroundContext returns a context not associated with a request.
15 // This should only be used when not servicing a request.
16 // This only works in App Engine "flexible environment".
14 //
15 // Deprecated: App Engine no longer has a special background context.
16 // Just use context.Background().
1717 func BackgroundContext() context.Context {
18 return internal.BackgroundContext()
18 return context.Background()
1919 }
88 This package does not work in App Engine "flexible environment".
99
1010 Example:
11
1112 if !capability.Enabled(c, "datastore_v3", "write") {
1213 // show user a different page
1314 }
1313
1414 A Go MySQL driver that has been tested to work well with Cloud SQL
1515 is the go-sql-driver:
16
1617 import "database/sql"
1718 import _ "github.com/go-sql-driver/mysql"
1819
1920 db, err := sql.Open("mysql", "user@cloudsql(project-id:instance-name)/dbname")
2021
22 Another driver that works well with Cloud SQL is the mymysql driver:
2123
22 Another driver that works well with Cloud SQL is the mymysql driver:
2324 import "database/sql"
2425 import _ "github.com/ziutek/mymysql/godrv"
2526
2627 db, err := sql.Open("mymysql", "cloudsql:instance-name*dbname/user/password")
27
2828
2929 Using either of these drivers, you can perform a standard SQL query.
3030 This example assumes there is a table named 'users' with
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build appengine
45 // +build appengine
56
67 package cloudsql
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package cloudsql
77 // A main func is synthesized if one does not exist.
88 //
99 // A sample Dockerfile to be used with this bundler could look like this:
10 // FROM gcr.io/google-appengine/go-compat
11 // ADD . /app
12 // RUN GOPATH=/app/_gopath go build -tags appenginevm -o /app/_ah/exe
10 //
11 // FROM gcr.io/google-appengine/go-compat
12 // ADD . /app
13 // RUN GOPATH=/app/_gopath go build -tags appenginevm -o /app/_ah/exe
1314 package main
1415
1516 import (
44 /*
55 Package datastore provides a client for App Engine's datastore service.
66
7
8 Basic Operations
7 # Basic Operations
98
109 Entities are the unit of storage and are associated with a key. A key
1110 consists of an optional parent key, a string application ID, a string kind
7372 Delete functions. They take a []*Key instead of a *Key, and may return an
7473 appengine.MultiError when encountering partial failure.
7574
76
77 Properties
75 # Properties
7876
7977 An entity's contents can be represented by a variety of types. These are
8078 typically struct pointers, but can also be any type that implements the
136134 J int `datastore:",noindex" json:"j"`
137135 }
138136
139
140 Structured Properties
137 # Structured Properties
141138
142139 If the struct pointed to contains other structs, then the nested or embedded
143140 structs are flattened. For example, given these definitions:
178175 If an outer struct is tagged "noindex" then all of its implicit flattened
179176 fields are effectively "noindex".
180177
181
182 The PropertyLoadSaver Interface
178 # The PropertyLoadSaver Interface
183179
184180 An entity's contents can also be represented by any type that implements the
185181 PropertyLoadSaver interface. This type may be a struct pointer, but it does
229225 The *PropertyList type implements PropertyLoadSaver, and can therefore hold an
230226 arbitrary entity's contents.
231227
232
233 Queries
228 # Queries
234229
235230 Queries retrieve entities based on their properties or key's ancestry. Running
236231 a query yields an iterator of results: either keys or (key, entity) pairs.
283278 io.Copy(w, b)
284279 }
285280
286
287 Transactions
281 # Transactions
288282
289283 RunInTransaction runs a function in a transaction.
290284
322316 fmt.Fprintf(w, "Count=%d", count)
323317 }
324318
325
326 Metadata
319 # Metadata
327320
328321 The datastore package provides access to some of App Engine's datastore
329322 metadata. This metadata includes information about the entity groups,
4949 // The properties are returned as a map of property names to a slice of the
5050 // representation types. The representation types for the supported Go property
5151 // types are:
52 // "INT64": signed integers and time.Time
53 // "DOUBLE": float32 and float64
54 // "BOOLEAN": bool
55 // "STRING": string, []byte and ByteString
56 // "POINT": appengine.GeoPoint
57 // "REFERENCE": *Key
58 // "USER": (not used in the Go runtime)
52 //
53 // "INT64": signed integers and time.Time
54 // "DOUBLE": float32 and float64
55 // "BOOLEAN": bool
56 // "STRING": string, []byte and ByteString
57 // "POINT": appengine.GeoPoint
58 // "REFERENCE": *Key
59 // "USER": (not used in the Go runtime)
5960 func KindProperties(ctx context.Context, kind string) (map[string][]string, error) {
6061 // TODO(djd): Support range queries.
6162 kindKey := NewKey(ctx, kindKind, kind, 0, nil)
475475 // The keys returned by GetAll will be in a 1-1 correspondence with the entities
476476 // added to dst.
477477 //
478 // If q is a ``keys-only'' query, GetAll ignores dst and only returns the keys.
478 // If q is a “keys-only” query, GetAll ignores dst and only returns the keys.
479479 //
480480 // The running time and number of API calls made by GetAll scale linearly with
481481 // the sum of the query's offset and limit. Unless the result count is
99 in a top-level assignment context, passing it an arbitrary string key
1010 and a function whose first argument is of type context.Context.
1111 The key is used to look up the function so it can be called later.
12
1213 var laterFunc = delay.Func("key", myFunc)
14
1315 It is also possible to use a function literal.
16
1417 var laterFunc = delay.Func("key", func(c context.Context, x string) {
1518 // ...
1619 })
1720
1821 To call a function, invoke its Call method.
22
1923 laterFunc.Call(c, "something")
24
2025 A function may be called any number of times. If the function has any
2126 return arguments, and the last one is of type error, the function may
2227 return a non-nil error to signal that the function should be retried.
3641 with pending function invocations should safe as long as the relevant
3742 functions have the (filename, key) combination preserved. The filename is
3843 parsed according to these rules:
39 * Paths in package main are shortened to just the file name (github.com/foo/foo.go -> foo.go)
40 * Paths are stripped to just package paths (/go/src/github.com/foo/bar.go -> github.com/foo/bar.go)
41 * Module versions are stripped (/go/pkg/mod/github.com/foo/bar@v0.0.0-20181026220418-f595d03440dc/baz.go -> github.com/foo/bar/baz.go)
44 - Paths in package main are shortened to just the file name (github.com/foo/foo.go -> foo.go)
45 - Paths are stripped to just package paths (/go/src/github.com/foo/bar.go -> github.com/foo/bar.go)
46 - Module versions are stripped (/go/pkg/mod/github.com/foo/bar@v0.0.0-20181026220418-f595d03440dc/baz.go -> github.com/foo/bar/baz.go)
4247
4348 There is some inherent risk of pending function invocations being lost during
4449 an update that contains large changes. For example, switching from using GOPATH
207212 }
208213
209214 // Call invokes a delayed function.
210 // err := f.Call(c, ...)
215 //
216 // err := f.Call(c, ...)
217 //
211218 // is equivalent to
212 // t, _ := f.Task(...)
213 // _, err := taskqueue.Add(c, t, "")
219 //
220 // t, _ := f.Task(...)
221 // _, err := taskqueue.Add(c, t, "")
214222 func (f *Function) Call(c context.Context, args ...interface{}) error {
215223 t, err := f.Task(args...)
216224 if err != nil {
22 // license that can be found in the LICENSE file.
33
44 // This example only works on App Engine "flexible environment".
5 //go:build !appengine
56 // +build !appengine
67
78 package main
22 // license that can be found in the LICENSE file.
33
44 // This example only works on App Engine "flexible environment".
5 //go:build !appengine
56 // +build !appengine
67
78 package main
22 go 1.11
33
44 require (
5 github.com/golang/protobuf v1.3.1
6 golang.org/x/net v0.0.0-20190603091049-60506f45cf65
7 golang.org/x/text v0.3.2
5 github.com/golang/protobuf v1.5.2
6 golang.org/x/net v0.0.0-20210525063256-abc453219eb5
7 golang.org/x/text v0.3.6
88 )
0 github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
1 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
2 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
3 golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
4 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
5 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
7 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
8 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
9 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
0 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
1 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
2 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
3 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
4 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
6 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
7 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
9 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
10 golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
11 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
1012 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
13 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
14 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
15 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
16 google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
17 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package internal
2223 "sync/atomic"
2324 "time"
2425
26 netcontext "context"
27
2528 "github.com/golang/protobuf/proto"
26 netcontext "golang.org/x/net/context"
2729
2830 basepb "google.golang.org/appengine/internal/base"
2931 logpb "google.golang.org/appengine/internal/log"
3133 )
3234
3335 const (
34 apiPath = "/rpc_http"
35 defaultTicketSuffix = "/default.20150612t184001.0"
36 apiPath = "/rpc_http"
3637 )
3738
3839 var (
6465 IdleConnTimeout: 90 * time.Second,
6566 },
6667 }
67
68 defaultTicketOnce sync.Once
69 defaultTicket string
70 backgroundContextOnce sync.Once
71 backgroundContext netcontext.Context
7268 )
7369
74 func apiURL() *url.URL {
70 func apiURL(ctx netcontext.Context) *url.URL {
7571 host, port := "appengine.googleapis.internal", "10001"
7672 if h := os.Getenv("API_HOST"); h != "" {
7773 host = h
7874 }
75 if hostOverride := ctx.Value(apiHostOverrideKey); hostOverride != nil {
76 host = hostOverride.(string)
77 }
7978 if p := os.Getenv("API_PORT"); p != "" {
8079 port = p
80 }
81 if portOverride := ctx.Value(apiPortOverrideKey); portOverride != nil {
82 port = portOverride.(string)
8183 }
8284 return &url.URL{
8385 Scheme: "http",
8688 }
8789 }
8890
89 func handleHTTP(w http.ResponseWriter, r *http.Request) {
90 c := &context{
91 req: r,
92 outHeader: w.Header(),
93 apiURL: apiURL(),
94 }
95 r = r.WithContext(withContext(r.Context(), c))
96 c.req = r
97
98 stopFlushing := make(chan int)
99
100 // Patch up RemoteAddr so it looks reasonable.
101 if addr := r.Header.Get(userIPHeader); addr != "" {
102 r.RemoteAddr = addr
103 } else if addr = r.Header.Get(remoteAddrHeader); addr != "" {
104 r.RemoteAddr = addr
105 } else {
106 // Should not normally reach here, but pick a sensible default anyway.
107 r.RemoteAddr = "127.0.0.1"
108 }
109 // The address in the headers will most likely be of these forms:
110 // 123.123.123.123
111 // 2001:db8::1
112 // net/http.Request.RemoteAddr is specified to be in "IP:port" form.
113 if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil {
114 // Assume the remote address is only a host; add a default port.
115 r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80")
116 }
117
118 // Start goroutine responsible for flushing app logs.
119 // This is done after adding c to ctx.m (and stopped before removing it)
120 // because flushing logs requires making an API call.
121 go c.logFlusher(stopFlushing)
122
123 executeRequestSafely(c, r)
124 c.outHeader = nil // make sure header changes aren't respected any more
125
126 stopFlushing <- 1 // any logging beyond this point will be dropped
127
128 // Flush any pending logs asynchronously.
129 c.pendingLogs.Lock()
130 flushes := c.pendingLogs.flushes
131 if len(c.pendingLogs.lines) > 0 {
132 flushes++
133 }
134 c.pendingLogs.Unlock()
135 flushed := make(chan struct{})
136 go func() {
137 defer close(flushed)
138 // Force a log flush, because with very short requests we
139 // may not ever flush logs.
140 c.flushLog(true)
141 }()
142 w.Header().Set(logFlushHeader, strconv.Itoa(flushes))
143
144 // Avoid nil Write call if c.Write is never called.
145 if c.outCode != 0 {
146 w.WriteHeader(c.outCode)
147 }
148 if c.outBody != nil {
149 w.Write(c.outBody)
150 }
151 // Wait for the last flush to complete before returning,
152 // otherwise the security ticket will not be valid.
153 <-flushed
154 }
155
156 func executeRequestSafely(c *context, r *http.Request) {
157 defer func() {
158 if x := recover(); x != nil {
159 logf(c, 4, "%s", renderPanic(x)) // 4 == critical
160 c.outCode = 500
161 }
162 }()
163
164 http.DefaultServeMux.ServeHTTP(c, r)
91 // Middleware wraps an http handler so that it can make GAE API calls
92 func Middleware(next http.Handler) http.Handler {
93 return handleHTTPMiddleware(executeRequestSafelyMiddleware(next))
94 }
95
96 func handleHTTPMiddleware(next http.Handler) http.Handler {
97 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
98 c := &context{
99 req: r,
100 outHeader: w.Header(),
101 }
102 r = r.WithContext(withContext(r.Context(), c))
103 c.req = r
104
105 stopFlushing := make(chan int)
106
107 // Patch up RemoteAddr so it looks reasonable.
108 if addr := r.Header.Get(userIPHeader); addr != "" {
109 r.RemoteAddr = addr
110 } else if addr = r.Header.Get(remoteAddrHeader); addr != "" {
111 r.RemoteAddr = addr
112 } else {
113 // Should not normally reach here, but pick a sensible default anyway.
114 r.RemoteAddr = "127.0.0.1"
115 }
116 // The address in the headers will most likely be of these forms:
117 // 123.123.123.123
118 // 2001:db8::1
119 // net/http.Request.RemoteAddr is specified to be in "IP:port" form.
120 if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil {
121 // Assume the remote address is only a host; add a default port.
122 r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80")
123 }
124
125 if logToLogservice() {
126 // Start goroutine responsible for flushing app logs.
127 // This is done after adding c to ctx.m (and stopped before removing it)
128 // because flushing logs requires making an API call.
129 go c.logFlusher(stopFlushing)
130 }
131
132 next.ServeHTTP(c, r)
133 c.outHeader = nil // make sure header changes aren't respected any more
134
135 flushed := make(chan struct{})
136 if logToLogservice() {
137 stopFlushing <- 1 // any logging beyond this point will be dropped
138
139 // Flush any pending logs asynchronously.
140 c.pendingLogs.Lock()
141 flushes := c.pendingLogs.flushes
142 if len(c.pendingLogs.lines) > 0 {
143 flushes++
144 }
145 c.pendingLogs.Unlock()
146 go func() {
147 defer close(flushed)
148 // Force a log flush, because with very short requests we
149 // may not ever flush logs.
150 c.flushLog(true)
151 }()
152 w.Header().Set(logFlushHeader, strconv.Itoa(flushes))
153 }
154
155 // Avoid nil Write call if c.Write is never called.
156 if c.outCode != 0 {
157 w.WriteHeader(c.outCode)
158 }
159 if c.outBody != nil {
160 w.Write(c.outBody)
161 }
162 if logToLogservice() {
163 // Wait for the last flush to complete before returning,
164 // otherwise the security ticket will not be valid.
165 <-flushed
166 }
167 })
168 }
169
170 func executeRequestSafelyMiddleware(next http.Handler) http.Handler {
171 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
172 defer func() {
173 if x := recover(); x != nil {
174 c := w.(*context)
175 logf(c, 4, "%s", renderPanic(x)) // 4 == critical
176 c.outCode = 500
177 }
178 }()
179
180 next.ServeHTTP(w, r)
181 })
165182 }
166183
167184 func renderPanic(x interface{}) string {
217234 lines []*logpb.UserAppLogLine
218235 flushes int
219236 }
220
221 apiURL *url.URL
222237 }
223238
224239 var contextKey = "holds a *context"
286301 }
287302 }
288303
289 // DefaultTicket returns a ticket used for background context or dev_appserver.
290 func DefaultTicket() string {
291 defaultTicketOnce.Do(func() {
292 if IsDevAppServer() {
293 defaultTicket = "testapp" + defaultTicketSuffix
294 return
295 }
296 appID := partitionlessAppID()
297 escAppID := strings.Replace(strings.Replace(appID, ":", "_", -1), ".", "_", -1)
298 majVersion := VersionID(nil)
299 if i := strings.Index(majVersion, "."); i > 0 {
300 majVersion = majVersion[:i]
301 }
302 defaultTicket = fmt.Sprintf("%s/%s.%s.%s", escAppID, ModuleName(nil), majVersion, InstanceID())
303 })
304 return defaultTicket
305 }
306
307 func BackgroundContext() netcontext.Context {
308 backgroundContextOnce.Do(func() {
309 // Compute background security ticket.
310 ticket := DefaultTicket()
311
312 c := &context{
313 req: &http.Request{
314 Header: http.Header{
315 ticketHeader: []string{ticket},
316 },
317 },
318 apiURL: apiURL(),
319 }
320 backgroundContext = toContext(c)
321
322 // TODO(dsymonds): Wire up the shutdown handler to do a final flush.
323 go c.logFlusher(make(chan int))
324 })
325
326 return backgroundContext
327 }
328
329304 // RegisterTestRequest registers the HTTP request req for testing, such that
330 // any API calls are sent to the provided URL. It returns a closure to delete
331 // the registration.
305 // any API calls are sent to the provided URL.
332306 // It should only be used by aetest package.
333 func RegisterTestRequest(req *http.Request, apiURL *url.URL, decorate func(netcontext.Context) netcontext.Context) (*http.Request, func()) {
334 c := &context{
335 req: req,
336 apiURL: apiURL,
337 }
338 ctx := withContext(decorate(req.Context()), c)
339 req = req.WithContext(ctx)
340 c.req = req
341 return req, func() {}
307 func RegisterTestRequest(req *http.Request, apiURL *url.URL, appID string) *http.Request {
308 ctx := req.Context()
309 ctx = withAPIHostOverride(ctx, apiURL.Hostname())
310 ctx = withAPIPortOverride(ctx, apiURL.Port())
311 ctx = WithAppIDOverride(ctx, appID)
312
313 // use the unregistered request as a placeholder so that withContext can read the headers
314 c := &context{req: req}
315 c.req = req.WithContext(withContext(ctx, c))
316 return c.req
342317 }
343318
344319 var errTimeout = &CallError{
383358 c.outCode = code
384359 }
385360
386 func (c *context) post(body []byte, timeout time.Duration) (b []byte, err error) {
361 func post(ctx netcontext.Context, body []byte, timeout time.Duration) (b []byte, err error) {
362 apiURL := apiURL(ctx)
387363 hreq := &http.Request{
388364 Method: "POST",
389 URL: c.apiURL,
365 URL: apiURL,
390366 Header: http.Header{
391367 apiEndpointHeader: apiEndpointHeaderValue,
392368 apiMethodHeader: apiMethodHeaderValue,
395371 },
396372 Body: ioutil.NopCloser(bytes.NewReader(body)),
397373 ContentLength: int64(len(body)),
398 Host: c.apiURL.Host,
399 }
400 if info := c.req.Header.Get(dapperHeader); info != "" {
401 hreq.Header.Set(dapperHeader, info)
402 }
403 if info := c.req.Header.Get(traceHeader); info != "" {
404 hreq.Header.Set(traceHeader, info)
374 Host: apiURL.Host,
375 }
376 c := fromContext(ctx)
377 if c != nil {
378 if info := c.req.Header.Get(dapperHeader); info != "" {
379 hreq.Header.Set(dapperHeader, info)
380 }
381 if info := c.req.Header.Get(traceHeader); info != "" {
382 hreq.Header.Set(traceHeader, info)
383 }
405384 }
406385
407386 tr := apiHTTPClient.Transport.(*http.Transport)
462441 }
463442
464443 c := fromContext(ctx)
465 if c == nil {
466 // Give a good error message rather than a panic lower down.
467 return errNotAppEngineContext
468 }
469444
470445 // Apply transaction modifications if we're in a transaction.
471446 if t := transactionFromContext(ctx); t != nil {
486461 return err
487462 }
488463
489 ticket := c.req.Header.Get(ticketHeader)
490 // Use a test ticket under test environment.
491 if ticket == "" {
492 if appid := ctx.Value(&appIDOverrideKey); appid != nil {
493 ticket = appid.(string) + defaultTicketSuffix
494 }
495 }
496 // Fall back to use background ticket when the request ticket is not available in Flex or dev_appserver.
497 if ticket == "" {
498 ticket = DefaultTicket()
499 }
500 if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" {
501 ticket = dri
464 ticket := ""
465 if c != nil {
466 ticket = c.req.Header.Get(ticketHeader)
467 if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" {
468 ticket = dri
469 }
502470 }
503471 req := &remotepb.Request{
504472 ServiceName: &service,
511479 return err
512480 }
513481
514 hrespBody, err := c.post(hreqBody, timeout)
482 hrespBody, err := post(ctx, hreqBody, timeout)
515483 if err != nil {
516484 return err
517485 }
580548 }
581549 s := fmt.Sprintf(format, args...)
582550 s = strings.TrimRight(s, "\n") // Remove any trailing newline characters.
583 c.addLogLine(&logpb.UserAppLogLine{
584 TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3),
585 Level: &level,
586 Message: &s,
587 })
588 // Only duplicate log to stderr if not running on App Engine second generation
551 if logToLogservice() {
552 c.addLogLine(&logpb.UserAppLogLine{
553 TimestampUsec: proto.Int64(time.Now().UnixNano() / 1e3),
554 Level: &level,
555 Message: &s,
556 })
557 }
558 // Log to stdout if not deployed
589559 if !IsSecondGen() {
590560 log.Print(logLevelName[level] + ": " + s)
591561 }
675645 func ContextForTesting(req *http.Request) netcontext.Context {
676646 return toContext(&context{req: req})
677647 }
648
649 func logToLogservice() bool {
650 // TODO: replace logservice with json structured logs to $LOG_DIR/app.log.json
651 // where $LOG_DIR is /var/log in prod and some tmpdir in dev
652 return os.Getenv("LOG_TO_LOGSERVICE") != "0"
653 }
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build appengine
45 // +build appengine
56
67 package internal
143144 return err
144145 }
145146
146 func handleHTTP(w http.ResponseWriter, r *http.Request) {
147 panic("handleHTTP called; this should be impossible")
147 func Middleware(next http.Handler) http.Handler {
148 panic("Middleware called; this should be impossible")
148149 }
149150
150151 func logf(c appengine.Context, level int64, format string, args ...interface{}) {
44 package internal
55
66 import (
7 netcontext "context"
78 "errors"
89 "os"
910
1011 "github.com/golang/protobuf/proto"
11 netcontext "golang.org/x/net/context"
1212 )
13
14 type ctxKey string
15
16 func (c ctxKey) String() string {
17 return "appengine context key: " + string(c)
18 }
1319
1420 var errNotAppEngineContext = errors.New("not an App Engine context")
1521
5258
5359 func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context {
5460 return netcontext.WithValue(ctx, &appIDOverrideKey, appID)
61 }
62
63 var apiHostOverrideKey = ctxKey("holds a string, being the alternate API_HOST")
64
65 func withAPIHostOverride(ctx netcontext.Context, apiHost string) netcontext.Context {
66 return netcontext.WithValue(ctx, apiHostOverrideKey, apiHost)
67 }
68
69 var apiPortOverrideKey = ctxKey("holds a string, being the alternate API_PORT")
70
71 func withAPIPortOverride(ctx netcontext.Context, apiPort string) netcontext.Context {
72 return netcontext.WithValue(ctx, apiPortOverrideKey, apiPort)
5573 }
5674
5775 var namespaceKey = "holds the namespace string"
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build race
45 // +build race
56
67 package internal
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package internal
89 import (
910 "bufio"
1011 "bytes"
12 netcontext "context"
1113 "fmt"
1214 "io"
1315 "io/ioutil"
1618 "net/url"
1719 "os"
1820 "os/exec"
21 "runtime"
1922 "strings"
2023 "sync/atomic"
2124 "testing"
2225 "time"
2326
2427 "github.com/golang/protobuf/proto"
25 netcontext "golang.org/x/net/context"
2628
2729 basepb "google.golang.org/appengine/internal/base"
2830 remotepb "google.golang.org/appengine/internal/remote_api"
2931 )
3032
3133 const testTicketHeader = "X-Magic-Ticket-Header"
34 const logserviceEnvVarKey = "LOG_TO_LOGSERVICE"
3235
3336 func init() {
3437 ticketHeader = testTicketHeader
3841 hang chan int // used for RunSlowly RPC
3942
4043 LogFlushes int32 // atomic
44
45 allowMissingTicket bool
4146 }
4247
4348 func (f *fakeAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6469 http.Error(w, fmt.Sprintf("Bad encoded API request: %v", err), 500)
6570 return
6671 }
67 if *apiReq.RequestId != "s3cr3t" && *apiReq.RequestId != DefaultTicket() {
72 if *apiReq.RequestId != "s3cr3t" && !f.allowMissingTicket {
6873 writeResponse(&remotepb.Response{
6974 RpcError: &remotepb.RpcError{
7075 Code: proto.Int32(int32(remotepb.RpcError_SECURITY_VIOLATION)),
144149 f = &fakeAPIHandler{}
145150 srv := httptest.NewServer(f)
146151 u, err := url.Parse(srv.URL + apiPath)
152 restoreAPIHost := restoreEnvVar("API_HOST")
153 restoreAPIPort := restoreEnvVar("API_HOST")
154 os.Setenv("API_HOST", u.Hostname())
155 os.Setenv("API_PORT", u.Port())
147156 if err != nil {
148157 panic(fmt.Sprintf("url.Parse(%q): %v", srv.URL+apiPath, err))
149158 }
150159 return f, &context{
151 req: &http.Request{
152 Header: http.Header{
153 ticketHeader: []string{"s3cr3t"},
154 dapperHeader: []string{"trace-001"},
160 req: &http.Request{
161 Header: http.Header{
162 ticketHeader: []string{"s3cr3t"},
163 dapperHeader: []string{"trace-001"},
164 },
155165 },
156 },
157 apiURL: u,
158 }, srv.Close
166 }, func() {
167 restoreAPIHost()
168 restoreAPIPort()
169 srv.Close()
170 }
171 }
172
173 func restoreEnvVar(key string) (cleanup func()) {
174 oldval, ok := os.LookupEnv(key)
175 return func() {
176 if ok {
177 os.Setenv(key, oldval)
178 } else {
179 os.Unsetenv(key)
180 }
181 }
159182 }
160183
161184 func TestAPICall(t *testing.T) {
178201 func TestAPICallTicketUnavailable(t *testing.T) {
179202 resetEnv := SetTestEnv()
180203 defer resetEnv()
181 _, c, cleanup := setup()
204 f, c, cleanup := setup()
182205 defer cleanup()
206 f.allowMissingTicket = true
183207
184208 c.req.Header.Set(ticketHeader, "")
185209 req := &basepb.StringProto{
229253 func TestAPICallDialFailure(t *testing.T) {
230254 // See what happens if the API host is unresponsive.
231255 // This should time out quickly, not hang forever.
232 _, c, cleanup := setup()
233 defer cleanup()
234 // Reset the URL to the production address so that dialing fails.
235 c.apiURL = apiURL()
236
256 // We intentially don't set up the fakeAPIHandler for this test to cause the dail failure.
237257 start := time.Now()
238 err := Call(toContext(c), "foo", "bar", &basepb.VoidProto{}, &basepb.VoidProto{})
258 err := Call(netcontext.Background(), "foo", "bar", &basepb.VoidProto{}, &basepb.VoidProto{})
239259 const max = 1 * time.Second
240260 if taken := time.Since(start); taken > max {
241261 t.Errorf("Dial hang took too long: %v > %v", taken, max)
246266 }
247267
248268 func TestDelayedLogFlushing(t *testing.T) {
249 f, c, cleanup := setup()
250 defer cleanup()
251
252 http.HandleFunc("/slow_log", func(w http.ResponseWriter, r *http.Request) {
253 logC := WithContext(netcontext.Background(), r)
254 fromContext(logC).apiURL = c.apiURL // Otherwise it will try to use the default URL.
255 Logf(logC, 1, "It's a lovely day.")
256 w.WriteHeader(200)
257 time.Sleep(1200 * time.Millisecond)
258 w.Write(make([]byte, 100<<10)) // write 100 KB to force HTTP flush
259 })
260
261 r := &http.Request{
262 Method: "GET",
263 URL: &url.URL{
264 Scheme: "http",
265 Path: "/slow_log",
266 },
267 Header: c.req.Header,
268 Body: ioutil.NopCloser(bytes.NewReader(nil)),
269 }
270 w := httptest.NewRecorder()
271
272 handled := make(chan struct{})
273 go func() {
274 defer close(handled)
275 handleHTTP(w, r)
276 }()
277 // Check that the log flush eventually comes in.
278 time.Sleep(1200 * time.Millisecond)
279 if f := atomic.LoadInt32(&f.LogFlushes); f != 1 {
280 t.Errorf("After 1.2s: f.LogFlushes = %d, want 1", f)
281 }
282
283 <-handled
284 const hdr = "X-AppEngine-Log-Flush-Count"
285 if got, want := w.HeaderMap.Get(hdr), "1"; got != want {
286 t.Errorf("%s header = %q, want %q", hdr, got, want)
287 }
288 if got, want := atomic.LoadInt32(&f.LogFlushes), int32(2); got != want {
289 t.Errorf("After HTTP response: f.LogFlushes = %d, want %d", got, want)
290 }
291
269 defer restoreEnvVar(logserviceEnvVarKey)()
270
271 testCases := []struct {
272 logToLogservice string
273 wantInitialFlushes int32
274 wantHeader string
275 wantEndFlushes int32
276 }{
277 {logToLogservice: "", wantHeader: "1", wantInitialFlushes: 1, wantEndFlushes: 2}, // default behavior
278 {logToLogservice: "1", wantHeader: "1", wantInitialFlushes: 1, wantEndFlushes: 2},
279 {logToLogservice: "0", wantHeader: "", wantInitialFlushes: 0, wantEndFlushes: 0},
280 }
281 for _, tc := range testCases {
282 t.Run(fmt.Sprintf("$%s=%q", logserviceEnvVarKey, tc.logToLogservice), func(t *testing.T) {
283 f, c, cleanup := setup()
284 defer cleanup()
285 os.Setenv(logserviceEnvVarKey, tc.logToLogservice)
286
287 path := "/slow_log_" + tc.logToLogservice
288
289 http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
290 logC := WithContext(netcontext.Background(), r)
291 Logf(logC, 1, "It's a lovely day.")
292 w.WriteHeader(200)
293 time.Sleep(1200 * time.Millisecond)
294 w.Write(make([]byte, 100<<10)) // write 100 KB to force HTTP flush
295 })
296
297 r := &http.Request{
298 Method: "GET",
299 URL: &url.URL{
300 Scheme: "http",
301 Path: path,
302 },
303 Header: c.req.Header,
304 Body: ioutil.NopCloser(bytes.NewReader(nil)),
305 }
306 w := httptest.NewRecorder()
307
308 handled := make(chan struct{})
309 go func() {
310 defer close(handled)
311 Middleware(http.DefaultServeMux).ServeHTTP(w, r)
312 }()
313 // Check that the log flush eventually comes in.
314 time.Sleep(1200 * time.Millisecond)
315 if got := atomic.LoadInt32(&f.LogFlushes); got != tc.wantInitialFlushes {
316 t.Errorf("After 1.2s: f.LogFlushes = %d, want %d", got, tc.wantInitialFlushes)
317 }
318
319 <-handled
320 const hdr = "X-AppEngine-Log-Flush-Count"
321 if got := w.HeaderMap.Get(hdr); got != tc.wantHeader {
322 t.Errorf("%s header = %q, want %q", hdr, got, tc.wantHeader)
323 }
324 if got := atomic.LoadInt32(&f.LogFlushes); got != tc.wantEndFlushes {
325 t.Errorf("After HTTP response: f.LogFlushes = %d, want %d", got, tc.wantEndFlushes)
326 }
327 })
328 }
292329 }
293330
294331 func TestLogFlushing(t *testing.T) {
295 f, c, cleanup := setup()
296 defer cleanup()
297
298 http.HandleFunc("/quick_log", func(w http.ResponseWriter, r *http.Request) {
299 logC := WithContext(netcontext.Background(), r)
300 fromContext(logC).apiURL = c.apiURL // Otherwise it will try to use the default URL.
301 Logf(logC, 1, "It's a lovely day.")
302 w.WriteHeader(200)
303 w.Write(make([]byte, 100<<10)) // write 100 KB to force HTTP flush
304 })
305
306 r := &http.Request{
307 Method: "GET",
308 URL: &url.URL{
309 Scheme: "http",
310 Path: "/quick_log",
311 },
312 Header: c.req.Header,
313 Body: ioutil.NopCloser(bytes.NewReader(nil)),
314 }
315 w := httptest.NewRecorder()
316
317 handleHTTP(w, r)
318 const hdr = "X-AppEngine-Log-Flush-Count"
319 if got, want := w.HeaderMap.Get(hdr), "1"; got != want {
320 t.Errorf("%s header = %q, want %q", hdr, got, want)
321 }
322 if got, want := atomic.LoadInt32(&f.LogFlushes), int32(1); got != want {
323 t.Errorf("After HTTP response: f.LogFlushes = %d, want %d", got, want)
332 defer restoreEnvVar(logserviceEnvVarKey)()
333
334 testCases := []struct {
335 logToLogservice string
336 wantHeader string
337 wantFlushes int32
338 }{
339 {logToLogservice: "", wantHeader: "1", wantFlushes: 1}, // default behavior
340 {logToLogservice: "1", wantHeader: "1", wantFlushes: 1},
341 {logToLogservice: "0", wantHeader: "", wantFlushes: 0},
342 }
343 for _, tc := range testCases {
344 t.Run(fmt.Sprintf("$%s=%q", logserviceEnvVarKey, tc.logToLogservice), func(t *testing.T) {
345 f, c, cleanup := setup()
346 defer cleanup()
347 os.Setenv(logserviceEnvVarKey, tc.logToLogservice)
348
349 path := "/quick_log_" + tc.logToLogservice
350 http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
351 logC := WithContext(netcontext.Background(), r)
352 Logf(logC, 1, "It's a lovely day.")
353 w.WriteHeader(200)
354 w.Write(make([]byte, 100<<10)) // write 100 KB to force HTTP flush
355 })
356
357 r := &http.Request{
358 Method: "GET",
359 URL: &url.URL{
360 Scheme: "http",
361 Path: path,
362 },
363 Header: c.req.Header,
364 Body: ioutil.NopCloser(bytes.NewReader(nil)),
365 }
366 w := httptest.NewRecorder()
367
368 Middleware(http.DefaultServeMux).ServeHTTP(w, r)
369 const hdr = "X-AppEngine-Log-Flush-Count"
370 if got := w.HeaderMap.Get(hdr); got != tc.wantHeader {
371 t.Errorf("%s header = %q, want %q", hdr, got, tc.wantHeader)
372 }
373 if got := atomic.LoadInt32(&f.LogFlushes); got != tc.wantFlushes {
374 t.Errorf("After HTTP response: f.LogFlushes = %d, want %d", got, tc.wantFlushes)
375 }
376 })
324377 }
325378 }
326379
355408 Header: tc.headers,
356409 Body: ioutil.NopCloser(bytes.NewReader(nil)),
357410 }
358 handleHTTP(httptest.NewRecorder(), r)
411 Middleware(http.DefaultServeMux).ServeHTTP(httptest.NewRecorder(), r)
359412 if addr != tc.addr {
360413 t.Errorf("Header %v, got %q, want %q", tc.headers, addr, tc.addr)
361414 }
372425 Body: ioutil.NopCloser(bytes.NewReader(nil)),
373426 }
374427 rec := httptest.NewRecorder()
375 handleHTTP(rec, r)
428 Middleware(http.DefaultServeMux).ServeHTTP(rec, r)
376429 if rec.Code != 500 {
377430 t.Errorf("Panicking handler returned HTTP %d, want HTTP %d", rec.Code, 500)
378431 }
386439 }
387440
388441 // Run the test API server in a subprocess so we aren't counting its allocations.
389 u, cleanup := launchHelperProcess(t)
442 cleanup := launchHelperProcess(t)
443
390444 defer cleanup()
391445 c := &context{
392446 req: &http.Request{
395449 dapperHeader: []string{"trace-001"},
396450 },
397451 },
398 apiURL: u,
399452 }
400453
401454 req := &basepb.StringProto{
414467 }
415468
416469 // Lots of room for improvement...
417 const min, max float64 = 60, 86
470 var min, max float64 = 60, 86
471 if strings.HasPrefix(runtime.Version(), "go1.11.") || strings.HasPrefix(runtime.Version(), "go1.12.") {
472 // add a bit more overhead for versions before go1.13
473 // see https://go.dev/doc/go1.13#compilers
474 max = 90
475 }
418476 if avg < min || max < avg {
419477 t.Errorf("Allocations per API call = %g, want in [%g,%g]", avg, min, max)
420478 }
421479 }
422480
423 func launchHelperProcess(t *testing.T) (apiURL *url.URL, cleanup func()) {
481 func launchHelperProcess(t *testing.T) (cleanup func()) {
424482 cmd := exec.Command(os.Args[0], "-test.run=TestHelperProcess")
425483 cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
426484 stdin, err := cmd.StdinPipe()
455513 t.Fatal("Helper process never reported")
456514 }
457515
458 return u, func() {
516 restoreAPIHost := restoreEnvVar("API_HOST")
517 restoreAPIPort := restoreEnvVar("API_HOST")
518 os.Setenv("API_HOST", u.Hostname())
519 os.Setenv("API_PORT", u.Port())
520 return func() {
521 restoreAPIHost()
522 restoreAPIPort()
459523 stdin.Close()
460524 if err := cmd.Wait(); err != nil {
461525 t.Errorf("Helper process did not exit cleanly: %v", err)
480544 // Wait for stdin to be closed.
481545 io.Copy(ioutil.Discard, os.Stdin)
482546 }
483
484 func TestBackgroundContext(t *testing.T) {
485 resetEnv := SetTestEnv()
486 defer resetEnv()
487
488 ctx, key := fromContext(BackgroundContext()), "X-Magic-Ticket-Header"
489 if g, w := ctx.req.Header.Get(key), "my-app-id/default.20150612t184001.0"; g != w {
490 t.Errorf("%v = %q, want %q", key, g, w)
491 }
492
493 // Check that using the background context doesn't panic.
494 req := &basepb.StringProto{
495 Value: proto.String("Doctor Who"),
496 }
497 res := &basepb.StringProto{}
498 Call(BackgroundContext(), "actordb", "LookupActor", req, res) // expected to fail
499 }
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build appengine
45 // +build appengine
56
67 package internal
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build appenginevm
45 // +build appenginevm
56
67 package internal
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package internal
129130 }
130131
131132 func IsDevAppServer() bool {
132 return os.Getenv("RUN_WITH_DEVAPPSERVER") != ""
133 return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" || os.Getenv("GAE_ENV") == "localdev"
133134 }
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package internal
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build appengine
45 // +build appengine
56
67 package internal
0 //go:build !appengine
01 // +build !appengine
12
23 package internal
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package internal
2829 if IsDevAppServer() {
2930 host = "127.0.0.1"
3031 }
31 if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
32 if err := http.ListenAndServe(host+":"+port, Middleware(http.DefaultServeMux)); err != nil {
3233 log.Fatalf("http.ListenAndServe: %v", err)
3334 }
3435 }
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package internal
3737 5: "OAUTH_ERROR",
3838 }
3939 var UserServiceError_ErrorCode_value = map[string]int32{
40 "OK": 0,
40 "OK": 0,
4141 "REDIRECT_URL_TOO_LONG": 1,
4242 "NOT_ALLOWED": 2,
4343 "OAUTH_INVALID_TOKEN": 3,
66 from within an App Engine application.
77
88 Example:
9
910 c := appengine.NewContext(r)
1011 query := &log.Query{
1112 AppLogs: true,
66 App Engine application.
77
88 Example:
9
910 msg := &mail.Message{
1011 Sender: "romeo@montague.com",
1112 To: []string{"Juliet <juliet@capulet.org>"},
44 /*
55 Package search provides a client for App Engine's search service.
66
7
8 Basic Operations
7 # Basic Operations
98
109 Indexes contain documents. Each index is identified by its name: a
1110 human-readable ASCII string.
5352 return err
5453 }
5554
56
57 Search and Listing Documents
55 # Search and Listing Documents
5856
5957 Indexes have two methods for retrieving multiple documents at once: Search and
6058 List.
9795 fmt.Fprintf(w, "%s -> %#v\n", id, doc)
9896 }
9997
100
101 Fields and Facets
98 # Fields and Facets
10299
103100 A document's contents can be represented by a variety of types. These are
104101 typically struct pointers, but they can also be represented by any type
144141 I float64 `search:",facet" json:"i"`
145142 }
146143
147
148 The FieldLoadSaver Interface
144 # The FieldLoadSaver Interface
149145
150146 A document's contents can also be represented by any type that implements the
151147 FieldLoadSaver interface. This type may be a struct pointer, but it
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build appengine
45 // +build appengine
56
67 package socket
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package socket
+0
-18
travis_install.sh less more
0 #!/bin/bash
1 set -e
2
3 if [[ $GO111MODULE == "on" ]]; then
4 go get .
5 else
6 go get -u -v $(go list -f '{{join .Imports "\n"}}{{"\n"}}{{join .TestImports "\n"}}' ./... | sort | uniq | grep -v appengine)
7 fi
8
9 if [[ $GOAPP == "true" ]]; then
10 mkdir /tmp/sdk
11 curl -o /tmp/sdk.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.68.zip"
12 unzip -q /tmp/sdk.zip -d /tmp/sdk
13 # NOTE: Set the following env vars in the test script:
14 # export PATH="$PATH:/tmp/sdk/go_appengine"
15 # export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py
16 fi
17
+0
-12
travis_test.sh less more
0 #!/bin/bash
1 set -e
2
3 go version
4 go test -v google.golang.org/appengine/...
5 go test -v -race google.golang.org/appengine/...
6 if [[ $GOAPP == "true" ]]; then
7 export PATH="$PATH:/tmp/sdk/go_appengine"
8 export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py
9 goapp version
10 goapp test -v google.golang.org/appengine/...
11 fi
4343 var _ http.RoundTripper = (*Transport)(nil)
4444
4545 // Client returns an *http.Client using a default urlfetch Transport. This
46 // client will have the default deadline of 5 seconds, and will check the
47 // validity of SSL certificates.
46 // client will check the validity of SSL certificates.
4847 //
49 // Any deadline of the provided context will be used for requests through this client;
50 // if the client does not have a deadline then a 5 second default is used.
48 // Any deadline of the provided context will be used for requests through this client.
49 // If the client does not have a deadline, then an App Engine default of 60 second is used.
5150 func Client(ctx context.Context) *http.Client {
5251 return &http.Client{
5352 Transport: &Transport{
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build appengine
45 // +build appengine
56
67 package user
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package user
11 // Use of this source code is governed by the Apache 2.0
22 // license that can be found in the LICENSE file.
33
4 //go:build !appengine
45 // +build !appengine
56
67 package user
0 # Contributing
1
2 1. Sign one of the contributor license agreements below.
3 1. Get the package:
4
5 `go get -d google.golang.org/appengine`
6 1. Change into the checked out source:
7
8 `cd $GOPATH/src/google.golang.org/appengine`
9 1. Fork the repo.
10 1. Set your fork as a remote:
11
12 `git remote add fork git@github.com:GITHUB_USERNAME/appengine.git`
13 1. Make changes, commit to your fork.
14 1. Send a pull request with your changes.
15 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.
16
17 # Testing
18
19 ## Running system tests
20
21 Set the `APPENGINE_DEV_APPSERVER` environment variable to `/path/to/go_appengine/dev_appserver.py`.
22
23 Run tests with `go test`:
24
25 ```
26 go test -v google.golang.org/appengine/v2/...
27 ```
28
29 ## Contributor License Agreements
30
31 Before we can accept your pull requests you'll need to sign a Contributor
32 License Agreement (CLA):
33
34 - **If you are an individual writing original source code** and **you own the
35 intellectual property**, then you'll need to sign an [individual CLA][indvcla].
36 - **If you work for a company that wants to allow you to contribute your work**,
37 then you'll need to sign a [corporate CLA][corpcla].
38
39 You can sign these electronically (just scroll to the bottom). After that,
40 we'll be able to accept your pull requests.
41
42 ## Contributor Code of Conduct
43
44 As contributors and maintainers of this project,
45 and in the interest of fostering an open and welcoming community,
46 we pledge to respect all people who contribute through reporting issues,
47 posting feature requests, updating documentation,
48 submitting pull requests or patches, and other activities.
49
50 We are committed to making participation in this project
51 a harassment-free experience for everyone,
52 regardless of level of experience, gender, gender identity and expression,
53 sexual orientation, disability, personal appearance,
54 body size, race, ethnicity, age, religion, or nationality.
55
56 Examples of unacceptable behavior by participants include:
57
58 * The use of sexualized language or imagery
59 * Personal attacks
60 * Trolling or insulting/derogatory comments
61 * Public or private harassment
62 * Publishing other's private information,
63 such as physical or electronic
64 addresses, without explicit permission
65 * Other unethical or unprofessional conduct.
66
67 Project maintainers have the right and responsibility to remove, edit, or reject
68 comments, commits, code, wiki edits, issues, and other contributions
69 that are not aligned to this Code of Conduct.
70 By adopting this Code of Conduct,
71 project maintainers commit themselves to fairly and consistently
72 applying these principles to every aspect of managing this project.
73 Project maintainers who do not follow or enforce the Code of Conduct
74 may be permanently removed from the project team.
75
76 This code of conduct applies both within project spaces and in public spaces
77 when an individual is representing the project or its community.
78
79 Instances of abusive, harassing, or otherwise unacceptable behavior
80 may be reported by opening an issue
81 or contacting one or more of the project maintainers.
82
83 This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
84 available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
85
86 [indvcla]: https://developers.google.com/open-source/cla/individual
87 [corpcla]: https://developers.google.com/open-source/cla/corporate
0
1 Apache License
2 Version 2.0, January 2004
3 http://www.apache.org/licenses/
4
5 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
7 1. Definitions.
8
9 "License" shall mean the terms and conditions for use, reproduction,
10 and distribution as defined by Sections 1 through 9 of this document.
11
12 "Licensor" shall mean the copyright owner or entity authorized by
13 the copyright owner that is granting the License.
14
15 "Legal Entity" shall mean the union of the acting entity and all
16 other entities that control, are controlled by, or are under common
17 control with that entity. For the purposes of this definition,
18 "control" means (i) the power, direct or indirect, to cause the
19 direction or management of such entity, whether by contract or
20 otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 outstanding shares, or (iii) beneficial ownership of such entity.
22
23 "You" (or "Your") shall mean an individual or Legal Entity
24 exercising permissions granted by this License.
25
26 "Source" form shall mean the preferred form for making modifications,
27 including but not limited to software source code, documentation
28 source, and configuration files.
29
30 "Object" form shall mean any form resulting from mechanical
31 transformation or translation of a Source form, including but
32 not limited to compiled object code, generated documentation,
33 and conversions to other media types.
34
35 "Work" shall mean the work of authorship, whether in Source or
36 Object form, made available under the License, as indicated by a
37 copyright notice that is included in or attached to the work
38 (an example is provided in the Appendix below).
39
40 "Derivative Works" shall mean any work, whether in Source or Object
41 form, that is based on (or derived from) the Work and for which the
42 editorial revisions, annotations, elaborations, or other modifications
43 represent, as a whole, an original work of authorship. For the purposes
44 of this License, Derivative Works shall not include works that remain
45 separable from, or merely link (or bind by name) to the interfaces of,
46 the Work and Derivative Works thereof.
47
48 "Contribution" shall mean any work of authorship, including
49 the original version of the Work and any modifications or additions
50 to that Work or Derivative Works thereof, that is intentionally
51 submitted to Licensor for inclusion in the Work by the copyright owner
52 or by an individual or Legal Entity authorized to submit on behalf of
53 the copyright owner. For the purposes of this definition, "submitted"
54 means any form of electronic, verbal, or written communication sent
55 to the Licensor or its representatives, including but not limited to
56 communication on electronic mailing lists, source code control systems,
57 and issue tracking systems that are managed by, or on behalf of, the
58 Licensor for the purpose of discussing and improving the Work, but
59 excluding communication that is conspicuously marked or otherwise
60 designated in writing by the copyright owner as "Not a Contribution."
61
62 "Contributor" shall mean Licensor and any individual or Legal Entity
63 on behalf of whom a Contribution has been received by Licensor and
64 subsequently incorporated within the Work.
65
66 2. Grant of Copyright License. Subject to the terms and conditions of
67 this License, each Contributor hereby grants to You a perpetual,
68 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 copyright license to reproduce, prepare Derivative Works of,
70 publicly display, publicly perform, sublicense, and distribute the
71 Work and such Derivative Works in Source or Object form.
72
73 3. Grant of Patent License. Subject to the terms and conditions of
74 this License, each Contributor hereby grants to You a perpetual,
75 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 (except as stated in this section) patent license to make, have made,
77 use, offer to sell, sell, import, and otherwise transfer the Work,
78 where such license applies only to those patent claims licensable
79 by such Contributor that are necessarily infringed by their
80 Contribution(s) alone or by combination of their Contribution(s)
81 with the Work to which such Contribution(s) was submitted. If You
82 institute patent litigation against any entity (including a
83 cross-claim or counterclaim in a lawsuit) alleging that the Work
84 or a Contribution incorporated within the Work constitutes direct
85 or contributory patent infringement, then any patent licenses
86 granted to You under this License for that Work shall terminate
87 as of the date such litigation is filed.
88
89 4. Redistribution. You may reproduce and distribute copies of the
90 Work or Derivative Works thereof in any medium, with or without
91 modifications, and in Source or Object form, provided that You
92 meet the following conditions:
93
94 (a) You must give any other recipients of the Work or
95 Derivative Works a copy of this License; and
96
97 (b) You must cause any modified files to carry prominent notices
98 stating that You changed the files; and
99
100 (c) You must retain, in the Source form of any Derivative Works
101 that You distribute, all copyright, patent, trademark, and
102 attribution notices from the Source form of the Work,
103 excluding those notices that do not pertain to any part of
104 the Derivative Works; and
105
106 (d) If the Work includes a "NOTICE" text file as part of its
107 distribution, then any Derivative Works that You distribute must
108 include a readable copy of the attribution notices contained
109 within such NOTICE file, excluding those notices that do not
110 pertain to any part of the Derivative Works, in at least one
111 of the following places: within a NOTICE text file distributed
112 as part of the Derivative Works; within the Source form or
113 documentation, if provided along with the Derivative Works; or,
114 within a display generated by the Derivative Works, if and
115 wherever such third-party notices normally appear. The contents
116 of the NOTICE file are for informational purposes only and
117 do not modify the License. You may add Your own attribution
118 notices within Derivative Works that You distribute, alongside
119 or as an addendum to the NOTICE text from the Work, provided
120 that such additional attribution notices cannot be construed
121 as modifying the License.
122
123 You may add Your own copyright statement to Your modifications and
124 may provide additional or different license terms and conditions
125 for use, reproduction, or distribution of Your modifications, or
126 for any such Derivative Works as a whole, provided Your use,
127 reproduction, and distribution of the Work otherwise complies with
128 the conditions stated in this License.
129
130 5. Submission of Contributions. Unless You explicitly state otherwise,
131 any Contribution intentionally submitted for inclusion in the Work
132 by You to the Licensor shall be under the terms and conditions of
133 this License, without any additional terms or conditions.
134 Notwithstanding the above, nothing herein shall supersede or modify
135 the terms of any separate license agreement you may have executed
136 with Licensor regarding such Contributions.
137
138 6. Trademarks. This License does not grant permission to use the trade
139 names, trademarks, service marks, or product names of the Licensor,
140 except as required for reasonable and customary use in describing the
141 origin of the Work and reproducing the content of the NOTICE file.
142
143 7. Disclaimer of Warranty. Unless required by applicable law or
144 agreed to in writing, Licensor provides the Work (and each
145 Contributor provides its Contributions) on an "AS IS" BASIS,
146 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 implied, including, without limitation, any warranties or conditions
148 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 PARTICULAR PURPOSE. You are solely responsible for determining the
150 appropriateness of using or redistributing the Work and assume any
151 risks associated with Your exercise of permissions under this License.
152
153 8. Limitation of Liability. In no event and under no legal theory,
154 whether in tort (including negligence), contract, or otherwise,
155 unless required by applicable law (such as deliberate and grossly
156 negligent acts) or agreed to in writing, shall any Contributor be
157 liable to You for damages, including any direct, indirect, special,
158 incidental, or consequential damages of any character arising as a
159 result of this License or out of the use or inability to use the
160 Work (including but not limited to damages for loss of goodwill,
161 work stoppage, computer failure or malfunction, or any and all
162 other commercial damages or losses), even if such Contributor
163 has been advised of the possibility of such damages.
164
165 9. Accepting Warranty or Additional Liability. While redistributing
166 the Work or Derivative Works thereof, You may choose to offer,
167 and charge a fee for, acceptance of support, warranty, indemnity,
168 or other liability obligations and/or rights consistent with this
169 License. However, in accepting such obligations, You may act only
170 on Your own behalf and on Your sole responsibility, not on behalf
171 of any other Contributor, and only if You agree to indemnify,
172 defend, and hold each Contributor harmless for any liability
173 incurred by, or claims asserted against, such Contributor by reason
174 of your accepting any such warranty or additional liability.
175
176 END OF TERMS AND CONDITIONS
177
178 APPENDIX: How to apply the Apache License to your work.
179
180 To apply the Apache License to your work, attach the following
181 boilerplate notice, with the fields enclosed by brackets "[]"
182 replaced with your own identifying information. (Don't include
183 the brackets!) The text should be enclosed in the appropriate
184 comment syntax for the file format. We also recommend that a
185 file or class name and description of purpose be included on the
186 same "printed page" as the copyright notice for easier
187 identification within third-party archives.
188
189 Copyright [yyyy] [name of copyright owner]
190
191 Licensed under the Apache License, Version 2.0 (the "License");
192 you may not use this file except in compliance with the License.
193 You may obtain a copy of the License at
194
195 http://www.apache.org/licenses/LICENSE-2.0
196
197 Unless required by applicable law or agreed to in writing, software
198 distributed under the License is distributed on an "AS IS" BASIS,
199 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 See the License for the specific language governing permissions and
201 limitations under the License.
0 # Go App Engine packages
1
2 [![Build Status](https://travis-ci.org/golang/appengine.svg)](https://travis-ci.org/golang/appengine)
3
4 This repository supports the Go runtime on *App Engine standard*.
5 It provides APIs for interacting with App Engine services.
6 Its canonical import path is `google.golang.org/appengine`.
7
8 See https://cloud.google.com/appengine/docs/go/
9 for more information.
10
11 File issue reports and feature requests on the [GitHub's issue
12 tracker](https://github.com/golang/appengine/issues).
13
14 ## Upgrading an App Engine app to the flexible environment
15
16 This package does not work on *App Engine flexible*.
17
18 There are many differences between the App Engine standard environment and
19 the flexible environment.
20
21 See the [documentation on upgrading to the flexible environment](https://cloud.google.com/appengine/docs/flexible/go/upgrading).
22
23 ## Directory structure
24
25 The top level directory of this repository is the `appengine` package. It
26 contains the
27 basic APIs (e.g. `appengine.NewContext`) that apply across APIs. Specific API
28 packages are in subdirectories (e.g. `datastore`).
29
30 There is an `internal` subdirectory that contains service protocol buffers,
31 plus packages required for connectivity to make API calls. App Engine apps
32 should not directly import any package under `internal`.
33
34 ## Updating from legacy (`import "appengine"`) packages
35
36 If you're currently using the bare `appengine` packages
37 (that is, not these ones, imported via `google.golang.org/appengine`),
38 then you can use the `aefix` tool to help automate an upgrade to these packages.
39
40 Run `go get google.golang.org/appengine/cmd/aefix` to install it.
41
42 ### 1. Update import paths
43
44 The import paths for App Engine packages are now fully qualified, based at `google.golang.org/appengine`.
45 You will need to update your code to use import paths starting with that; for instance,
46 code importing `appengine/datastore` will now need to import `google.golang.org/appengine/datastore`.
47
48 ### 2. Update code using deprecated, removed or modified APIs
49
50 Most App Engine services are available with exactly the same API.
51 A few APIs were cleaned up, and there are some differences:
52
53 * `appengine.Context` has been replaced with the `Context` type from `golang.org/x/net/context`.
54 * Logging methods that were on `appengine.Context` are now functions in `google.golang.org/appengine/log`.
55 * `appengine.Timeout` has been removed. Use `context.WithTimeout` instead.
56 * `appengine.Datacenter` now takes a `context.Context` argument.
57 * `datastore.PropertyLoadSaver` has been simplified to use slices in place of channels.
58 * `delay.Call` now returns an error.
59 * `search.FieldLoadSaver` now handles document metadata.
60 * `urlfetch.Transport` no longer has a Deadline field; set a deadline on the
61 `context.Context` instead.
62 * `aetest` no longer declares its own Context type, and uses the standard one instead.
63 * `taskqueue.QueueStats` no longer takes a maxTasks argument. That argument has been
64 deprecated and unused for a long time.
65 * `appengine.BackendHostname` and `appengine.BackendInstance` were for the deprecated backends feature.
66 Use `appengine.ModuleHostname`and `appengine.ModuleName` instead.
67 * Most of `appengine/file` and parts of `appengine/blobstore` are deprecated.
68 Use [Google Cloud Storage](https://godoc.org/cloud.google.com/go/storage) if the
69 feature you require is not present in the new
70 [blobstore package](https://google.golang.org/appengine/blobstore).
71 * `appengine/socket` is not required on App Engine flexible environment / Managed VMs.
72 Use the standard `net` package instead.
73
74 ## Key Encode/Decode compatibiltiy to help with datastore library migrations
75
76 Key compatibility updates have been added to help customers transition from google.golang.org/appengine/datastore to cloud.google.com/go/datastore.
77 The `EnableKeyConversion` enables automatic conversion from a key encoded with cloud.google.com/go/datastore to google.golang.org/appengine/datastore key type.
78
79 ### Enabling key conversion
80
81 Enable key conversion by calling `EnableKeyConversion(ctx)` in the `/_ah/start` handler for basic and manual scaling or any handler in automatic scaling.
82
83 #### 1. Basic or manual scaling
84
85 This start handler will enable key conversion for all handlers in the service.
86
87 ```
88 http.HandleFunc("/_ah/start", func(w http.ResponseWriter, r *http.Request) {
89 datastore.EnableKeyConversion(appengine.NewContext(r))
90 })
91 ```
92
93 #### 2. Automatic scaling
94
95 `/_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))`
96 before you use code that needs key conversion.
97
98 You may want to add this to each of your handlers, or introduce middleware where it's called.
99 `EnableKeyConversion` is safe for concurrent use. Any call to it after the first is ignored.
100
101 ## QA
102
103 Googlers, [integration tests](http://go/appengine-go-integration) run on the QA branch. You should first merge to QA
104 and verify the integration tests pass before cutting a new release.
0 /*
1 Package aetest provides an API for running dev_appserver for use in tests.
2
3 An example test file:
4
5 package foo_test
6
7 import (
8 "testing"
9
10 "google.golang.org/appengine/v2/memcache"
11 "google.golang.org/appengine/v2/aetest"
12 )
13
14 func TestFoo(t *testing.T) {
15 ctx, done, err := aetest.NewContext()
16 if err != nil {
17 t.Fatal(err)
18 }
19 defer done()
20
21 it := &memcache.Item{
22 Key: "some-key",
23 Value: []byte("some-value"),
24 }
25 err = memcache.Set(ctx, it)
26 if err != nil {
27 t.Fatalf("Set err: %v", err)
28 }
29 it, err = memcache.Get(ctx, "some-key")
30 if err != nil {
31 t.Fatalf("Get err: %v; want no error", err)
32 }
33 if g, w := string(it.Value), "some-value" ; g != w {
34 t.Errorf("retrieved Item.Value = %q, want %q", g, w)
35 }
36 }
37
38 The environment variable APPENGINE_DEV_APPSERVER specifies the location of the
39 dev_appserver.py executable to use. If unset, the system PATH is consulted.
40 */
41 package aetest
0 package aetest
1
2 import (
3 "bufio"
4 "context"
5 "crypto/rand"
6 "errors"
7 "fmt"
8 "io"
9 "io/ioutil"
10 "net/http"
11 "net/url"
12 "os"
13 "os/exec"
14 "path/filepath"
15 "regexp"
16 "time"
17
18 "google.golang.org/appengine/v2"
19 "google.golang.org/appengine/v2/internal"
20 )
21
22 // Instance represents a running instance of the development API Server.
23 type Instance interface {
24 // Close kills the child api_server.py process, releasing its resources.
25 io.Closer
26 // NewRequest returns an *http.Request associated with this instance.
27 NewRequest(method, urlStr string, body io.Reader) (*http.Request, error)
28 }
29
30 // Options is used to specify options when creating an Instance.
31 type Options struct {
32 // AppID specifies the App ID to use during tests.
33 // By default, "testapp".
34 AppID string
35 // StronglyConsistentDatastore is whether the local datastore should be
36 // strongly consistent. This will diverge from production behaviour.
37 StronglyConsistentDatastore bool
38 // SupportDatastoreEmulator is whether use Cloud Datastore Emulator or
39 // use old SQLite based Datastore backend or use default settings.
40 SupportDatastoreEmulator *bool
41 // SuppressDevAppServerLog is whether the dev_appserver running in tests
42 // should output logs.
43 SuppressDevAppServerLog bool
44 // StartupTimeout is a duration to wait for instance startup.
45 // By default, 15 seconds.
46 StartupTimeout time.Duration
47 }
48
49 // NewContext starts an instance of the development API server, and returns
50 // a context that will route all API calls to that server, as well as a
51 // closure that must be called when the Context is no longer required.
52 func NewContext() (context.Context, func(), error) {
53 inst, err := NewInstance(nil)
54 if err != nil {
55 return nil, nil, err
56 }
57 req, err := inst.NewRequest("GET", "/", nil)
58 if err != nil {
59 inst.Close()
60 return nil, nil, err
61 }
62 ctx := appengine.NewContext(req)
63 return ctx, func() {
64 inst.Close()
65 }, nil
66 }
67
68 // PrepareDevAppserver is a hook which, if set, will be called before the
69 // dev_appserver.py is started, each time it is started. If aetest.NewContext
70 // is invoked from the goapp test tool, this hook is unnecessary.
71 var PrepareDevAppserver func() error
72
73 // NewInstance launches a running instance of api_server.py which can be used
74 // for multiple test Contexts that delegate all App Engine API calls to that
75 // instance.
76 // If opts is nil the default values are used.
77 func NewInstance(opts *Options) (Instance, error) {
78 i := &instance{
79 opts: opts,
80 appID: "testapp",
81 startupTimeout: 15 * time.Second,
82 }
83 if opts != nil {
84 if opts.AppID != "" {
85 i.appID = opts.AppID
86 }
87 if opts.StartupTimeout > 0 {
88 i.startupTimeout = opts.StartupTimeout
89 }
90 }
91 if err := i.startChild(); err != nil {
92 return nil, err
93 }
94 return i, nil
95 }
96
97 func newSessionID() string {
98 var buf [16]byte
99 io.ReadFull(rand.Reader, buf[:])
100 return fmt.Sprintf("%x", buf[:])
101 }
102
103 // instance implements the Instance interface.
104 type instance struct {
105 opts *Options
106 child *exec.Cmd
107 apiURL *url.URL // base URL of API HTTP server
108 adminURL string // base URL of admin HTTP server
109 appDir string
110 appID string
111 startupTimeout time.Duration
112 }
113
114 // NewRequest returns an *http.Request associated with this instance.
115 func (i *instance) NewRequest(method, urlStr string, body io.Reader) (*http.Request, error) {
116 req, err := http.NewRequest(method, urlStr, body)
117 if err != nil {
118 return nil, err
119 }
120
121 // Associate this request.
122 return internal.RegisterTestRequest(req, i.apiURL, "dev~"+i.appID), nil
123 }
124
125 // Close kills the child api_server.py process, releasing its resources.
126 func (i *instance) Close() (err error) {
127 child := i.child
128 if child == nil {
129 return nil
130 }
131 defer func() {
132 i.child = nil
133 err1 := os.RemoveAll(i.appDir)
134 if err == nil {
135 err = err1
136 }
137 }()
138
139 if p := child.Process; p != nil {
140 errc := make(chan error, 1)
141 go func() {
142 errc <- child.Wait()
143 }()
144
145 // Call the quit handler on the admin server.
146 res, err := http.Get(i.adminURL + "/quit")
147 if err != nil {
148 p.Kill()
149 return fmt.Errorf("unable to call /quit handler: %v", err)
150 }
151 res.Body.Close()
152 select {
153 case <-time.After(15 * time.Second):
154 p.Kill()
155 return errors.New("timeout killing child process")
156 case err = <-errc:
157 // Do nothing.
158 }
159 }
160 return
161 }
162
163 func fileExists(path string) bool {
164 _, err := os.Stat(path)
165 return err == nil
166 }
167
168 func findPython() (path string, err error) {
169 for _, name := range []string{"python2.7", "python"} {
170 path, err = exec.LookPath(name)
171 if err == nil {
172 return
173 }
174 }
175 return
176 }
177
178 func findDevAppserver() (string, error) {
179 if p := os.Getenv("APPENGINE_DEV_APPSERVER"); p != "" {
180 if fileExists(p) {
181 return p, nil
182 }
183 return "", fmt.Errorf("invalid APPENGINE_DEV_APPSERVER environment variable; path %q doesn't exist", p)
184 }
185 return exec.LookPath("dev_appserver.py")
186 }
187
188 var apiServerAddrRE = regexp.MustCompile(`Starting API server at: (\S+)`)
189 var adminServerAddrRE = regexp.MustCompile(`Starting admin server at: (\S+)`)
190
191 func (i *instance) startChild() (err error) {
192 if PrepareDevAppserver != nil {
193 if err := PrepareDevAppserver(); err != nil {
194 return err
195 }
196 }
197 executable := os.Getenv("APPENGINE_DEV_APPSERVER_BINARY")
198 var appserverArgs []string
199 if len(executable) == 0 {
200 executable, err = findPython()
201 if err != nil {
202 return fmt.Errorf("Could not find python interpreter: %v", err)
203 }
204 devAppserver, err := findDevAppserver()
205 if err != nil {
206 return fmt.Errorf("Could not find dev_appserver.py: %v", err)
207 }
208 appserverArgs = append(appserverArgs, devAppserver)
209 }
210
211 i.appDir, err = ioutil.TempDir("", "appengine-aetest")
212 if err != nil {
213 return err
214 }
215 defer func() {
216 if err != nil {
217 os.RemoveAll(i.appDir)
218 }
219 }()
220 err = os.Mkdir(filepath.Join(i.appDir, "app"), 0755)
221 if err != nil {
222 return err
223 }
224 err = ioutil.WriteFile(filepath.Join(i.appDir, "app", "app.yaml"), []byte(i.appYAML()), 0644)
225 if err != nil {
226 return err
227 }
228 err = ioutil.WriteFile(filepath.Join(i.appDir, "app", "stubapp.go"), []byte(appSource), 0644)
229 if err != nil {
230 return err
231 }
232
233 datastorePath := os.Getenv("APPENGINE_DEV_APPSERVER_DATASTORE_PATH")
234 if len(datastorePath) == 0 {
235 datastorePath = filepath.Join(i.appDir, "datastore")
236 }
237
238 appserverArgs = append(appserverArgs,
239 "--port=0",
240 "--api_port=0",
241 "--admin_port=0",
242 "--automatic_restart=false",
243 "--skip_sdk_update_check=true",
244 "--clear_datastore=true",
245 "--clear_search_indexes=true",
246 "--datastore_path", datastorePath,
247 )
248 if i.opts != nil && i.opts.StronglyConsistentDatastore {
249 appserverArgs = append(appserverArgs, "--datastore_consistency_policy=consistent")
250 }
251 if i.opts != nil && i.opts.SupportDatastoreEmulator != nil {
252 appserverArgs = append(appserverArgs, fmt.Sprintf("--support_datastore_emulator=%t", *i.opts.SupportDatastoreEmulator))
253 }
254 appserverArgs = append(appserverArgs, filepath.Join(i.appDir, "app"))
255
256 i.child = exec.Command(executable, appserverArgs...)
257
258 i.child.Stdout = os.Stdout
259 var stderr io.Reader
260 stderr, err = i.child.StderrPipe()
261 if err != nil {
262 return err
263 }
264
265 if err = i.child.Start(); err != nil {
266 return err
267 }
268
269 // Read stderr until we have read the URLs of the API server and admin interface.
270 errc := make(chan error, 1)
271 go func() {
272 s := bufio.NewScanner(stderr)
273 for s.Scan() {
274 // Pass stderr along as we go so the user can see it.
275 if !(i.opts != nil && i.opts.SuppressDevAppServerLog) {
276 fmt.Fprintln(os.Stderr, s.Text())
277 }
278 if match := apiServerAddrRE.FindStringSubmatch(s.Text()); match != nil {
279 u, err := url.Parse(match[1])
280 if err != nil {
281 errc <- fmt.Errorf("failed to parse API URL %q: %v", match[1], err)
282 return
283 }
284 i.apiURL = u
285 }
286 if match := adminServerAddrRE.FindStringSubmatch(s.Text()); match != nil {
287 i.adminURL = match[1]
288 }
289 if i.adminURL != "" && i.apiURL != nil {
290 // Pass along stderr to the user after we're done with it.
291 if !(i.opts != nil && i.opts.SuppressDevAppServerLog) {
292 go io.Copy(os.Stderr, stderr)
293 }
294 break
295 }
296 }
297 errc <- s.Err()
298 }()
299
300 select {
301 case <-time.After(i.startupTimeout):
302 if p := i.child.Process; p != nil {
303 p.Kill()
304 }
305 return errors.New("timeout starting child process")
306 case err := <-errc:
307 if err != nil {
308 return fmt.Errorf("error reading child process stderr: %v", err)
309 }
310 }
311 if i.adminURL == "" {
312 return errors.New("unable to find admin server URL")
313 }
314 if i.apiURL == nil {
315 return errors.New("unable to find API server URL")
316 }
317 return nil
318 }
319
320 func (i *instance) appYAML() string {
321 return fmt.Sprintf(appYAMLTemplate, i.appID)
322 }
323
324 const appYAMLTemplate = `
325 application: %s
326 version: 1
327 runtime: go111
328
329 handlers:
330 - url: /.*
331 script: _go_app
332 `
333
334 const appSource = `
335 package main
336 import "google.golang.org/appengine/v2"
337 func main() { appengine.Main() }
338 `
0 package aetest
1
2 import (
3 "os"
4 "testing"
5
6 "google.golang.org/appengine/v2"
7 "google.golang.org/appengine/v2/datastore"
8 "google.golang.org/appengine/v2/internal"
9 "google.golang.org/appengine/v2/memcache"
10 "google.golang.org/appengine/v2/user"
11 )
12
13 func TestBasicAPICalls(t *testing.T) {
14 // Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
15 if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
16 t.Skip("APPENGINE_DEV_APPSERVER not set")
17 }
18 resetEnv := internal.SetTestEnv()
19 defer resetEnv()
20
21 inst, err := NewInstance(nil)
22 if err != nil {
23 t.Fatalf("NewInstance: %v", err)
24 }
25 defer inst.Close()
26
27 req, err := inst.NewRequest("GET", "http://example.com/page", nil)
28 if err != nil {
29 t.Fatalf("NewRequest: %v", err)
30 }
31 ctx := appengine.NewContext(req)
32
33 it := &memcache.Item{
34 Key: "some-key",
35 Value: []byte("some-value"),
36 }
37 err = memcache.Set(ctx, it)
38 if err != nil {
39 t.Fatalf("Set err: %v", err)
40 }
41 it, err = memcache.Get(ctx, "some-key")
42 if err != nil {
43 t.Fatalf("Get err: %v; want no error", err)
44 }
45 if g, w := string(it.Value), "some-value"; g != w {
46 t.Errorf("retrieved Item.Value = %q, want %q", g, w)
47 }
48
49 type Entity struct{ Value string }
50 e := &Entity{Value: "foo"}
51 k := datastore.NewIncompleteKey(ctx, "Entity", nil)
52 k, err = datastore.Put(ctx, k, e)
53 if err != nil {
54 t.Fatalf("datastore.Put: %v", err)
55 }
56 e = new(Entity)
57 if err := datastore.Get(ctx, k, e); err != nil {
58 t.Fatalf("datastore.Get: %v", err)
59 }
60 if g, w := e.Value, "foo"; g != w {
61 t.Errorf("retrieved Entity.Value = %q, want %q", g, w)
62 }
63 }
64
65 func TestContext(t *testing.T) {
66 // Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
67 if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
68 t.Skip("APPENGINE_DEV_APPSERVER not set")
69 }
70
71 // Check that the context methods work.
72 _, done, err := NewContext()
73 if err != nil {
74 t.Fatalf("NewContext: %v", err)
75 }
76 done()
77 }
78
79 func TestUsers(t *testing.T) {
80 // Only run the test if APPENGINE_DEV_APPSERVER is explicitly set.
81 if os.Getenv("APPENGINE_DEV_APPSERVER") == "" {
82 t.Skip("APPENGINE_DEV_APPSERVER not set")
83 }
84
85 inst, err := NewInstance(nil)
86 if err != nil {
87 t.Fatalf("NewInstance: %v", err)
88 }
89 defer inst.Close()
90
91 req, err := inst.NewRequest("GET", "http://example.com/page", nil)
92 if err != nil {
93 t.Fatalf("NewRequest: %v", err)
94 }
95 ctx := appengine.NewContext(req)
96
97 if user := user.Current(ctx); user != nil {
98 t.Errorf("user.Current initially %v, want nil", user)
99 }
100
101 u := &user.User{
102 Email: "gopher@example.com",
103 Admin: true,
104 }
105 Login(u, req)
106
107 if got := user.Current(ctx); got.Email != u.Email {
108 t.Errorf("user.Current: %v, want %v", got, u)
109 }
110 if admin := user.IsAdmin(ctx); !admin {
111 t.Errorf("user.IsAdmin: %t, want true", admin)
112 }
113
114 Logout(req)
115 if user := user.Current(ctx); user != nil {
116 t.Errorf("user.Current after logout %v, want nil", user)
117 }
118 }
0 package aetest
1
2 import (
3 "hash/crc32"
4 "net/http"
5 "strconv"
6
7 "google.golang.org/appengine/v2/user"
8 )
9
10 // Login causes the provided Request to act as though issued by the given user.
11 func Login(u *user.User, req *http.Request) {
12 req.Header.Set("X-AppEngine-User-Email", u.Email)
13 id := u.ID
14 if id == "" {
15 id = strconv.Itoa(int(crc32.Checksum([]byte(u.Email), crc32.IEEETable)))
16 }
17 req.Header.Set("X-AppEngine-User-Id", id)
18 req.Header.Set("X-AppEngine-Federated-Identity", u.FederatedIdentity)
19 req.Header.Set("X-AppEngine-Federated-Provider", u.FederatedProvider)
20 // NOTE: the following two headers are wrong, but are preserved to not break legacy tests.
21 req.Header.Set("X-AppEngine-User-Federated-Identity", u.Email)
22 req.Header.Set("X-AppEngine-User-Federated-Provider", u.FederatedProvider)
23 if u.Admin {
24 req.Header.Set("X-AppEngine-User-Is-Admin", "1")
25 } else {
26 req.Header.Set("X-AppEngine-User-Is-Admin", "0")
27 }
28 }
29
30 // Logout causes the provided Request to act as though issued by a logged-out
31 // user.
32 func Logout(req *http.Request) {
33 req.Header.Del("X-AppEngine-User-Email")
34 req.Header.Del("X-AppEngine-User-Id")
35 req.Header.Del("X-AppEngine-User-Is-Admin")
36 req.Header.Del("X-AppEngine-Federated-Identity")
37 req.Header.Del("X-AppEngine-Federated-Provider")
38 // NOTE: the following two headers are wrong, but are preserved to not break legacy tests.
39 req.Header.Del("X-AppEngine-User-Federated-Identity")
40 req.Header.Del("X-AppEngine-User-Federated-Provider")
41 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package appengine provides basic functionality for Google App Engine.
5 //
6 // For more information on how to write Go apps for Google App Engine, see:
7 // https://cloud.google.com/appengine/docs/go/
8 package appengine // import "google.golang.org/appengine/v2"
9
10 import (
11 "context"
12 "net/http"
13
14 "github.com/golang/protobuf/proto"
15
16 "google.golang.org/appengine/v2/internal"
17 )
18
19 // The gophers party all night; the rabbits provide the beats.
20
21 // Main is the principal entry point for an app running in App Engine.
22 //
23 // On App Engine Flexible it installs a trivial health checker if one isn't
24 // already registered, and starts listening on port 8080 (overridden by the
25 // $PORT environment variable).
26 //
27 // See https://cloud.google.com/appengine/docs/flexible/custom-runtimes#health_check_requests
28 // for details on how to do your own health checking.
29 //
30 // On App Engine Standard it ensures the server has started and is prepared to
31 // receive requests.
32 //
33 // Main never returns.
34 //
35 // Main is designed so that the app's main package looks like this:
36 //
37 // package main
38 //
39 // import (
40 // "google.golang.org/appengine/v2"
41 //
42 // _ "myapp/package0"
43 // _ "myapp/package1"
44 // )
45 //
46 // func main() {
47 // appengine.Main()
48 // }
49 //
50 // The "myapp/packageX" packages are expected to register HTTP handlers
51 // in their init functions.
52 func Main() {
53 internal.Main()
54 }
55
56 // Middleware wraps an http handler so that it can make GAE API calls
57 var Middleware func(http.Handler) http.Handler = internal.Middleware
58
59 // IsDevAppServer reports whether the App Engine app is running in the
60 // development App Server.
61 func IsDevAppServer() bool {
62 return internal.IsDevAppServer()
63 }
64
65 // IsStandard reports whether the App Engine app is running in the standard
66 // environment. This includes both the first generation runtimes (<= Go 1.9)
67 // and the second generation runtimes (>= Go 1.11).
68 func IsStandard() bool {
69 return internal.IsStandard()
70 }
71
72 // IsFlex reports whether the App Engine app is running in the flexible environment.
73 func IsFlex() bool {
74 return internal.IsFlex()
75 }
76
77 // IsAppEngine reports whether the App Engine app is running on App Engine, in either
78 // the standard or flexible environment.
79 func IsAppEngine() bool {
80 return internal.IsAppEngine()
81 }
82
83 // IsSecondGen reports whether the App Engine app is running on the second generation
84 // runtimes (>= Go 1.11).
85 func IsSecondGen() bool {
86 return internal.IsSecondGen()
87 }
88
89 // NewContext returns a context for an in-flight HTTP request.
90 // This function is cheap.
91 func NewContext(req *http.Request) context.Context {
92 return internal.ReqContext(req)
93 }
94
95 // WithContext returns a copy of the parent context
96 // and associates it with an in-flight HTTP request.
97 // This function is cheap.
98 func WithContext(parent context.Context, req *http.Request) context.Context {
99 return internal.WithContext(parent, req)
100 }
101
102 // BlobKey is a key for a blobstore blob.
103 //
104 // Conceptually, this type belongs in the blobstore package, but it lives in
105 // the appengine package to avoid a circular dependency: blobstore depends on
106 // datastore, and datastore needs to refer to the BlobKey type.
107 type BlobKey string
108
109 // GeoPoint represents a location as latitude/longitude in degrees.
110 type GeoPoint struct {
111 Lat, Lng float64
112 }
113
114 // Valid returns whether a GeoPoint is within [-90, 90] latitude and [-180, 180] longitude.
115 func (g GeoPoint) Valid() bool {
116 return -90 <= g.Lat && g.Lat <= 90 && -180 <= g.Lng && g.Lng <= 180
117 }
118
119 // APICallFunc defines a function type for handling an API call.
120 // See WithCallOverride.
121 type APICallFunc func(ctx context.Context, service, method string, in, out proto.Message) error
122
123 // WithAPICallFunc returns a copy of the parent context
124 // that will cause API calls to invoke f instead of their normal operation.
125 //
126 // This is intended for advanced users only.
127 func WithAPICallFunc(ctx context.Context, f APICallFunc) context.Context {
128 return internal.WithCallOverride(ctx, internal.CallOverrideFunc(f))
129 }
130
131 // APICall performs an API call.
132 //
133 // This is not intended for general use; it is exported for use in conjunction
134 // with WithAPICallFunc.
135 func APICall(ctx context.Context, service, method string, in, out proto.Message) error {
136 return internal.Call(ctx, service, method, in, out)
137 }
138
139 // BackgroundContext returns a context not associated with a request.
140 //
141 // Deprecated: App Engine no longer has a special background context.
142 // Just use context.Background().
143 func BackgroundContext() context.Context {
144 return context.Background()
145 }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package appengine
5
6 import (
7 "testing"
8 )
9
10 func TestValidGeoPoint(t *testing.T) {
11 testCases := []struct {
12 desc string
13 pt GeoPoint
14 want bool
15 }{
16 {
17 "valid",
18 GeoPoint{67.21, 13.37},
19 true,
20 },
21 {
22 "high lat",
23 GeoPoint{-90.01, 13.37},
24 false,
25 },
26 {
27 "low lat",
28 GeoPoint{90.01, 13.37},
29 false,
30 },
31 {
32 "high lng",
33 GeoPoint{67.21, 182},
34 false,
35 },
36 {
37 "low lng",
38 GeoPoint{67.21, -181},
39 false,
40 },
41 }
42
43 for _, tc := range testCases {
44 if got := tc.pt.Valid(); got != tc.want {
45 t.Errorf("%s: got %v, want %v", tc.desc, got, tc.want)
46 }
47 }
48 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package blobstore provides a client for App Engine's persistent blob
5 // storage service.
6 package blobstore // import "google.golang.org/appengine/v2/blobstore"
7
8 import (
9 "bufio"
10 "bytes"
11 "context"
12 "encoding/base64"
13 "fmt"
14 "io"
15 "io/ioutil"
16 "mime"
17 "mime/multipart"
18 "net/http"
19 "net/textproto"
20 "net/url"
21 "strconv"
22 "strings"
23 "time"
24
25 "github.com/golang/protobuf/proto"
26 "golang.org/x/text/encoding/htmlindex"
27
28 "google.golang.org/appengine/v2"
29 "google.golang.org/appengine/v2/datastore"
30 "google.golang.org/appengine/v2/internal"
31
32 basepb "google.golang.org/appengine/v2/internal/base"
33 blobpb "google.golang.org/appengine/v2/internal/blobstore"
34 )
35
36 const (
37 blobInfoKind = "__BlobInfo__"
38 blobFileIndexKind = "__BlobFileIndex__"
39 zeroKey = appengine.BlobKey("")
40 )
41
42 // BlobInfo is the blob metadata that is stored in the datastore.
43 // Filename may be empty.
44 type BlobInfo struct {
45 BlobKey appengine.BlobKey
46 ContentType string `datastore:"content_type"`
47 CreationTime time.Time `datastore:"creation"`
48 Filename string `datastore:"filename"`
49 Size int64 `datastore:"size"`
50 MD5 string `datastore:"md5_hash"`
51
52 // ObjectName is the Google Cloud Storage name for this blob.
53 ObjectName string `datastore:"gs_object_name"`
54 }
55
56 // isErrFieldMismatch returns whether err is a datastore.ErrFieldMismatch.
57 //
58 // The blobstore stores blob metadata in the datastore. When loading that
59 // metadata, it may contain fields that we don't care about. datastore.Get will
60 // return datastore.ErrFieldMismatch in that case, so we ignore that specific
61 // error.
62 func isErrFieldMismatch(err error) bool {
63 _, ok := err.(*datastore.ErrFieldMismatch)
64 return ok
65 }
66
67 // Stat returns the BlobInfo for a provided blobKey. If no blob was found for
68 // that key, Stat returns datastore.ErrNoSuchEntity.
69 func Stat(c context.Context, blobKey appengine.BlobKey) (*BlobInfo, error) {
70 c, _ = appengine.Namespace(c, "") // Blobstore is always in the empty string namespace
71 dskey := datastore.NewKey(c, blobInfoKind, string(blobKey), 0, nil)
72 bi := &BlobInfo{
73 BlobKey: blobKey,
74 }
75 if err := datastore.Get(c, dskey, bi); err != nil && !isErrFieldMismatch(err) {
76 return nil, err
77 }
78 return bi, nil
79 }
80
81 // Send sets the headers on response to instruct App Engine to send a blob as
82 // the response body. This is more efficient than reading and writing it out
83 // manually and isn't subject to normal response size limits.
84 func Send(response http.ResponseWriter, blobKey appengine.BlobKey) {
85 hdr := response.Header()
86 hdr.Set("X-AppEngine-BlobKey", string(blobKey))
87
88 if hdr.Get("Content-Type") == "" {
89 // This value is known to dev_appserver to mean automatic.
90 // In production this is remapped to the empty value which
91 // means automatic.
92 hdr.Set("Content-Type", "application/vnd.google.appengine.auto")
93 }
94 }
95
96 // UploadURL creates an upload URL for the form that the user will
97 // fill out, passing the application path to load when the POST of the
98 // form is completed. These URLs expire and should not be reused. The
99 // opts parameter may be nil.
100 func UploadURL(c context.Context, successPath string, opts *UploadURLOptions) (*url.URL, error) {
101 req := &blobpb.CreateUploadURLRequest{
102 SuccessPath: proto.String(successPath),
103 }
104 if opts != nil {
105 if n := opts.MaxUploadBytes; n != 0 {
106 req.MaxUploadSizeBytes = &n
107 }
108 if n := opts.MaxUploadBytesPerBlob; n != 0 {
109 req.MaxUploadSizePerBlobBytes = &n
110 }
111 if s := opts.StorageBucket; s != "" {
112 req.GsBucketName = &s
113 }
114 }
115 res := &blobpb.CreateUploadURLResponse{}
116 if err := internal.Call(c, "blobstore", "CreateUploadURL", req, res); err != nil {
117 return nil, err
118 }
119 return url.Parse(*res.Url)
120 }
121
122 // UploadURLOptions are the options to create an upload URL.
123 type UploadURLOptions struct {
124 MaxUploadBytes int64 // optional
125 MaxUploadBytesPerBlob int64 // optional
126
127 // StorageBucket specifies the Google Cloud Storage bucket in which
128 // to store the blob.
129 // This is required if you use Cloud Storage instead of Blobstore.
130 // Your application must have permission to write to the bucket.
131 // You may optionally specify a bucket name and path in the format
132 // "bucket_name/path", in which case the included path will be the
133 // prefix of the uploaded object's name.
134 StorageBucket string
135 }
136
137 // Delete deletes a blob.
138 func Delete(c context.Context, blobKey appengine.BlobKey) error {
139 return DeleteMulti(c, []appengine.BlobKey{blobKey})
140 }
141
142 // DeleteMulti deletes multiple blobs.
143 func DeleteMulti(c context.Context, blobKey []appengine.BlobKey) error {
144 s := make([]string, len(blobKey))
145 for i, b := range blobKey {
146 s[i] = string(b)
147 }
148 req := &blobpb.DeleteBlobRequest{
149 BlobKey: s,
150 }
151 res := &basepb.VoidProto{}
152 if err := internal.Call(c, "blobstore", "DeleteBlob", req, res); err != nil {
153 return err
154 }
155 return nil
156 }
157
158 func errorf(format string, args ...interface{}) error {
159 return fmt.Errorf("blobstore: "+format, args...)
160 }
161
162 // ParseUpload parses the synthetic POST request that your app gets from
163 // App Engine after a user's successful upload of blobs. Given the request,
164 // ParseUpload returns a map of the blobs received (keyed by HTML form
165 // element name) and other non-blob POST parameters.
166 func ParseUpload(req *http.Request) (blobs map[string][]*BlobInfo, other url.Values, err error) {
167 _, params, err := mime.ParseMediaType(req.Header.Get("Content-Type"))
168 if err != nil {
169 return nil, nil, err
170 }
171 boundary := params["boundary"]
172 if boundary == "" {
173 return nil, nil, errorf("did not find MIME multipart boundary")
174 }
175
176 blobs = make(map[string][]*BlobInfo)
177 other = make(url.Values)
178
179 mreader := multipart.NewReader(io.MultiReader(req.Body, strings.NewReader("\r\n\r\n")), boundary)
180 for {
181 part, perr := mreader.NextPart()
182 if perr == io.EOF {
183 break
184 }
185 if perr != nil {
186 return nil, nil, errorf("error reading next mime part with boundary %q (len=%d): %v",
187 boundary, len(boundary), perr)
188 }
189
190 bi := &BlobInfo{}
191 ctype, params, err := mime.ParseMediaType(part.Header.Get("Content-Disposition"))
192 if err != nil {
193 return nil, nil, err
194 }
195 bi.Filename = params["filename"]
196 formKey := params["name"]
197
198 ctype, params, err = mime.ParseMediaType(part.Header.Get("Content-Type"))
199 if err != nil {
200 return nil, nil, err
201 }
202 bi.BlobKey = appengine.BlobKey(params["blob-key"])
203 charset := params["charset"]
204
205 if ctype != "message/external-body" || bi.BlobKey == "" {
206 if formKey != "" {
207 slurp, serr := ioutil.ReadAll(part)
208 if serr != nil {
209 return nil, nil, errorf("error reading %q MIME part", formKey)
210 }
211
212 // Handle base64 content transfer encoding. multipart.Part transparently
213 // handles quoted-printable, and no special handling is required for
214 // 7bit, 8bit, or binary.
215 ctype, params, err = mime.ParseMediaType(part.Header.Get("Content-Transfer-Encoding"))
216 if err == nil && ctype == "base64" {
217 slurp, serr = ioutil.ReadAll(base64.NewDecoder(
218 base64.StdEncoding, bytes.NewReader(slurp)))
219 if serr != nil {
220 return nil, nil, errorf("error %s decoding %q MIME part", ctype, formKey)
221 }
222 }
223
224 // Handle charset
225 if charset != "" {
226 encoding, err := htmlindex.Get(charset)
227 if err != nil {
228 return nil, nil, errorf("error getting decoder for charset %q", charset)
229 }
230
231 slurp, err = encoding.NewDecoder().Bytes(slurp)
232 if err != nil {
233 return nil, nil, errorf("error decoding from charset %q", charset)
234 }
235 }
236
237 other[formKey] = append(other[formKey], string(slurp))
238 }
239 continue
240 }
241
242 // App Engine sends a MIME header as the body of each MIME part.
243 tp := textproto.NewReader(bufio.NewReader(part))
244 header, mimeerr := tp.ReadMIMEHeader()
245 if mimeerr != nil {
246 return nil, nil, mimeerr
247 }
248 bi.Size, err = strconv.ParseInt(header.Get("Content-Length"), 10, 64)
249 if err != nil {
250 return nil, nil, err
251 }
252 bi.ContentType = header.Get("Content-Type")
253
254 // Parse the time from the MIME header like:
255 // X-AppEngine-Upload-Creation: 2011-03-15 21:38:34.712136
256 createDate := header.Get("X-AppEngine-Upload-Creation")
257 if createDate == "" {
258 return nil, nil, errorf("expected to find an X-AppEngine-Upload-Creation header")
259 }
260 bi.CreationTime, err = time.Parse("2006-01-02 15:04:05.000000", createDate)
261 if err != nil {
262 return nil, nil, errorf("error parsing X-AppEngine-Upload-Creation: %s", err)
263 }
264
265 if hdr := header.Get("Content-MD5"); hdr != "" {
266 md5, err := base64.URLEncoding.DecodeString(hdr)
267 if err != nil {
268 return nil, nil, errorf("bad Content-MD5 %q: %v", hdr, err)
269 }
270 bi.MD5 = string(md5)
271 }
272
273 // If the GCS object name was provided, record it.
274 bi.ObjectName = header.Get("X-AppEngine-Cloud-Storage-Object")
275
276 blobs[formKey] = append(blobs[formKey], bi)
277 }
278 return
279 }
280
281 // Reader is a blob reader.
282 type Reader interface {
283 io.Reader
284 io.ReaderAt
285 io.Seeker
286 }
287
288 // NewReader returns a reader for a blob. It always succeeds; if the blob does
289 // not exist then an error will be reported upon first read.
290 func NewReader(c context.Context, blobKey appengine.BlobKey) Reader {
291 return openBlob(c, blobKey)
292 }
293
294 // BlobKeyForFile returns a BlobKey for a Google Storage file.
295 // The filename should be of the form "/gs/bucket_name/object_name".
296 func BlobKeyForFile(c context.Context, filename string) (appengine.BlobKey, error) {
297 req := &blobpb.CreateEncodedGoogleStorageKeyRequest{
298 Filename: &filename,
299 }
300 res := &blobpb.CreateEncodedGoogleStorageKeyResponse{}
301 if err := internal.Call(c, "blobstore", "CreateEncodedGoogleStorageKey", req, res); err != nil {
302 return "", err
303 }
304 return appengine.BlobKey(*res.BlobKey), nil
305 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package blobstore
5
6 import (
7 "bytes"
8 "encoding/base64"
9 "fmt"
10 "io"
11 "mime/multipart"
12 "mime/quotedprintable"
13 "net/http"
14 "net/textproto"
15 "os"
16 "strconv"
17 "strings"
18 "testing"
19
20 "golang.org/x/text/encoding/htmlindex"
21
22 "google.golang.org/appengine/v2"
23 "google.golang.org/appengine/v2/internal/aetesting"
24
25 pb "google.golang.org/appengine/v2/internal/blobstore"
26 )
27
28 const rbs = readBufferSize
29
30 const charsetUTF8 = "utf-8"
31 const charsetISO2022JP = "iso-2022-jp"
32 const nonASCIIStr = "Hello, 世界"
33
34 func min(x, y int) int {
35 if x < y {
36 return x
37 }
38 return y
39 }
40
41 func fakeFetchData(req *pb.FetchDataRequest, res *pb.FetchDataResponse) error {
42 i0 := int(*req.StartIndex)
43 i1 := int(*req.EndIndex + 1) // Blobstore's end-indices are inclusive; Go's are exclusive.
44 bk := *req.BlobKey
45 if i := strings.Index(bk, "."); i != -1 {
46 // Strip everything past the ".".
47 bk = bk[:i]
48 }
49 switch bk {
50 case "a14p":
51 const s = "abcdefghijklmnop"
52 i0 := min(len(s), i0)
53 i1 := min(len(s), i1)
54 res.Data = []byte(s[i0:i1])
55 case "longBlob":
56 res.Data = make([]byte, i1-i0)
57 for i := range res.Data {
58 res.Data[i] = 'A' + uint8(i0/rbs)
59 i0++
60 }
61 }
62 return nil
63 }
64
65 // step is one step of a readerTest.
66 // It consists of a Reader method to call, the method arguments
67 // (lenp, offset, whence) and the expected results.
68 type step struct {
69 method string
70 lenp int
71 offset int64
72 whence int
73 want string
74 wantErr error
75 }
76
77 var readerTest = []struct {
78 blobKey string
79 step []step
80 }{
81 {"noSuchBlobKey", []step{
82 {"Read", 8, 0, 0, "", io.EOF},
83 }},
84 {"a14p.0", []step{
85 // Test basic reads.
86 {"Read", 1, 0, 0, "a", nil},
87 {"Read", 3, 0, 0, "bcd", nil},
88 {"Read", 1, 0, 0, "e", nil},
89 {"Read", 2, 0, 0, "fg", nil},
90 // Test Seek.
91 {"Seek", 0, 2, os.SEEK_SET, "2", nil},
92 {"Read", 5, 0, 0, "cdefg", nil},
93 {"Seek", 0, 2, os.SEEK_CUR, "9", nil},
94 {"Read", 1, 0, 0, "j", nil},
95 // Test reads up to and past EOF.
96 {"Read", 5, 0, 0, "klmno", nil},
97 {"Read", 5, 0, 0, "p", nil},
98 {"Read", 5, 0, 0, "", io.EOF},
99 // Test ReadAt.
100 {"ReadAt", 4, 0, 0, "abcd", nil},
101 {"ReadAt", 4, 3, 0, "defg", nil},
102 {"ReadAt", 4, 12, 0, "mnop", nil},
103 {"ReadAt", 4, 13, 0, "nop", io.EOF},
104 {"ReadAt", 4, 99, 0, "", io.EOF},
105 }},
106 {"a14p.1", []step{
107 // Test Seek before any reads.
108 {"Seek", 0, 2, os.SEEK_SET, "2", nil},
109 {"Read", 1, 0, 0, "c", nil},
110 // Test that ReadAt doesn't affect the Read offset.
111 {"ReadAt", 3, 9, 0, "jkl", nil},
112 {"Read", 3, 0, 0, "def", nil},
113 }},
114 {"a14p.2", []step{
115 // Test ReadAt before any reads or seeks.
116 {"ReadAt", 2, 14, 0, "op", nil},
117 }},
118 {"longBlob.0", []step{
119 // Test basic read.
120 {"Read", 1, 0, 0, "A", nil},
121 // Test that Read returns early when the buffer is exhausted.
122 {"Seek", 0, rbs - 2, os.SEEK_SET, strconv.Itoa(rbs - 2), nil},
123 {"Read", 5, 0, 0, "AA", nil},
124 {"Read", 3, 0, 0, "BBB", nil},
125 // Test that what we just read is still in the buffer.
126 {"Seek", 0, rbs - 2, os.SEEK_SET, strconv.Itoa(rbs - 2), nil},
127 {"Read", 5, 0, 0, "AABBB", nil},
128 // Test ReadAt.
129 {"ReadAt", 3, rbs - 4, 0, "AAA", nil},
130 {"ReadAt", 6, rbs - 4, 0, "AAAABB", nil},
131 {"ReadAt", 8, rbs - 4, 0, "AAAABBBB", nil},
132 {"ReadAt", 5, rbs - 4, 0, "AAAAB", nil},
133 {"ReadAt", 2, rbs - 4, 0, "AA", nil},
134 // Test seeking backwards from the Read offset.
135 {"Seek", 0, 2*rbs - 8, os.SEEK_SET, strconv.Itoa(2*rbs - 8), nil},
136 {"Read", 1, 0, 0, "B", nil},
137 {"Read", 1, 0, 0, "B", nil},
138 {"Read", 1, 0, 0, "B", nil},
139 {"Read", 1, 0, 0, "B", nil},
140 {"Read", 8, 0, 0, "BBBBCCCC", nil},
141 }},
142 {"longBlob.1", []step{
143 // Test ReadAt with a slice larger than the buffer size.
144 {"LargeReadAt", 2*rbs - 2, 0, 0, strconv.Itoa(2*rbs - 2), nil},
145 {"LargeReadAt", 2*rbs - 1, 0, 0, strconv.Itoa(2*rbs - 1), nil},
146 {"LargeReadAt", 2*rbs + 0, 0, 0, strconv.Itoa(2*rbs + 0), nil},
147 {"LargeReadAt", 2*rbs + 1, 0, 0, strconv.Itoa(2*rbs + 1), nil},
148 {"LargeReadAt", 2*rbs + 2, 0, 0, strconv.Itoa(2*rbs + 2), nil},
149 {"LargeReadAt", 2*rbs - 2, 1, 0, strconv.Itoa(2*rbs - 2), nil},
150 {"LargeReadAt", 2*rbs - 1, 1, 0, strconv.Itoa(2*rbs - 1), nil},
151 {"LargeReadAt", 2*rbs + 0, 1, 0, strconv.Itoa(2*rbs + 0), nil},
152 {"LargeReadAt", 2*rbs + 1, 1, 0, strconv.Itoa(2*rbs + 1), nil},
153 {"LargeReadAt", 2*rbs + 2, 1, 0, strconv.Itoa(2*rbs + 2), nil},
154 }},
155 }
156
157 func TestReader(t *testing.T) {
158 for _, rt := range readerTest {
159 c := aetesting.FakeSingleContext(t, "blobstore", "FetchData", fakeFetchData)
160 r := NewReader(c, appengine.BlobKey(rt.blobKey))
161 for i, step := range rt.step {
162 var (
163 got string
164 gotErr error
165 n int
166 offset int64
167 )
168 switch step.method {
169 case "LargeReadAt":
170 p := make([]byte, step.lenp)
171 n, gotErr = r.ReadAt(p, step.offset)
172 got = strconv.Itoa(n)
173 case "Read":
174 p := make([]byte, step.lenp)
175 n, gotErr = r.Read(p)
176 got = string(p[:n])
177 case "ReadAt":
178 p := make([]byte, step.lenp)
179 n, gotErr = r.ReadAt(p, step.offset)
180 got = string(p[:n])
181 case "Seek":
182 offset, gotErr = r.Seek(step.offset, step.whence)
183 got = strconv.FormatInt(offset, 10)
184 default:
185 t.Fatalf("unknown method: %s", step.method)
186 }
187 if gotErr != step.wantErr {
188 t.Fatalf("%s step %d: got error %v want %v", rt.blobKey, i, gotErr, step.wantErr)
189 }
190 if got != step.want {
191 t.Fatalf("%s step %d: got %q want %q", rt.blobKey, i, got, step.want)
192 }
193 }
194 }
195 }
196
197 // doPlainTextParseUploadTest tests ParseUpload's decoding of non-file form fields.
198 // It ensures that MIME multipart parts with Content-Type not equal to
199 // "message/external-body" (i.e. form fields that are not file uploads) are decoded
200 // correctly according to the value of their Content-Transfer-Encoding header field.
201 // If charset is not the empty string it will be set in the request's Content-Type
202 // header field, and if encoding is not the empty string then the Content-Transfer-Encoding
203 // header field will be set.
204 func doPlainTextParseUploadTest(t *testing.T, charset string, encoding string,
205 rawContent string, encodedContent string) {
206 bodyBuf := &bytes.Buffer{}
207 w := multipart.NewWriter(bodyBuf)
208
209 fieldName := "foo"
210 hdr := textproto.MIMEHeader{}
211 hdr.Set("Content-Disposition", fmt.Sprintf("form-data; name=%q", fieldName))
212
213 if charset != "" {
214 hdr.Set("Content-Type", fmt.Sprintf("text/plain; charset=%q", charset))
215 } else {
216 hdr.Set("Content-Type", "text/plain")
217 }
218
219 if encoding != "" {
220 hdr.Set("Content-Transfer-Encoding", encoding)
221 }
222
223 pw, err := w.CreatePart(hdr)
224 if err != nil {
225 t.Fatalf("error creating part: %v", err)
226 }
227 pw.Write([]byte(encodedContent))
228
229 if err := w.Close(); err != nil {
230 t.Fatalf("error closing multipart writer: %v\n", err)
231 }
232
233 req, err := http.NewRequest("POST", "/upload", bodyBuf)
234 if err != nil {
235 t.Fatalf("error creating request: %v", err)
236 }
237
238 req.Header.Set("Content-Type", w.FormDataContentType())
239 _, other, err := ParseUpload(req)
240 if err != nil {
241 t.Fatalf("error parsing upload: %v", err)
242 }
243
244 if other[fieldName][0] != rawContent {
245 t.Errorf("got %q expected %q", other[fieldName][0], rawContent)
246 }
247 }
248
249 func TestParseUploadUTF8Base64Encoding(t *testing.T) {
250 encoded := base64.StdEncoding.EncodeToString([]byte(nonASCIIStr))
251 doPlainTextParseUploadTest(t, charsetUTF8, "base64", nonASCIIStr, encoded)
252 }
253
254 func TestParseUploadUTF8Base64EncodingMultiline(t *testing.T) {
255 testStr := "words words words words words words words words words words words words"
256 encoded := "d29yZHMgd29yZHMgd29yZHMgd29yZHMgd29yZHMgd29yZHMgd29yZHMgd29yZHMgd29yZHMgd29y\r\nZHMgd29yZHMgd29yZHM="
257 doPlainTextParseUploadTest(t, charsetUTF8, "base64", testStr, encoded)
258 }
259
260 func TestParseUploadUTF8QuotedPrintableEncoding(t *testing.T) {
261 var encoded bytes.Buffer
262 writer := quotedprintable.NewWriter(&encoded)
263 writer.Write([]byte(nonASCIIStr))
264 writer.Close()
265
266 doPlainTextParseUploadTest(t, charsetUTF8, "quoted-printable", nonASCIIStr,
267 encoded.String())
268 }
269
270 func TestParseUploadISO2022JPBase64Encoding(t *testing.T) {
271 testStr := "こんにちは"
272 encoding, err := htmlindex.Get(charsetISO2022JP)
273 if err != nil {
274 t.Fatalf("error getting encoding: %v", err)
275 }
276
277 charsetEncoded, err := encoding.NewEncoder().String(testStr)
278 if err != nil {
279 t.Fatalf("error encoding string: %v", err)
280 }
281
282 base64Encoded := base64.StdEncoding.EncodeToString([]byte(charsetEncoded))
283 doPlainTextParseUploadTest(t, charsetISO2022JP, "base64", testStr, base64Encoded)
284 }
285
286 func TestParseUploadNoEncoding(t *testing.T) {
287 doPlainTextParseUploadTest(t, "", "", "Hello", "Hello")
288 }
0 // Copyright 2012 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package blobstore
5
6 import (
7 "context"
8 "errors"
9 "fmt"
10 "io"
11 "os"
12 "sync"
13
14 "github.com/golang/protobuf/proto"
15
16 "google.golang.org/appengine/v2"
17 "google.golang.org/appengine/v2/internal"
18
19 blobpb "google.golang.org/appengine/v2/internal/blobstore"
20 )
21
22 // openBlob returns a reader for a blob. It always succeeds; if the blob does
23 // not exist then an error will be reported upon first read.
24 func openBlob(c context.Context, blobKey appengine.BlobKey) Reader {
25 return &reader{
26 c: c,
27 blobKey: blobKey,
28 }
29 }
30
31 const readBufferSize = 256 * 1024
32
33 // reader is a blob reader. It implements the Reader interface.
34 type reader struct {
35 c context.Context
36
37 // Either blobKey or filename is set:
38 blobKey appengine.BlobKey
39 filename string
40
41 closeFunc func() // is nil if unavailable or already closed.
42
43 // buf is the read buffer. r is how much of buf has been read.
44 // off is the offset of buf[0] relative to the start of the blob.
45 // An invariant is 0 <= r && r <= len(buf).
46 // Reads that don't require an RPC call will increment r but not off.
47 // Seeks may modify r without discarding the buffer, but only if the
48 // invariant can be maintained.
49 mu sync.Mutex
50 buf []byte
51 r int
52 off int64
53 }
54
55 func (r *reader) Close() error {
56 if f := r.closeFunc; f != nil {
57 f()
58 }
59 r.closeFunc = nil
60 return nil
61 }
62
63 func (r *reader) Read(p []byte) (int, error) {
64 if len(p) == 0 {
65 return 0, nil
66 }
67 r.mu.Lock()
68 defer r.mu.Unlock()
69 if r.r == len(r.buf) {
70 if err := r.fetch(r.off + int64(r.r)); err != nil {
71 return 0, err
72 }
73 }
74 n := copy(p, r.buf[r.r:])
75 r.r += n
76 return n, nil
77 }
78
79 func (r *reader) ReadAt(p []byte, off int64) (int, error) {
80 if len(p) == 0 {
81 return 0, nil
82 }
83 r.mu.Lock()
84 defer r.mu.Unlock()
85 // Convert relative offsets to absolute offsets.
86 ab0 := r.off + int64(r.r)
87 ab1 := r.off + int64(len(r.buf))
88 ap0 := off
89 ap1 := off + int64(len(p))
90 // Check if we can satisfy the read entirely out of the existing buffer.
91 if r.off <= ap0 && ap1 <= ab1 {
92 // Convert off from an absolute offset to a relative offset.
93 rp0 := int(ap0 - r.off)
94 return copy(p, r.buf[rp0:]), nil
95 }
96 // Restore the original Read/Seek offset after ReadAt completes.
97 defer r.seek(ab0)
98 // Repeatedly fetch and copy until we have filled p.
99 n := 0
100 for len(p) > 0 {
101 if err := r.fetch(off + int64(n)); err != nil {
102 return n, err
103 }
104 r.r = copy(p, r.buf)
105 n += r.r
106 p = p[r.r:]
107 }
108 return n, nil
109 }
110
111 func (r *reader) Seek(offset int64, whence int) (ret int64, err error) {
112 r.mu.Lock()
113 defer r.mu.Unlock()
114 switch whence {
115 case os.SEEK_SET:
116 ret = offset
117 case os.SEEK_CUR:
118 ret = r.off + int64(r.r) + offset
119 case os.SEEK_END:
120 return 0, errors.New("seeking relative to the end of a blob isn't supported")
121 default:
122 return 0, fmt.Errorf("invalid Seek whence value: %d", whence)
123 }
124 if ret < 0 {
125 return 0, errors.New("negative Seek offset")
126 }
127 return r.seek(ret)
128 }
129
130 // fetch fetches readBufferSize bytes starting at the given offset. On success,
131 // the data is saved as r.buf.
132 func (r *reader) fetch(off int64) error {
133 req := &blobpb.FetchDataRequest{
134 BlobKey: proto.String(string(r.blobKey)),
135 StartIndex: proto.Int64(off),
136 EndIndex: proto.Int64(off + readBufferSize - 1), // EndIndex is inclusive.
137 }
138 res := &blobpb.FetchDataResponse{}
139 if err := internal.Call(r.c, "blobstore", "FetchData", req, res); err != nil {
140 return err
141 }
142 if len(res.Data) == 0 {
143 return io.EOF
144 }
145 r.buf, r.r, r.off = res.Data, 0, off
146 return nil
147 }
148
149 // seek seeks to the given offset with an effective whence equal to SEEK_SET.
150 // It discards the read buffer if the invariant cannot be maintained.
151 func (r *reader) seek(off int64) (int64, error) {
152 delta := off - r.off
153 if delta >= 0 && delta < int64(len(r.buf)) {
154 r.r = int(delta)
155 return off, nil
156 }
157 r.buf, r.r, r.off = nil, 0, off
158 return off, nil
159 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 /*
5 Package capability exposes information about outages and scheduled downtime
6 for specific API capabilities.
7
8 This package does not work in App Engine "flexible environment".
9
10 Example:
11
12 if !capability.Enabled(c, "datastore_v3", "write") {
13 // show user a different page
14 }
15 */
16 package capability // import "google.golang.org/appengine/v2/capability"
17
18 import (
19 "context"
20
21 "google.golang.org/appengine/v2/internal"
22 "google.golang.org/appengine/v2/log"
23
24 pb "google.golang.org/appengine/v2/internal/capability"
25 )
26
27 // Enabled returns whether an API's capabilities are enabled.
28 // The wildcard "*" capability matches every capability of an API.
29 // If the underlying RPC fails (if the package is unknown, for example),
30 // false is returned and information is written to the application log.
31 func Enabled(ctx context.Context, api, capability string) bool {
32 // For non datastore*/write requests always return ENABLED
33 if !(api == "datastore_v3" && capability == "write") {
34 return true
35 }
36
37 req := &pb.IsEnabledRequest{
38 Package: &api,
39 Capability: []string{capability},
40 }
41 res := &pb.IsEnabledResponse{}
42 if err := internal.Call(ctx, "capability_service", "IsEnabled", req, res); err != nil {
43 log.Warningf(ctx, "capability.Enabled: RPC failed: %v", err)
44 return false
45 }
46 return *res.SummaryStatus == pb.IsEnabledResponse_ENABLED
47 }
0 // Copyright 2015 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Program aebundler turns a Go app into a fully self-contained tar file.
5 // The app and its subdirectories (if any) are placed under "."
6 // and the dependencies from $GOPATH are placed under ./_gopath/src.
7 // A main func is synthesized if one does not exist.
8 //
9 // A sample Dockerfile to be used with this bundler could look like this:
10 //
11 // FROM gcr.io/google-appengine/go-compat
12 // ADD . /app
13 // RUN GOPATH=/app/_gopath go build -tags appenginevm -o /app/_ah/exe
14 package main
15
16 import (
17 "archive/tar"
18 "flag"
19 "fmt"
20 "go/ast"
21 "go/build"
22 "go/parser"
23 "go/token"
24 "io"
25 "io/ioutil"
26 "os"
27 "path/filepath"
28 "strings"
29 )
30
31 var (
32 output = flag.String("o", "", "name of output tar file or '-' for stdout")
33 rootDir = flag.String("root", ".", "directory name of application root")
34 vm = flag.Bool("vm", true, `bundle an app for App Engine "flexible environment"`)
35
36 skipFiles = map[string]bool{
37 ".git": true,
38 ".gitconfig": true,
39 ".hg": true,
40 ".travis.yml": true,
41 }
42 )
43
44 const (
45 newMain = `package main
46 import "google.golang.org/appengine/v2"
47 func main() {
48 appengine.Main()
49 }
50 `
51 )
52
53 func usage() {
54 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
55 fmt.Fprintf(os.Stderr, "\t%s -o <file.tar|->\tBundle app to named tar file or stdout\n", os.Args[0])
56 fmt.Fprintf(os.Stderr, "\noptional arguments:\n")
57 flag.PrintDefaults()
58 }
59
60 func main() {
61 flag.Usage = usage
62 flag.Parse()
63
64 var tags []string
65 if *vm {
66 tags = append(tags, "appenginevm")
67 } else {
68 tags = append(tags, "appengine")
69 }
70
71 tarFile := *output
72 if tarFile == "" {
73 usage()
74 errorf("Required -o flag not specified.")
75 }
76
77 app, err := analyze(tags)
78 if err != nil {
79 errorf("Error analyzing app: %v", err)
80 }
81 if err := app.bundle(tarFile); err != nil {
82 errorf("Unable to bundle app: %v", err)
83 }
84 }
85
86 // errorf prints the error message and exits.
87 func errorf(format string, a ...interface{}) {
88 fmt.Fprintf(os.Stderr, "aebundler: "+format+"\n", a...)
89 os.Exit(1)
90 }
91
92 type app struct {
93 hasMain bool
94 appFiles []string
95 imports map[string]string
96 }
97
98 // analyze checks the app for building with the given build tags and returns hasMain,
99 // app files, and a map of full directory import names to original import names.
100 func analyze(tags []string) (*app, error) {
101 ctxt := buildContext(tags)
102 hasMain, appFiles, err := checkMain(ctxt)
103 if err != nil {
104 return nil, err
105 }
106 gopath := filepath.SplitList(ctxt.GOPATH)
107 im, err := imports(ctxt, *rootDir, gopath)
108 return &app{
109 hasMain: hasMain,
110 appFiles: appFiles,
111 imports: im,
112 }, err
113 }
114
115 // buildContext returns the context for building the source.
116 func buildContext(tags []string) *build.Context {
117 return &build.Context{
118 GOARCH: build.Default.GOARCH,
119 GOOS: build.Default.GOOS,
120 GOROOT: build.Default.GOROOT,
121 GOPATH: build.Default.GOPATH,
122 Compiler: build.Default.Compiler,
123 BuildTags: append(build.Default.BuildTags, tags...),
124 }
125 }
126
127 // bundle bundles the app into the named tarFile ("-"==stdout).
128 func (s *app) bundle(tarFile string) (err error) {
129 var out io.Writer
130 if tarFile == "-" {
131 out = os.Stdout
132 } else {
133 f, err := os.Create(tarFile)
134 if err != nil {
135 return err
136 }
137 defer func() {
138 if cerr := f.Close(); err == nil {
139 err = cerr
140 }
141 }()
142 out = f
143 }
144 tw := tar.NewWriter(out)
145
146 for srcDir, importName := range s.imports {
147 dstDir := "_gopath/src/" + importName
148 if err = copyTree(tw, dstDir, srcDir); err != nil {
149 return fmt.Errorf("unable to copy directory %v to %v: %v", srcDir, dstDir, err)
150 }
151 }
152 if err := copyTree(tw, ".", *rootDir); err != nil {
153 return fmt.Errorf("unable to copy root directory to /app: %v", err)
154 }
155 if !s.hasMain {
156 if err := synthesizeMain(tw, s.appFiles); err != nil {
157 return fmt.Errorf("unable to synthesize new main func: %v", err)
158 }
159 }
160
161 if err := tw.Close(); err != nil {
162 return fmt.Errorf("unable to close tar file %v: %v", tarFile, err)
163 }
164 return nil
165 }
166
167 // synthesizeMain generates a new main func and writes it to the tarball.
168 func synthesizeMain(tw *tar.Writer, appFiles []string) error {
169 appMap := make(map[string]bool)
170 for _, f := range appFiles {
171 appMap[f] = true
172 }
173 var f string
174 for i := 0; i < 100; i++ {
175 f = fmt.Sprintf("app_main%d.go", i)
176 if !appMap[filepath.Join(*rootDir, f)] {
177 break
178 }
179 }
180 if appMap[filepath.Join(*rootDir, f)] {
181 return fmt.Errorf("unable to find unique name for %v", f)
182 }
183 hdr := &tar.Header{
184 Name: f,
185 Mode: 0644,
186 Size: int64(len(newMain)),
187 }
188 if err := tw.WriteHeader(hdr); err != nil {
189 return fmt.Errorf("unable to write header for %v: %v", f, err)
190 }
191 if _, err := tw.Write([]byte(newMain)); err != nil {
192 return fmt.Errorf("unable to write %v to tar file: %v", f, err)
193 }
194 return nil
195 }
196
197 // imports returns a map of all import directories (recursively) used by the app.
198 // The return value maps full directory names to original import names.
199 func imports(ctxt *build.Context, srcDir string, gopath []string) (map[string]string, error) {
200 pkg, err := ctxt.ImportDir(srcDir, 0)
201 if err != nil {
202 return nil, fmt.Errorf("unable to analyze source: %v", err)
203 }
204
205 // Resolve all non-standard-library imports
206 result := make(map[string]string)
207 for _, v := range pkg.Imports {
208 if !strings.Contains(v, ".") {
209 continue
210 }
211 src, err := findInGopath(v, gopath)
212 if err != nil {
213 return nil, fmt.Errorf("unable to find import %v in gopath %v: %v", v, gopath, err)
214 }
215 result[src] = v
216 im, err := imports(ctxt, src, gopath)
217 if err != nil {
218 return nil, fmt.Errorf("unable to parse package %v: %v", src, err)
219 }
220 for k, v := range im {
221 result[k] = v
222 }
223 }
224 return result, nil
225 }
226
227 // findInGopath searches the gopath for the named import directory.
228 func findInGopath(dir string, gopath []string) (string, error) {
229 for _, v := range gopath {
230 dst := filepath.Join(v, "src", dir)
231 if _, err := os.Stat(dst); err == nil {
232 return dst, nil
233 }
234 }
235 return "", fmt.Errorf("unable to find package %v in gopath %v", dir, gopath)
236 }
237
238 // copyTree copies srcDir to tar file dstDir, ignoring skipFiles.
239 func copyTree(tw *tar.Writer, dstDir, srcDir string) error {
240 entries, err := ioutil.ReadDir(srcDir)
241 if err != nil {
242 return fmt.Errorf("unable to read dir %v: %v", srcDir, err)
243 }
244 for _, entry := range entries {
245 n := entry.Name()
246 if skipFiles[n] {
247 continue
248 }
249 s := filepath.Join(srcDir, n)
250 d := filepath.Join(dstDir, n)
251 if entry.IsDir() {
252 if err := copyTree(tw, d, s); err != nil {
253 return fmt.Errorf("unable to copy dir %v to %v: %v", s, d, err)
254 }
255 continue
256 }
257 if err := copyFile(tw, d, s); err != nil {
258 return fmt.Errorf("unable to copy dir %v to %v: %v", s, d, err)
259 }
260 }
261 return nil
262 }
263
264 // copyFile copies src to tar file dst.
265 func copyFile(tw *tar.Writer, dst, src string) error {
266 s, err := os.Open(src)
267 if err != nil {
268 return fmt.Errorf("unable to open %v: %v", src, err)
269 }
270 defer s.Close()
271 fi, err := s.Stat()
272 if err != nil {
273 return fmt.Errorf("unable to stat %v: %v", src, err)
274 }
275
276 hdr, err := tar.FileInfoHeader(fi, dst)
277 if err != nil {
278 return fmt.Errorf("unable to create tar header for %v: %v", dst, err)
279 }
280 hdr.Name = dst
281 if err := tw.WriteHeader(hdr); err != nil {
282 return fmt.Errorf("unable to write header for %v: %v", dst, err)
283 }
284 _, err = io.Copy(tw, s)
285 if err != nil {
286 return fmt.Errorf("unable to copy %v to %v: %v", src, dst, err)
287 }
288 return nil
289 }
290
291 // checkMain verifies that there is a single "main" function.
292 // It also returns a list of all Go source files in the app.
293 func checkMain(ctxt *build.Context) (bool, []string, error) {
294 pkg, err := ctxt.ImportDir(*rootDir, 0)
295 if err != nil {
296 return false, nil, fmt.Errorf("unable to analyze source: %v", err)
297 }
298 if !pkg.IsCommand() {
299 errorf("Your app's package needs to be changed from %q to \"main\".\n", pkg.Name)
300 }
301 // Search for a "func main"
302 var hasMain bool
303 var appFiles []string
304 for _, f := range pkg.GoFiles {
305 n := filepath.Join(*rootDir, f)
306 appFiles = append(appFiles, n)
307 if hasMain, err = readFile(n); err != nil {
308 return false, nil, fmt.Errorf("error parsing %q: %v", n, err)
309 }
310 }
311 return hasMain, appFiles, nil
312 }
313
314 // isMain returns whether the given function declaration is a main function.
315 // Such a function must be called "main", not have a receiver, and have no arguments or return types.
316 func isMain(f *ast.FuncDecl) bool {
317 ft := f.Type
318 return f.Name.Name == "main" && f.Recv == nil && ft.Params.NumFields() == 0 && ft.Results.NumFields() == 0
319 }
320
321 // readFile reads and parses the Go source code file and returns whether it has a main function.
322 func readFile(filename string) (hasMain bool, err error) {
323 var src []byte
324 src, err = ioutil.ReadFile(filename)
325 if err != nil {
326 return
327 }
328 fset := token.NewFileSet()
329 file, err := parser.ParseFile(fset, filename, src, 0)
330 for _, decl := range file.Decls {
331 funcDecl, ok := decl.(*ast.FuncDecl)
332 if !ok {
333 continue
334 }
335 if !isMain(funcDecl) {
336 continue
337 }
338 hasMain = true
339 break
340 }
341 return
342 }
0 // Copyright 2016 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package main
5
6 import (
7 "go/ast"
8 "strconv"
9 "strings"
10 )
11
12 const (
13 ctxPackage = "golang.org/x/net/context"
14
15 newPackageBase = "google.golang.org/"
16 )
17
18 func init() {
19 register(fix{
20 "ae",
21 "2016-04-15",
22 aeFn,
23 `Update old App Engine APIs to new App Engine APIs`,
24 })
25 }
26
27 // logMethod is the set of methods on appengine.Context used for logging.
28 var logMethod = map[string]bool{
29 "Debugf": true,
30 "Infof": true,
31 "Warningf": true,
32 "Errorf": true,
33 "Criticalf": true,
34 }
35
36 // mapPackage turns "appengine" into "google.golang.org/appengine/v2", etc.
37 func mapPackage(s string) string {
38 return newPackageBase + strings.Replace(s, "appengine", "appengine/v2", 1)
39 }
40
41 func aeFn(f *ast.File) bool {
42 // During the walk, we track the last thing seen that looks like
43 // an appengine.Context, and reset it once the walk leaves a func.
44 var lastContext *ast.Ident
45
46 fixed := false
47
48 // Update imports.
49 mainImp := "appengine"
50 for _, imp := range f.Imports {
51 pth, _ := strconv.Unquote(imp.Path.Value)
52 if pth == "appengine" || strings.HasPrefix(pth, "appengine/") {
53 newPth := mapPackage(pth)
54 imp.Path.Value = strconv.Quote(newPth)
55 fixed = true
56
57 if pth == "appengine" {
58 mainImp = newPth
59 }
60 }
61 }
62
63 // Update any API changes.
64 walk(f, func(n interface{}) {
65 if ft, ok := n.(*ast.FuncType); ok && ft.Params != nil {
66 // See if this func has an `appengine.Context arg`.
67 // If so, remember its identifier.
68 for _, param := range ft.Params.List {
69 if !isPkgDot(param.Type, "appengine", "Context") {
70 continue
71 }
72 if len(param.Names) == 1 {
73 lastContext = param.Names[0]
74 break
75 }
76 }
77 return
78 }
79
80 if as, ok := n.(*ast.AssignStmt); ok {
81 if len(as.Lhs) == 1 && len(as.Rhs) == 1 {
82 // If this node is an assignment from an appengine.NewContext invocation,
83 // remember the identifier on the LHS.
84 if isCall(as.Rhs[0], "appengine", "NewContext") {
85 if ident, ok := as.Lhs[0].(*ast.Ident); ok {
86 lastContext = ident
87 return
88 }
89 }
90 // x (=|:=) appengine.Timeout(y, z)
91 // should become
92 // x, _ (=|:=) context.WithTimeout(y, z)
93 if isCall(as.Rhs[0], "appengine", "Timeout") {
94 addImport(f, ctxPackage)
95 as.Lhs = append(as.Lhs, ast.NewIdent("_"))
96 // isCall already did the type checking.
97 sel := as.Rhs[0].(*ast.CallExpr).Fun.(*ast.SelectorExpr)
98 sel.X = ast.NewIdent("context")
99 sel.Sel = ast.NewIdent("WithTimeout")
100 fixed = true
101 return
102 }
103 }
104 return
105 }
106
107 // If this node is a FuncDecl, we've finished the function, so reset lastContext.
108 if _, ok := n.(*ast.FuncDecl); ok {
109 lastContext = nil
110 return
111 }
112
113 if call, ok := n.(*ast.CallExpr); ok {
114 if isPkgDot(call.Fun, "appengine", "Datacenter") && len(call.Args) == 0 {
115 insertContext(f, call, lastContext)
116 fixed = true
117 return
118 }
119 if isPkgDot(call.Fun, "taskqueue", "QueueStats") && len(call.Args) == 3 {
120 call.Args = call.Args[:2] // drop last arg
121 fixed = true
122 return
123 }
124
125 sel, ok := call.Fun.(*ast.SelectorExpr)
126 if !ok {
127 return
128 }
129 if lastContext != nil && refersTo(sel.X, lastContext) && logMethod[sel.Sel.Name] {
130 // c.Errorf(...)
131 // should become
132 // log.Errorf(c, ...)
133 addImport(f, mapPackage("appengine/log"))
134 sel.X = &ast.Ident{ // ast.NewIdent doesn't preserve the position.
135 NamePos: sel.X.Pos(),
136 Name: "log",
137 }
138 insertContext(f, call, lastContext)
139 fixed = true
140 return
141 }
142 }
143 })
144
145 // Change any `appengine.Context` to `context.Context`.
146 // Do this in a separate walk because the previous walk
147 // wants to identify "appengine.Context".
148 walk(f, func(n interface{}) {
149 expr, ok := n.(ast.Expr)
150 if ok && isPkgDot(expr, "appengine", "Context") {
151 addImport(f, ctxPackage)
152 // isPkgDot did the type checking.
153 n.(*ast.SelectorExpr).X.(*ast.Ident).Name = "context"
154 fixed = true
155 return
156 }
157 })
158
159 // The changes above might remove the need to import "appengine".
160 // Check if it's used, and drop it if it isn't.
161 if fixed && !usesImport(f, mainImp) {
162 deleteImport(f, mainImp)
163 }
164
165 return fixed
166 }
167
168 // ctx may be nil.
169 func insertContext(f *ast.File, call *ast.CallExpr, ctx *ast.Ident) {
170 if ctx == nil {
171 // context is unknown, so use a plain "ctx".
172 ctx = ast.NewIdent("ctx")
173 } else {
174 // Create a fresh *ast.Ident so we drop the position information.
175 ctx = ast.NewIdent(ctx.Name)
176 }
177
178 call.Args = append([]ast.Expr{ctx}, call.Args...)
179 }
0 // Copyright 2016 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package main
5
6 func init() {
7 addTestCases(aeTests, nil)
8 }
9
10 var aeTests = []testCase{
11 // Collection of fixes:
12 // - imports
13 // - appengine.Timeout -> context.WithTimeout
14 // - add ctx arg to appengine.Datacenter
15 // - logging API
16 {
17 Name: "ae.0",
18 In: `package foo
19
20 import (
21 "net/http"
22 "time"
23
24 "appengine"
25 "appengine/datastore"
26 )
27
28 func f(w http.ResponseWriter, r *http.Request) {
29 c := appengine.NewContext(r)
30
31 c = appengine.Timeout(c, 5*time.Second)
32 err := datastore.ErrNoSuchEntity
33 c.Errorf("Something interesting happened: %v", err)
34 _ = appengine.Datacenter()
35 }
36 `,
37 Out: `package foo
38
39 import (
40 "net/http"
41 "time"
42
43 "golang.org/x/net/context"
44 "google.golang.org/appengine/v2"
45 "google.golang.org/appengine/v2/datastore"
46 "google.golang.org/appengine/v2/log"
47 )
48
49 func f(w http.ResponseWriter, r *http.Request) {
50 c := appengine.NewContext(r)
51
52 c, _ = context.WithTimeout(c, 5*time.Second)
53 err := datastore.ErrNoSuchEntity
54 log.Errorf(c, "Something interesting happened: %v", err)
55 _ = appengine.Datacenter(c)
56 }
57 `,
58 },
59
60 // Updating a function that takes an appengine.Context arg.
61 {
62 Name: "ae.1",
63 In: `package foo
64
65 import (
66 "appengine"
67 )
68
69 func LogSomething(c2 appengine.Context) {
70 c2.Warningf("Stand back! I'm going to try science!")
71 }
72 `,
73 Out: `package foo
74
75 import (
76 "golang.org/x/net/context"
77 "google.golang.org/appengine/v2/log"
78 )
79
80 func LogSomething(c2 context.Context) {
81 log.Warningf(c2, "Stand back! I'm going to try science!")
82 }
83 `,
84 },
85
86 // Less widely used API changes:
87 // - drop maxTasks arg to taskqueue.QueueStats
88 {
89 Name: "ae.2",
90 In: `package foo
91
92 import (
93 "appengine"
94 "appengine/taskqueue"
95 )
96
97 func f(ctx appengine.Context) {
98 stats, err := taskqueue.QueueStats(ctx, []string{"one", "two"}, 0)
99 }
100 `,
101 Out: `package foo
102
103 import (
104 "golang.org/x/net/context"
105 "google.golang.org/appengine/v2/taskqueue"
106 )
107
108 func f(ctx context.Context) {
109 stats, err := taskqueue.QueueStats(ctx, []string{"one", "two"})
110 }
111 `,
112 },
113
114 // Check that the main "appengine" import will not be dropped
115 // if an appengine.Context -> context.Context change happens
116 // but the appengine package is still referenced.
117 {
118 Name: "ae.3",
119 In: `package foo
120
121 import (
122 "appengine"
123 "io"
124 )
125
126 func f(ctx appengine.Context, w io.Writer) {
127 _ = appengine.IsDevAppServer()
128 }
129 `,
130 Out: `package foo
131
132 import (
133 "golang.org/x/net/context"
134 "google.golang.org/appengine/v2"
135 "io"
136 )
137
138 func f(ctx context.Context, w io.Writer) {
139 _ = appengine.IsDevAppServer()
140 }
141 `,
142 },
143 }
0 // Copyright 2011 The Go Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package main
5
6 import (
7 "fmt"
8 "go/ast"
9 "go/parser"
10 "go/token"
11 "os"
12 "path"
13 "reflect"
14 "strconv"
15 "strings"
16 )
17
18 type fix struct {
19 name string
20 date string // date that fix was introduced, in YYYY-MM-DD format
21 f func(*ast.File) bool
22 desc string
23 }
24
25 // main runs sort.Sort(byName(fixes)) before printing list of fixes.
26 type byName []fix
27
28 func (f byName) Len() int { return len(f) }
29 func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
30 func (f byName) Less(i, j int) bool { return f[i].name < f[j].name }
31
32 // main runs sort.Sort(byDate(fixes)) before applying fixes.
33 type byDate []fix
34
35 func (f byDate) Len() int { return len(f) }
36 func (f byDate) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
37 func (f byDate) Less(i, j int) bool { return f[i].date < f[j].date }
38
39 var fixes []fix
40
41 func register(f fix) {
42 fixes = append(fixes, f)
43 }
44
45 // walk traverses the AST x, calling visit(y) for each node y in the tree but
46 // also with a pointer to each ast.Expr, ast.Stmt, and *ast.BlockStmt,
47 // in a bottom-up traversal.
48 func walk(x interface{}, visit func(interface{})) {
49 walkBeforeAfter(x, nop, visit)
50 }
51
52 func nop(interface{}) {}
53
54 // walkBeforeAfter is like walk but calls before(x) before traversing
55 // x's children and after(x) afterward.
56 func walkBeforeAfter(x interface{}, before, after func(interface{})) {
57 before(x)
58
59 switch n := x.(type) {
60 default:
61 panic(fmt.Errorf("unexpected type %T in walkBeforeAfter", x))
62
63 case nil:
64
65 // pointers to interfaces
66 case *ast.Decl:
67 walkBeforeAfter(*n, before, after)
68 case *ast.Expr:
69 walkBeforeAfter(*n, before, after)
70 case *ast.Spec:
71 walkBeforeAfter(*n, before, after)
72 case *ast.Stmt:
73 walkBeforeAfter(*n, before, after)
74
75 // pointers to struct pointers
76 case **ast.BlockStmt:
77 walkBeforeAfter(*n, before, after)
78 case **ast.CallExpr:
79 walkBeforeAfter(*n, before, after)
80 case **ast.FieldList:
81 walkBeforeAfter(*n, before, after)
82 case **ast.FuncType:
83 walkBeforeAfter(*n, before, after)
84 case **ast.Ident:
85 walkBeforeAfter(*n, before, after)
86 case **ast.BasicLit:
87 walkBeforeAfter(*n, before, after)
88
89 // pointers to slices
90 case *[]ast.Decl:
91 walkBeforeAfter(*n, before, after)
92 case *[]ast.Expr:
93 walkBeforeAfter(*n, before, after)
94 case *[]*ast.File:
95 walkBeforeAfter(*n, before, after)
96 case *[]*ast.Ident:
97 walkBeforeAfter(*n, before, after)
98 case *[]ast.Spec:
99 walkBeforeAfter(*n, before, after)
100 case *[]ast.Stmt:
101 walkBeforeAfter(*n, before, after)
102
103 // These are ordered and grouped to match ../../pkg/go/ast/ast.go
104 case *ast.Field:
105 walkBeforeAfter(&n.Names, before, after)
106 walkBeforeAfter(&n.Type, before, after)
107 walkBeforeAfter(&n.Tag, before, after)
108 case *ast.FieldList:
109 for _, field := range n.List {
110 walkBeforeAfter(field, before, after)
111 }
112 case *ast.BadExpr:
113 case *ast.Ident:
114 case *ast.Ellipsis:
115 walkBeforeAfter(&n.Elt, before, after)
116 case *ast.BasicLit:
117 case *ast.FuncLit:
118 walkBeforeAfter(&n.Type, before, after)
119 walkBeforeAfter(&n.Body, before, after)
120 case *ast.CompositeLit:
121 walkBeforeAfter(&n.Type, before, after)
122 walkBeforeAfter(&n.Elts, before, after)
123 case *ast.ParenExpr:
124 walkBeforeAfter(&n.X, before, after)
125 case *ast.SelectorExpr:
126 walkBeforeAfter(&n.X, before, after)
127 case *ast.IndexExpr:
128 walkBeforeAfter(&n.X, before, after)
129 walkBeforeAfter(&n.Index, before, after)
130 case *ast.SliceExpr:
131 walkBeforeAfter(&n.X, before, after)
132 if n.Low != nil {
133 walkBeforeAfter(&n.Low, before, after)
134 }
135 if n.High != nil {
136 walkBeforeAfter(&n.High, before, after)
137 }
138 case *ast.TypeAssertExpr:
139 walkBeforeAfter(&n.X, before, after)
140 walkBeforeAfter(&n.Type, before, after)
141 case *ast.CallExpr:
142 walkBeforeAfter(&n.Fun, before, after)
143 walkBeforeAfter(&n.Args, before, after)
144 case *ast.StarExpr:
145 walkBeforeAfter(&n.X, before, after)
146 case *ast.UnaryExpr:
147 walkBeforeAfter(&n.X, before, after)
148 case *ast.BinaryExpr:
149 walkBeforeAfter(&n.X, before, after)
150 walkBeforeAfter(&n.Y, before, after)
151 case *ast.KeyValueExpr:
152 walkBeforeAfter(&n.Key, before, after)
153 walkBeforeAfter(&n.Value, before, after)
154
155 case *ast.ArrayType:
156 walkBeforeAfter(&n.Len, before, after)
157 walkBeforeAfter(&n.Elt, before, after)
158 case *ast.StructType:
159 walkBeforeAfter(&n.Fields, before, after)
160 case *ast.FuncType:
161 walkBeforeAfter(&n.Params, before, after)
162 if n.Results != nil {
163 walkBeforeAfter(&n.Results, before, after)
164 }
165 case *ast.InterfaceType:
166 walkBeforeAfter(&n.Methods, before, after)
167 case *ast.MapType:
168 walkBeforeAfter(&n.Key, before, after)
169 walkBeforeAfter(&n.Value, before, after)
170 case *ast.ChanType:
171 walkBeforeAfter(&n.Value, before, after)
172
173 case *ast.BadStmt:
174 case *ast.DeclStmt:
175 walkBeforeAfter(&n.Decl, before, after)
176 case *ast.EmptyStmt:
177 case *ast.LabeledStmt:
178 walkBeforeAfter(&n.Stmt, before, after)
179 case *ast.ExprStmt:
180 walkBeforeAfter(&n.X, before, after)
181 case *ast.SendStmt:
182 walkBeforeAfter(&n.Chan, before, after)
183 walkBeforeAfter(&n.Value, before, after)
184 case *ast.IncDecStmt:
185 walkBeforeAfter(&n.X, before, after)
186 case *ast.AssignStmt:
187 walkBeforeAfter(&n.Lhs, before, after)
188 walkBeforeAfter(&n.Rhs, before, after)
189 case *ast.GoStmt:
190 walkBeforeAfter(&n.Call, before, after)
191 case *ast.DeferStmt:
192 walkBeforeAfter(&n.Call, before, after)
193 case *ast.ReturnStmt:
194 walkBeforeAfter(&n.Results, before, after)
195 case *ast.BranchStmt:
196 case *ast.BlockStmt:
197 walkBeforeAfter(&n.List, before, after)
198 case *ast.IfStmt:
199 walkBeforeAfter(&n.Init, before, after)
200 walkBeforeAfter(&n.Cond, before, after)
201 walkBeforeAfter(&n.Body, before, after)
202 walkBeforeAfter(&n.Else, before, after)
203 case *ast.CaseClause:
204 walkBeforeAfter(&n.List, before, after)
205 walkBeforeAfter(&n.Body, before, after)
206 case *ast.SwitchStmt:
207 walkBeforeAfter(&n.Init, before, after)
208 walkBeforeAfter(&n.Tag, before, after)
209 walkBeforeAfter(&n.Body, before, after)
210 case *ast.TypeSwitchStmt:
211 walkBeforeAfter(&n.Init, before, after)
212 walkBeforeAfter(&n.Assign, before, after)
213 walkBeforeAfter(&n.Body, before, after)
214 case *ast.CommClause:
215 walkBeforeAfter(&n.Comm, before, after)
216 walkBeforeAfter(&n.Body, before, after)
217 case *ast.SelectStmt:
218 walkBeforeAfter(&n.Body, before, after)
219 case *ast.ForStmt:
220 walkBeforeAfter(&n.Init, before, after)
221 walkBeforeAfter(&n.Cond, before, after)
222 walkBeforeAfter(&n.Post, before, after)
223 walkBeforeAfter(&n.Body, before, after)
224 case *ast.RangeStmt:
225 walkBeforeAfter(&n.Key, before, after)
226 walkBeforeAfter(&n.Value, before, after)
227 walkBeforeAfter(&n.X, before, after)
228 walkBeforeAfter(&n.Body, before, after)
229
230 case *ast.ImportSpec:
231 case *ast.ValueSpec:
232 walkBeforeAfter(&n.Type, before, after)
233 walkBeforeAfter(&n.Values, before, after)
234 walkBeforeAfter(&n.Names, before, after)
235 case *ast.TypeSpec:
236 walkBeforeAfter(&n.Type, before, after)
237
238 case *ast.BadDecl:
239 case *ast.GenDecl:
240 walkBeforeAfter(&n.Specs, before, after)
241 case *ast.FuncDecl:
242 if n.Recv != nil {
243 walkBeforeAfter(&n.Recv, before, after)
244 }
245 walkBeforeAfter(&n.Type, before, after)
246 if n.Body != nil {
247 walkBeforeAfter(&n.Body, before, after)
248 }
249
250 case *ast.File:
251 walkBeforeAfter(&n.Decls, before, after)
252
253 case *ast.Package:
254 walkBeforeAfter(&n.Files, before, after)
255
256 case []*ast.File:
257 for i := range n {
258 walkBeforeAfter(&n[i], before, after)
259 }
260 case []ast.Decl:
261 for i := range n {
262 walkBeforeAfter(&n[i], before, after)
263 }
264 case []ast.Expr:
265 for i := range n {
266 walkBeforeAfter(&n[i], before, after)
267 }
268 case []*ast.Ident:
269 for i := range n {
270 walkBeforeAfter(&n[i], before, after)
271 }
272 case []ast.Stmt:
273 for i := range n {
274 walkBeforeAfter(&n[i], before, after)
275 }
276 case []ast.Spec:
277 for i := range n {
278 walkBeforeAfter(&n[i], before, after)
279 }
280 }
281 after(x)
282 }
283
284 // imports returns true if f imports path.
285 func imports(f *ast.File, path string) bool {
286 return importSpec(f, path) != nil
287 }
288
289 // importSpec returns the import spec if f imports path,
290 // or nil otherwise.
291 func importSpec(f *ast.File, path string) *ast.ImportSpec {
292 for _, s := range f.Imports {
293 if importPath(s) == path {
294 return s
295 }
296 }
297 return nil
298 }
299
300 // importPath returns the unquoted import path of s,
301 // or "" if the path is not properly quoted.
302 func importPath(s *ast.ImportSpec) string {
303 t, err := strconv.Unquote(s.Path.Value)
304 if err == nil {
305 return t
306 }
307 return ""
308 }
309
310 // declImports reports whether gen contains an import of path.
311 func declImports(gen *ast.GenDecl, path string) bool {
312 if gen.Tok != token.IMPORT {
313 return false
314 }
315 for _, spec := range gen.Specs {
316 impspec := spec.(*ast.ImportSpec)
317 if importPath(impspec) == path {
318 return true
319 }
320 }
321 return false
322 }
323
324 // isPkgDot returns true if t is the expression "pkg.name"
325 // where pkg is an imported identifier.
326 func isPkgDot(t ast.Expr, pkg, name string) bool {
327 sel, ok := t.(*ast.SelectorExpr)
328 return ok && isTopName(sel.X, pkg) && sel.Sel.String() == name
329 }
330
331 // isPtrPkgDot returns true if f is the expression "*pkg.name"
332 // where pkg is an imported identifier.
333 func isPtrPkgDot(t ast.Expr, pkg, name string) bool {
334 ptr, ok := t.(*ast.StarExpr)
335 return ok && isPkgDot(ptr.X, pkg, name)
336 }
337
338 // isTopName returns true if n is a top-level unresolved identifier with the given name.
339 func isTopName(n ast.Expr, name string) bool {
340 id, ok := n.(*ast.Ident)
341 return ok && id.Name == name && id.Obj == nil
342 }
343
344 // isName returns true if n is an identifier with the given name.
345 func isName(n ast.Expr, name string) bool {
346 id, ok := n.(*ast.Ident)
347 return ok && id.String() == name
348 }
349
350 // isCall returns true if t is a call to pkg.name.
351 func isCall(t ast.Expr, pkg, name string) bool {
352 call, ok := t.(*ast.CallExpr)
353 return ok && isPkgDot(call.Fun, pkg, name)
354 }
355
356 // If n is an *ast.Ident, isIdent returns it; otherwise isIdent returns nil.
357 func isIdent(n interface{}) *ast.Ident {
358 id, _ := n.(*ast.Ident)
359 return id
360 }
361
362 // refersTo returns true if n is a reference to the same object as x.
363 func refersTo(n ast.Node, x *ast.Ident) bool {
364 id, ok := n.(*ast.Ident)
365 // The test of id.Name == x.Name handles top-level unresolved
366 // identifiers, which all have Obj == nil.
367 return ok && id.Obj == x.Obj && id.Name == x.Name
368 }
369
370 // isBlank returns true if n is the blank identifier.
371 func isBlank(n ast.Expr) bool {
372 return isName(n, "_")
373 }
374
375 // isEmptyString returns true if n is an empty string literal.
376 func isEmptyString(n ast.Expr) bool {
377 lit, ok := n.(*ast.BasicLit)
378 return ok && lit.Kind == token.STRING && len(lit.Value) == 2
379 }
380
381 func warn(pos token.Pos, msg string, args ...interface{}) {
382 if pos.IsValid() {
383 msg = "%s: " + msg
384 arg1 := []interface{}{fset.Position(pos).String()}
385 args = append(arg1, args...)
386 }
387 fmt.Fprintf(os.Stderr, msg+"\n", args...)
388 }
389
390 // countUses returns the number of uses of the identifier x in scope.
391 func countUses(x *ast.Ident, scope []ast.Stmt) int {
392 count := 0
393 ff := func(n interface{}) {
394 if n, ok := n.(ast.Node); ok && refersTo(n, x) {
395 count++
396 }
397 }
398 for _, n := range scope {
399 walk(n, ff)
400 }
401 return count
402 }
403
404 // rewriteUses replaces all uses of the identifier x and !x in scope
405 // with f(x.Pos()) and fnot(x.Pos()).
406 func rewriteUses(x *ast.Ident, f, fnot func(token.Pos) ast.Expr, scope []ast.Stmt) {
407 var lastF ast.Expr
408 ff := func(n interface{}) {
409 ptr, ok := n.(*ast.Expr)
410 if !ok {
411 return
412 }
413 nn := *ptr
414
415 // The child node was just walked and possibly replaced.
416 // If it was replaced and this is a negation, replace with fnot(p).
417 not, ok := nn.(*ast.UnaryExpr)
418 if ok && not.Op == token.NOT && not.X == lastF {
419 *ptr = fnot(nn.Pos())
420 return
421 }
422 if refersTo(nn, x) {
423 lastF = f(nn.Pos())
424 *ptr = lastF
425 }
426 }
427 for _, n := range scope {
428 walk(n, ff)
429 }
430 }
431
432 // assignsTo returns true if any of the code in scope assigns to or takes the address of x.
433 func assignsTo(x *ast.Ident, scope []ast.Stmt) bool {
434 assigned := false
435 ff := func(n interface{}) {
436 if assigned {
437 return
438 }
439 switch n := n.(type) {
440 case *ast.UnaryExpr:
441 // use of &x
442 if n.Op == token.AND && refersTo(n.X, x) {
443 assigned = true
444 return
445 }
446 case *ast.AssignStmt:
447 for _, l := range n.Lhs {
448 if refersTo(l, x) {
449 assigned = true
450 return
451 }
452 }
453 }
454 }
455 for _, n := range scope {
456 if assigned {
457 break
458 }
459 walk(n, ff)
460 }
461 return assigned
462 }
463
464 // newPkgDot returns an ast.Expr referring to "pkg.name" at position pos.
465 func newPkgDot(pos token.Pos, pkg, name string) ast.Expr {
466 return &ast.SelectorExpr{
467 X: &ast.Ident{
468 NamePos: pos,
469 Name: pkg,
470 },
471 Sel: &ast.Ident{
472 NamePos: pos,
473 Name: name,
474 },
475 }
476 }
477
478 // renameTop renames all references to the top-level name old.
479 // It returns true if it makes any changes.
480 func renameTop(f *ast.File, old, new string) bool {
481 var fixed bool
482
483 // Rename any conflicting imports
484 // (assuming package name is last element of path).
485 for _, s := range f.Imports {
486 if s.Name != nil {
487 if s.Name.Name == old {
488 s.Name.Name = new
489 fixed = true
490 }
491 } else {
492 _, thisName := path.Split(importPath(s))
493 if thisName == old {
494 s.Name = ast.NewIdent(new)
495 fixed = true
496 }
497 }
498 }
499
500 // Rename any top-level declarations.
501 for _, d := range f.Decls {
502 switch d := d.(type) {
503 case *ast.FuncDecl:
504 if d.Recv == nil && d.Name.Name == old {
505 d.Name.Name = new
506 d.Name.Obj.Name = new
507 fixed = true
508 }
509 case *ast.GenDecl:
510 for _, s := range d.Specs {
511 switch s := s.(type) {
512 case *ast.TypeSpec:
513 if s.Name.Name == old {
514 s.Name.Name = new
515 s.Name.Obj.Name = new
516 fixed = true
517 }
518 case *ast.ValueSpec:
519 for _, n := range s.Names {
520 if n.Name == old {
521 n.Name = new
522 n.Obj.Name = new
523 fixed = true
524 }
525 }
526 }
527 }
528 }
529 }
530
531 // Rename top-level old to new, both unresolved names
532 // (probably defined in another file) and names that resolve
533 // to a declaration we renamed.
534 walk(f, func(n interface{}) {
535 id, ok := n.(*ast.Ident)
536 if ok && isTopName(id, old) {
537 id.Name = new
538 fixed = true
539 }
540 if ok && id.Obj != nil && id.Name == old && id.Obj.Name == new {
541 id.Name = id.Obj.Name
542 fixed = true
543 }
544 })
545
546 return fixed
547 }
548
549 // matchLen returns the length of the longest prefix shared by x and y.
550 func matchLen(x, y string) int {
551 i := 0
552 for i < len(x) && i < len(y) && x[i] == y[i] {
553 i++
554 }
555 return i
556 }
557
558 // addImport adds the import path to the file f, if absent.
559 func addImport(f *ast.File, ipath string) (added bool) {
560 if imports(f, ipath) {
561 return false
562 }
563
564 // Determine name of import.
565 // Assume added imports follow convention of using last element.
566 _, name := path.Split(ipath)
567
568 // Rename any conflicting top-level references from name to name_.
569 renameTop(f, name, name+"_")
570
571 newImport := &ast.ImportSpec{
572 Path: &ast.BasicLit{
573 Kind: token.STRING,
574 Value: strconv.Quote(ipath),
575 },
576 }
577
578 // Find an import decl to add to.
579 var (
580 bestMatch = -1
581 lastImport = -1
582 impDecl *ast.GenDecl
583 impIndex = -1
584 )
585 for i, decl := range f.Decls {
586 gen, ok := decl.(*ast.GenDecl)
587 if ok && gen.Tok == token.IMPORT {
588 lastImport = i
589 // Do not add to import "C", to avoid disrupting the
590 // association with its doc comment, breaking cgo.
591 if declImports(gen, "C") {
592 continue
593 }
594
595 // Compute longest shared prefix with imports in this block.
596 for j, spec := range gen.Specs {
597 impspec := spec.(*ast.ImportSpec)
598 n := matchLen(importPath(impspec), ipath)
599 if n > bestMatch {
600 bestMatch = n
601 impDecl = gen
602 impIndex = j
603 }
604 }
605 }
606 }
607
608 // If no import decl found, add one after the last import.
609 if impDecl == nil {
610 impDecl = &ast.GenDecl{
611 Tok: token.IMPORT,
612 }
613 f.Decls = append(f.Decls, nil)
614 copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
615 f.Decls[lastImport+1] = impDecl
616 }
617
618 // Ensure the import decl has parentheses, if needed.
619 if len(impDecl.Specs) > 0 && !impDecl.Lparen.IsValid() {
620 impDecl.Lparen = impDecl.Pos()
621 }
622
623 insertAt := impIndex + 1
624 if insertAt == 0 {
625 insertAt = len(impDecl.Specs)
626 }
627 impDecl.Specs = append(impDecl.Specs, nil)
628 copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
629 impDecl.Specs[insertAt] = newImport
630 if insertAt > 0 {
631 // Assign same position as the previous import,
632 // so that the sorter sees it as being in the same block.
633 prev := impDecl.Specs[insertAt-1]
634 newImport.Path.ValuePos = prev.Pos()
635 newImport.EndPos = prev.Pos()
636 }
637
638 f.Imports = append(f.Imports, newImport)
639 return true
640 }
641
642 // deleteImport deletes the import path from the file f, if present.
643 func deleteImport(f *ast.File, path string) (deleted bool) {
644 oldImport := importSpec(f, path)
645
646 // Find the import node that imports path, if any.
647 for i, decl := range f.Decls {
648 gen, ok := decl.(*ast.GenDecl)
649 if !ok || gen.Tok != token.IMPORT {
650 continue
651 }
652 for j, spec := range gen.Specs {
653 impspec := spec.(*ast.ImportSpec)
654 if oldImport != impspec {
655 continue
656 }
657
658 // We found an import spec that imports path.
659 // Delete it.
660 deleted = true
661 copy(gen.Specs[j:], gen.Specs[j+1:])
662 gen.Specs = gen.Specs[:len(gen.Specs)-1]
663
664 // If this was the last import spec in this decl,
665 // delete the decl, too.
666 if len(gen.Specs) == 0 {
667 copy(f.Decls[i:], f.Decls[i+1:])
668 f.Decls = f.Decls[:len(f.Decls)-1]
669 } else if len(gen.Specs) == 1 {
670 gen.Lparen = token.NoPos // drop parens
671 }
672 if j > 0 {
673 // We deleted an entry but now there will be
674 // a blank line-sized hole where the import was.
675 // Close the hole by making the previous
676 // import appear to "end" where this one did.
677 gen.Specs[j-1].(*ast.ImportSpec).EndPos = impspec.End()
678 }
679 break
680 }
681 }
682
683 // Delete it from f.Imports.
684 for i, imp := range f.Imports {
685 if imp == oldImport {
686 copy(f.Imports[i:], f.Imports[i+1:])
687 f.Imports = f.Imports[:len(f.Imports)-1]
688 break
689 }
690 }
691
692 return
693 }
694
695 // rewriteImport rewrites any import of path oldPath to path newPath.
696 func rewriteImport(f *ast.File, oldPath, newPath string) (rewrote bool) {
697 for _, imp := range f.Imports {
698 if importPath(imp) == oldPath {
699 rewrote = true
700 // record old End, because the default is to compute
701 // it using the length of imp.Path.Value.
702 imp.EndPos = imp.End()
703 imp.Path.Value = strconv.Quote(newPath)
704 }
705 }
706 return
707 }
708
709 func usesImport(f *ast.File, path string) (used bool) {
710 spec := importSpec(f, path)
711 if spec == nil {
712 return
713 }
714
715 name := spec.Name.String()
716 switch name {
717 case "<nil>":
718 // If the package name is not explicitly specified,
719 // make an educated guess. This is not guaranteed to be correct.
720 if strings.HasSuffix(path, "/v2") {
721 path = strings.TrimRight(path, "/v2")
722 }
723 lastSlash := strings.LastIndex(path, "/")
724 if lastSlash == -1 {
725 name = path
726 } else {
727 name = path[lastSlash+1:]
728 }
729 case "_", ".":
730 // Not sure if this import is used - err on the side of caution.
731 return true
732 }
733
734 walk(f, func(n interface{}) {
735 sel, ok := n.(*ast.SelectorExpr)
736 if ok && isTopName(sel.X, name) {
737 used = true
738 }
739 })
740
741 return
742 }
743
744 func expr(s string) ast.Expr {
745 x, err := parser.ParseExpr(s)
746 if err != nil {
747 panic("parsing " + s + ": " + err.Error())
748 }
749 // Remove position information to avoid spurious newlines.
750 killPos(reflect.ValueOf(x))
751 return x
752 }
753
754 var posType = reflect.TypeOf(token.Pos(0))
755
756 func killPos(v reflect.Value) {
757 switch v.Kind() {
758 case reflect.Ptr, reflect.Interface:
759 if !v.IsNil() {
760 killPos(v.Elem())
761 }
762 case reflect.Slice:
763 n := v.Len()
764 for i := 0; i < n; i++ {
765 killPos(v.Index(i))
766 }
767 case reflect.Struct:
768 n := v.NumField()
769 for i := 0; i < n; i++ {
770 f := v.Field(i)
771 if f.Type() == posType {
772 f.SetInt(0)
773 continue
774 }
775 killPos(f)
776 }
777 }
778 }
779
780 // A Rename describes a single renaming.
781 type rename struct {
782 OldImport string // only apply rename if this import is present
783 NewImport string // add this import during rewrite
784 Old string // old name: p.T or *p.T
785 New string // new name: p.T or *p.T
786 }
787
788 func renameFix(tab []rename) func(*ast.File) bool {
789 return func(f *ast.File) bool {
790 return renameFixTab(f, tab)
791 }
792 }
793
794 func parseName(s string) (ptr bool, pkg, nam string) {
795 i := strings.Index(s, ".")
796 if i < 0 {
797 panic("parseName: invalid name " + s)
798 }
799 if strings.HasPrefix(s, "*") {
800 ptr = true
801 s = s[1:]
802 i--
803 }
804 pkg = s[:i]
805 nam = s[i+1:]
806 return
807 }
808
809 func renameFixTab(f *ast.File, tab []rename) bool {
810 fixed := false
811 added := map[string]bool{}
812 check := map[string]bool{}
813 for _, t := range tab {
814 if !imports(f, t.OldImport) {
815 continue
816 }
817 optr, opkg, onam := parseName(t.Old)
818 walk(f, func(n interface{}) {
819 np, ok := n.(*ast.Expr)
820 if !ok {
821 return
822 }
823 x := *np
824 if optr {
825 p, ok := x.(*ast.StarExpr)
826 if !ok {
827 return
828 }
829 x = p.X
830 }
831 if !isPkgDot(x, opkg, onam) {
832 return
833 }
834 if t.NewImport != "" && !added[t.NewImport] {
835 addImport(f, t.NewImport)
836 added[t.NewImport] = true
837 }
838 *np = expr(t.New)
839 check[t.OldImport] = true
840 fixed = true
841 })
842 }
843
844 for ipath := range check {
845 if !usesImport(f, ipath) {
846 deleteImport(f, ipath)
847 }
848 }
849 return fixed
850 }
0 // Copyright 2011 The Go Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package main
5
6 import (
7 "bytes"
8 "flag"
9 "fmt"
10 "go/ast"
11 "go/format"
12 "go/parser"
13 "go/scanner"
14 "go/token"
15 "io/ioutil"
16 "os"
17 "os/exec"
18 "path/filepath"
19 "sort"
20 "strings"
21 )
22
23 var (
24 fset = token.NewFileSet()
25 exitCode = 0
26 )
27
28 var allowedRewrites = flag.String("r", "",
29 "restrict the rewrites to this comma-separated list")
30
31 var forceRewrites = flag.String("force", "",
32 "force these fixes to run even if the code looks updated")
33
34 var allowed, force map[string]bool
35
36 var doDiff = flag.Bool("diff", false, "display diffs instead of rewriting files")
37
38 // enable for debugging fix failures
39 const debug = false // display incorrectly reformatted source and exit
40
41 func usage() {
42 fmt.Fprintf(os.Stderr, "usage: aefix [-diff] [-r fixname,...] [-force fixname,...] [path ...]\n")
43 flag.PrintDefaults()
44 fmt.Fprintf(os.Stderr, "\nAvailable rewrites are:\n")
45 sort.Sort(byName(fixes))
46 for _, f := range fixes {
47 fmt.Fprintf(os.Stderr, "\n%s\n", f.name)
48 desc := strings.TrimSpace(f.desc)
49 desc = strings.Replace(desc, "\n", "\n\t", -1)
50 fmt.Fprintf(os.Stderr, "\t%s\n", desc)
51 }
52 os.Exit(2)
53 }
54
55 func main() {
56 flag.Usage = usage
57 flag.Parse()
58
59 sort.Sort(byDate(fixes))
60
61 if *allowedRewrites != "" {
62 allowed = make(map[string]bool)
63 for _, f := range strings.Split(*allowedRewrites, ",") {
64 allowed[f] = true
65 }
66 }
67
68 if *forceRewrites != "" {
69 force = make(map[string]bool)
70 for _, f := range strings.Split(*forceRewrites, ",") {
71 force[f] = true
72 }
73 }
74
75 if flag.NArg() == 0 {
76 if err := processFile("standard input", true); err != nil {
77 report(err)
78 }
79 os.Exit(exitCode)
80 }
81
82 for i := 0; i < flag.NArg(); i++ {
83 path := flag.Arg(i)
84 switch dir, err := os.Stat(path); {
85 case err != nil:
86 report(err)
87 case dir.IsDir():
88 walkDir(path)
89 default:
90 if err := processFile(path, false); err != nil {
91 report(err)
92 }
93 }
94 }
95
96 os.Exit(exitCode)
97 }
98
99 const parserMode = parser.ParseComments
100
101 func gofmtFile(f *ast.File) ([]byte, error) {
102 var buf bytes.Buffer
103 if err := format.Node(&buf, fset, f); err != nil {
104 return nil, err
105 }
106 return buf.Bytes(), nil
107 }
108
109 func processFile(filename string, useStdin bool) error {
110 var f *os.File
111 var err error
112 var fixlog bytes.Buffer
113
114 if useStdin {
115 f = os.Stdin
116 } else {
117 f, err = os.Open(filename)
118 if err != nil {
119 return err
120 }
121 defer f.Close()
122 }
123
124 src, err := ioutil.ReadAll(f)
125 if err != nil {
126 return err
127 }
128
129 file, err := parser.ParseFile(fset, filename, src, parserMode)
130 if err != nil {
131 return err
132 }
133
134 // Apply all fixes to file.
135 newFile := file
136 fixed := false
137 for _, fix := range fixes {
138 if allowed != nil && !allowed[fix.name] {
139 continue
140 }
141 if fix.f(newFile) {
142 fixed = true
143 fmt.Fprintf(&fixlog, " %s", fix.name)
144
145 // AST changed.
146 // Print and parse, to update any missing scoping
147 // or position information for subsequent fixers.
148 newSrc, err := gofmtFile(newFile)
149 if err != nil {
150 return err
151 }
152 newFile, err = parser.ParseFile(fset, filename, newSrc, parserMode)
153 if err != nil {
154 if debug {
155 fmt.Printf("%s", newSrc)
156 report(err)
157 os.Exit(exitCode)
158 }
159 return err
160 }
161 }
162 }
163 if !fixed {
164 return nil
165 }
166 fmt.Fprintf(os.Stderr, "%s: fixed %s\n", filename, fixlog.String()[1:])
167
168 // Print AST. We did that after each fix, so this appears
169 // redundant, but it is necessary to generate gofmt-compatible
170 // source code in a few cases. The official gofmt style is the
171 // output of the printer run on a standard AST generated by the parser,
172 // but the source we generated inside the loop above is the
173 // output of the printer run on a mangled AST generated by a fixer.
174 newSrc, err := gofmtFile(newFile)
175 if err != nil {
176 return err
177 }
178
179 if *doDiff {
180 data, err := diff(src, newSrc)
181 if err != nil {
182 return fmt.Errorf("computing diff: %s", err)
183 }
184 fmt.Printf("diff %s fixed/%s\n", filename, filename)
185 os.Stdout.Write(data)
186 return nil
187 }
188
189 if useStdin {
190 os.Stdout.Write(newSrc)
191 return nil
192 }
193
194 return ioutil.WriteFile(f.Name(), newSrc, 0)
195 }
196
197 var gofmtBuf bytes.Buffer
198
199 func gofmt(n interface{}) string {
200 gofmtBuf.Reset()
201 if err := format.Node(&gofmtBuf, fset, n); err != nil {
202 return "<" + err.Error() + ">"
203 }
204 return gofmtBuf.String()
205 }
206
207 func report(err error) {
208 scanner.PrintError(os.Stderr, err)
209 exitCode = 2
210 }
211
212 func walkDir(path string) {
213 filepath.Walk(path, visitFile)
214 }
215
216 func visitFile(path string, f os.FileInfo, err error) error {
217 if err == nil && isGoFile(f) {
218 err = processFile(path, false)
219 }
220 if err != nil {
221 report(err)
222 }
223 return nil
224 }
225
226 func isGoFile(f os.FileInfo) bool {
227 // ignore non-Go files
228 name := f.Name()
229 return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
230 }
231
232 func diff(b1, b2 []byte) (data []byte, err error) {
233 f1, err := ioutil.TempFile("", "go-fix")
234 if err != nil {
235 return nil, err
236 }
237 defer os.Remove(f1.Name())
238 defer f1.Close()
239
240 f2, err := ioutil.TempFile("", "go-fix")
241 if err != nil {
242 return nil, err
243 }
244 defer os.Remove(f2.Name())
245 defer f2.Close()
246
247 f1.Write(b1)
248 f2.Write(b2)
249
250 data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
251 if len(data) > 0 {
252 // diff exits with a non-zero status when the files don't match.
253 // Ignore that failure as long as we get output.
254 err = nil
255 }
256 return
257 }
0 // Copyright 2011 The Go Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package main
5
6 import (
7 "go/ast"
8 "go/parser"
9 "strings"
10 "testing"
11 )
12
13 type testCase struct {
14 Name string
15 Fn func(*ast.File) bool
16 In string
17 Out string
18 }
19
20 var testCases []testCase
21
22 func addTestCases(t []testCase, fn func(*ast.File) bool) {
23 // Fill in fn to avoid repetition in definitions.
24 if fn != nil {
25 for i := range t {
26 if t[i].Fn == nil {
27 t[i].Fn = fn
28 }
29 }
30 }
31 testCases = append(testCases, t...)
32 }
33
34 func fnop(*ast.File) bool { return false }
35
36 func parseFixPrint(t *testing.T, fn func(*ast.File) bool, desc, in string, mustBeGofmt bool) (out string, fixed, ok bool) {
37 file, err := parser.ParseFile(fset, desc, in, parserMode)
38 if err != nil {
39 t.Errorf("%s: parsing: %v", desc, err)
40 return
41 }
42
43 outb, err := gofmtFile(file)
44 if err != nil {
45 t.Errorf("%s: printing: %v", desc, err)
46 return
47 }
48 if s := string(outb); in != s && mustBeGofmt {
49 t.Errorf("%s: not gofmt-formatted.\n--- %s\n%s\n--- %s | gofmt\n%s",
50 desc, desc, in, desc, s)
51 tdiff(t, in, s)
52 return
53 }
54
55 if fn == nil {
56 for _, fix := range fixes {
57 if fix.f(file) {
58 fixed = true
59 }
60 }
61 } else {
62 fixed = fn(file)
63 }
64
65 outb, err = gofmtFile(file)
66 if err != nil {
67 t.Errorf("%s: printing: %v", desc, err)
68 return
69 }
70
71 return string(outb), fixed, true
72 }
73
74 func TestRewrite(t *testing.T) {
75 for _, tt := range testCases {
76 // Apply fix: should get tt.Out.
77 out, fixed, ok := parseFixPrint(t, tt.Fn, tt.Name, tt.In, true)
78 if !ok {
79 continue
80 }
81
82 // reformat to get printing right
83 out, _, ok = parseFixPrint(t, fnop, tt.Name, out, false)
84 if !ok {
85 continue
86 }
87
88 if out != tt.Out {
89 t.Errorf("%s: incorrect output.\n", tt.Name)
90 if !strings.HasPrefix(tt.Name, "testdata/") {
91 t.Errorf("--- have\n%s\n--- want\n%s", out, tt.Out)
92 }
93 tdiff(t, out, tt.Out)
94 continue
95 }
96
97 if changed := out != tt.In; changed != fixed {
98 t.Errorf("%s: changed=%v != fixed=%v", tt.Name, changed, fixed)
99 continue
100 }
101
102 // Should not change if run again.
103 out2, fixed2, ok := parseFixPrint(t, tt.Fn, tt.Name+" output", out, true)
104 if !ok {
105 continue
106 }
107
108 if fixed2 {
109 t.Errorf("%s: applied fixes during second round", tt.Name)
110 continue
111 }
112
113 if out2 != out {
114 t.Errorf("%s: changed output after second round of fixes.\n--- output after first round\n%s\n--- output after second round\n%s",
115 tt.Name, out, out2)
116 tdiff(t, out, out2)
117 }
118 }
119 }
120
121 func tdiff(t *testing.T, a, b string) {
122 data, err := diff([]byte(a), []byte(b))
123 if err != nil {
124 t.Error(err)
125 return
126 }
127 t.Error(string(data))
128 }
0 // Copyright 2011 The Go Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package main
5
6 import (
7 "fmt"
8 "go/ast"
9 "go/token"
10 "os"
11 "reflect"
12 "strings"
13 )
14
15 // Partial type checker.
16 //
17 // The fact that it is partial is very important: the input is
18 // an AST and a description of some type information to
19 // assume about one or more packages, but not all the
20 // packages that the program imports. The checker is
21 // expected to do as much as it can with what it has been
22 // given. There is not enough information supplied to do
23 // a full type check, but the type checker is expected to
24 // apply information that can be derived from variable
25 // declarations, function and method returns, and type switches
26 // as far as it can, so that the caller can still tell the types
27 // of expression relevant to a particular fix.
28 //
29 // TODO(rsc,gri): Replace with go/typechecker.
30 // Doing that could be an interesting test case for go/typechecker:
31 // the constraints about working with partial information will
32 // likely exercise it in interesting ways. The ideal interface would
33 // be to pass typecheck a map from importpath to package API text
34 // (Go source code), but for now we use data structures (TypeConfig, Type).
35 //
36 // The strings mostly use gofmt form.
37 //
38 // A Field or FieldList has as its type a comma-separated list
39 // of the types of the fields. For example, the field list
40 // x, y, z int
41 // has type "int, int, int".
42
43 // The prefix "type " is the type of a type.
44 // For example, given
45 // var x int
46 // type T int
47 // x's type is "int" but T's type is "type int".
48 // mkType inserts the "type " prefix.
49 // getType removes it.
50 // isType tests for it.
51
52 func mkType(t string) string {
53 return "type " + t
54 }
55
56 func getType(t string) string {
57 if !isType(t) {
58 return ""
59 }
60 return t[len("type "):]
61 }
62
63 func isType(t string) bool {
64 return strings.HasPrefix(t, "type ")
65 }
66
67 // TypeConfig describes the universe of relevant types.
68 // For ease of creation, the types are all referred to by string
69 // name (e.g., "reflect.Value"). TypeByName is the only place
70 // where the strings are resolved.
71
72 type TypeConfig struct {
73 Type map[string]*Type
74 Var map[string]string
75 Func map[string]string
76 }
77
78 // typeof returns the type of the given name, which may be of
79 // the form "x" or "p.X".
80 func (cfg *TypeConfig) typeof(name string) string {
81 if cfg.Var != nil {
82 if t := cfg.Var[name]; t != "" {
83 return t
84 }
85 }
86 if cfg.Func != nil {
87 if t := cfg.Func[name]; t != "" {
88 return "func()" + t
89 }
90 }
91 return ""
92 }
93
94 // Type describes the Fields and Methods of a type.
95 // If the field or method cannot be found there, it is next
96 // looked for in the Embed list.
97 type Type struct {
98 Field map[string]string // map field name to type
99 Method map[string]string // map method name to comma-separated return types (should start with "func ")
100 Embed []string // list of types this type embeds (for extra methods)
101 Def string // definition of named type
102 }
103
104 // dot returns the type of "typ.name", making its decision
105 // using the type information in cfg.
106 func (typ *Type) dot(cfg *TypeConfig, name string) string {
107 if typ.Field != nil {
108 if t := typ.Field[name]; t != "" {
109 return t
110 }
111 }
112 if typ.Method != nil {
113 if t := typ.Method[name]; t != "" {
114 return t
115 }
116 }
117
118 for _, e := range typ.Embed {
119 etyp := cfg.Type[e]
120 if etyp != nil {
121 if t := etyp.dot(cfg, name); t != "" {
122 return t
123 }
124 }
125 }
126
127 return ""
128 }
129
130 // typecheck type checks the AST f assuming the information in cfg.
131 // It returns two maps with type information:
132 // typeof maps AST nodes to type information in gofmt string form.
133 // assign maps type strings to lists of expressions that were assigned
134 // to values of another type that were assigned to that type.
135 func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, assign map[string][]interface{}) {
136 typeof = make(map[interface{}]string)
137 assign = make(map[string][]interface{})
138 cfg1 := &TypeConfig{}
139 *cfg1 = *cfg // make copy so we can add locally
140 copied := false
141
142 // gather function declarations
143 for _, decl := range f.Decls {
144 fn, ok := decl.(*ast.FuncDecl)
145 if !ok {
146 continue
147 }
148 typecheck1(cfg, fn.Type, typeof, assign)
149 t := typeof[fn.Type]
150 if fn.Recv != nil {
151 // The receiver must be a type.
152 rcvr := typeof[fn.Recv]
153 if !isType(rcvr) {
154 if len(fn.Recv.List) != 1 {
155 continue
156 }
157 rcvr = mkType(gofmt(fn.Recv.List[0].Type))
158 typeof[fn.Recv.List[0].Type] = rcvr
159 }
160 rcvr = getType(rcvr)
161 if rcvr != "" && rcvr[0] == '*' {
162 rcvr = rcvr[1:]
163 }
164 typeof[rcvr+"."+fn.Name.Name] = t
165 } else {
166 if isType(t) {
167 t = getType(t)
168 } else {
169 t = gofmt(fn.Type)
170 }
171 typeof[fn.Name] = t
172
173 // Record typeof[fn.Name.Obj] for future references to fn.Name.
174 typeof[fn.Name.Obj] = t
175 }
176 }
177
178 // gather struct declarations
179 for _, decl := range f.Decls {
180 d, ok := decl.(*ast.GenDecl)
181 if ok {
182 for _, s := range d.Specs {
183 switch s := s.(type) {
184 case *ast.TypeSpec:
185 if cfg1.Type[s.Name.Name] != nil {
186 break
187 }
188 if !copied {
189 copied = true
190 // Copy map lazily: it's time.
191 cfg1.Type = make(map[string]*Type)
192 for k, v := range cfg.Type {
193 cfg1.Type[k] = v
194 }
195 }
196 t := &Type{Field: map[string]string{}}
197 cfg1.Type[s.Name.Name] = t
198 switch st := s.Type.(type) {
199 case *ast.StructType:
200 for _, f := range st.Fields.List {
201 for _, n := range f.Names {
202 t.Field[n.Name] = gofmt(f.Type)
203 }
204 }
205 case *ast.ArrayType, *ast.StarExpr, *ast.MapType:
206 t.Def = gofmt(st)
207 }
208 }
209 }
210 }
211 }
212
213 typecheck1(cfg1, f, typeof, assign)
214 return typeof, assign
215 }
216
217 func makeExprList(a []*ast.Ident) []ast.Expr {
218 var b []ast.Expr
219 for _, x := range a {
220 b = append(b, x)
221 }
222 return b
223 }
224
225 // Typecheck1 is the recursive form of typecheck.
226 // It is like typecheck but adds to the information in typeof
227 // instead of allocating a new map.
228 func typecheck1(cfg *TypeConfig, f interface{}, typeof map[interface{}]string, assign map[string][]interface{}) {
229 // set sets the type of n to typ.
230 // If isDecl is true, n is being declared.
231 set := func(n ast.Expr, typ string, isDecl bool) {
232 if typeof[n] != "" || typ == "" {
233 if typeof[n] != typ {
234 assign[typ] = append(assign[typ], n)
235 }
236 return
237 }
238 typeof[n] = typ
239
240 // If we obtained typ from the declaration of x
241 // propagate the type to all the uses.
242 // The !isDecl case is a cheat here, but it makes
243 // up in some cases for not paying attention to
244 // struct fields. The real type checker will be
245 // more accurate so we won't need the cheat.
246 if id, ok := n.(*ast.Ident); ok && id.Obj != nil && (isDecl || typeof[id.Obj] == "") {
247 typeof[id.Obj] = typ
248 }
249 }
250
251 // Type-check an assignment lhs = rhs.
252 // If isDecl is true, this is := so we can update
253 // the types of the objects that lhs refers to.
254 typecheckAssign := func(lhs, rhs []ast.Expr, isDecl bool) {
255 if len(lhs) > 1 && len(rhs) == 1 {
256 if _, ok := rhs[0].(*ast.CallExpr); ok {
257 t := split(typeof[rhs[0]])
258 // Lists should have same length but may not; pair what can be paired.
259 for i := 0; i < len(lhs) && i < len(t); i++ {
260 set(lhs[i], t[i], isDecl)
261 }
262 return
263 }
264 }
265 if len(lhs) == 1 && len(rhs) == 2 {
266 // x = y, ok
267 rhs = rhs[:1]
268 } else if len(lhs) == 2 && len(rhs) == 1 {
269 // x, ok = y
270 lhs = lhs[:1]
271 }
272
273 // Match as much as we can.
274 for i := 0; i < len(lhs) && i < len(rhs); i++ {
275 x, y := lhs[i], rhs[i]
276 if typeof[y] != "" {
277 set(x, typeof[y], isDecl)
278 } else {
279 set(y, typeof[x], false)
280 }
281 }
282 }
283
284 expand := func(s string) string {
285 typ := cfg.Type[s]
286 if typ != nil && typ.Def != "" {
287 return typ.Def
288 }
289 return s
290 }
291
292 // The main type check is a recursive algorithm implemented
293 // by walkBeforeAfter(n, before, after).
294 // Most of it is bottom-up, but in a few places we need
295 // to know the type of the function we are checking.
296 // The before function records that information on
297 // the curfn stack.
298 var curfn []*ast.FuncType
299
300 before := func(n interface{}) {
301 // push function type on stack
302 switch n := n.(type) {
303 case *ast.FuncDecl:
304 curfn = append(curfn, n.Type)
305 case *ast.FuncLit:
306 curfn = append(curfn, n.Type)
307 }
308 }
309
310 // After is the real type checker.
311 after := func(n interface{}) {
312 if n == nil {
313 return
314 }
315 if false && reflect.TypeOf(n).Kind() == reflect.Ptr { // debugging trace
316 defer func() {
317 if t := typeof[n]; t != "" {
318 pos := fset.Position(n.(ast.Node).Pos())
319 fmt.Fprintf(os.Stderr, "%s: typeof[%s] = %s\n", pos, gofmt(n), t)
320 }
321 }()
322 }
323
324 switch n := n.(type) {
325 case *ast.FuncDecl, *ast.FuncLit:
326 // pop function type off stack
327 curfn = curfn[:len(curfn)-1]
328
329 case *ast.FuncType:
330 typeof[n] = mkType(joinFunc(split(typeof[n.Params]), split(typeof[n.Results])))
331
332 case *ast.FieldList:
333 // Field list is concatenation of sub-lists.
334 t := ""
335 for _, field := range n.List {
336 if t != "" {
337 t += ", "
338 }
339 t += typeof[field]
340 }
341 typeof[n] = t
342
343 case *ast.Field:
344 // Field is one instance of the type per name.
345 all := ""
346 t := typeof[n.Type]
347 if !isType(t) {
348 // Create a type, because it is typically *T or *p.T
349 // and we might care about that type.
350 t = mkType(gofmt(n.Type))
351 typeof[n.Type] = t
352 }
353 t = getType(t)
354 if len(n.Names) == 0 {
355 all = t
356 } else {
357 for _, id := range n.Names {
358 if all != "" {
359 all += ", "
360 }
361 all += t
362 typeof[id.Obj] = t
363 typeof[id] = t
364 }
365 }
366 typeof[n] = all
367
368 case *ast.ValueSpec:
369 // var declaration. Use type if present.
370 if n.Type != nil {
371 t := typeof[n.Type]
372 if !isType(t) {
373 t = mkType(gofmt(n.Type))
374 typeof[n.Type] = t
375 }
376 t = getType(t)
377 for _, id := range n.Names {
378 set(id, t, true)
379 }
380 }
381 // Now treat same as assignment.
382 typecheckAssign(makeExprList(n.Names), n.Values, true)
383
384 case *ast.AssignStmt:
385 typecheckAssign(n.Lhs, n.Rhs, n.Tok == token.DEFINE)
386
387 case *ast.Ident:
388 // Identifier can take its type from underlying object.
389 if t := typeof[n.Obj]; t != "" {
390 typeof[n] = t
391 }
392
393 case *ast.SelectorExpr:
394 // Field or method.
395 name := n.Sel.Name
396 if t := typeof[n.X]; t != "" {
397 if strings.HasPrefix(t, "*") {
398 t = t[1:] // implicit *
399 }
400 if typ := cfg.Type[t]; typ != nil {
401 if t := typ.dot(cfg, name); t != "" {
402 typeof[n] = t
403 return
404 }
405 }
406 tt := typeof[t+"."+name]
407 if isType(tt) {
408 typeof[n] = getType(tt)
409 return
410 }
411 }
412 // Package selector.
413 if x, ok := n.X.(*ast.Ident); ok && x.Obj == nil {
414 str := x.Name + "." + name
415 if cfg.Type[str] != nil {
416 typeof[n] = mkType(str)
417 return
418 }
419 if t := cfg.typeof(x.Name + "." + name); t != "" {
420 typeof[n] = t
421 return
422 }
423 }
424
425 case *ast.CallExpr:
426 // make(T) has type T.
427 if isTopName(n.Fun, "make") && len(n.Args) >= 1 {
428 typeof[n] = gofmt(n.Args[0])
429 return
430 }
431 // new(T) has type *T
432 if isTopName(n.Fun, "new") && len(n.Args) == 1 {
433 typeof[n] = "*" + gofmt(n.Args[0])
434 return
435 }
436 // Otherwise, use type of function to determine arguments.
437 t := typeof[n.Fun]
438 in, out := splitFunc(t)
439 if in == nil && out == nil {
440 return
441 }
442 typeof[n] = join(out)
443 for i, arg := range n.Args {
444 if i >= len(in) {
445 break
446 }
447 if typeof[arg] == "" {
448 typeof[arg] = in[i]
449 }
450 }
451
452 case *ast.TypeAssertExpr:
453 // x.(type) has type of x.
454 if n.Type == nil {
455 typeof[n] = typeof[n.X]
456 return
457 }
458 // x.(T) has type T.
459 if t := typeof[n.Type]; isType(t) {
460 typeof[n] = getType(t)
461 } else {
462 typeof[n] = gofmt(n.Type)
463 }
464
465 case *ast.SliceExpr:
466 // x[i:j] has type of x.
467 typeof[n] = typeof[n.X]
468
469 case *ast.IndexExpr:
470 // x[i] has key type of x's type.
471 t := expand(typeof[n.X])
472 if strings.HasPrefix(t, "[") || strings.HasPrefix(t, "map[") {
473 // Lazy: assume there are no nested [] in the array
474 // length or map key type.
475 if i := strings.Index(t, "]"); i >= 0 {
476 typeof[n] = t[i+1:]
477 }
478 }
479
480 case *ast.StarExpr:
481 // *x for x of type *T has type T when x is an expr.
482 // We don't use the result when *x is a type, but
483 // compute it anyway.
484 t := expand(typeof[n.X])
485 if isType(t) {
486 typeof[n] = "type *" + getType(t)
487 } else if strings.HasPrefix(t, "*") {
488 typeof[n] = t[len("*"):]
489 }
490
491 case *ast.UnaryExpr:
492 // &x for x of type T has type *T.
493 t := typeof[n.X]
494 if t != "" && n.Op == token.AND {
495 typeof[n] = "*" + t
496 }
497
498 case *ast.CompositeLit:
499 // T{...} has type T.
500 typeof[n] = gofmt(n.Type)
501
502 case *ast.ParenExpr:
503 // (x) has type of x.
504 typeof[n] = typeof[n.X]
505
506 case *ast.RangeStmt:
507 t := expand(typeof[n.X])
508 if t == "" {
509 return
510 }
511 var key, value string
512 if t == "string" {
513 key, value = "int", "rune"
514 } else if strings.HasPrefix(t, "[") {
515 key = "int"
516 if i := strings.Index(t, "]"); i >= 0 {
517 value = t[i+1:]
518 }
519 } else if strings.HasPrefix(t, "map[") {
520 if i := strings.Index(t, "]"); i >= 0 {
521 key, value = t[4:i], t[i+1:]
522 }
523 }
524 changed := false
525 if n.Key != nil && key != "" {
526 changed = true
527 set(n.Key, key, n.Tok == token.DEFINE)
528 }
529 if n.Value != nil && value != "" {
530 changed = true
531 set(n.Value, value, n.Tok == token.DEFINE)
532 }
533 // Ugly failure of vision: already type-checked body.
534 // Do it again now that we have that type info.
535 if changed {
536 typecheck1(cfg, n.Body, typeof, assign)
537 }
538
539 case *ast.TypeSwitchStmt:
540 // Type of variable changes for each case in type switch,
541 // but go/parser generates just one variable.
542 // Repeat type check for each case with more precise
543 // type information.
544 as, ok := n.Assign.(*ast.AssignStmt)
545 if !ok {
546 return
547 }
548 varx, ok := as.Lhs[0].(*ast.Ident)
549 if !ok {
550 return
551 }
552 t := typeof[varx]
553 for _, cas := range n.Body.List {
554 cas := cas.(*ast.CaseClause)
555 if len(cas.List) == 1 {
556 // Variable has specific type only when there is
557 // exactly one type in the case list.
558 if tt := typeof[cas.List[0]]; isType(tt) {
559 tt = getType(tt)
560 typeof[varx] = tt
561 typeof[varx.Obj] = tt
562 typecheck1(cfg, cas.Body, typeof, assign)
563 }
564 }
565 }
566 // Restore t.
567 typeof[varx] = t
568 typeof[varx.Obj] = t
569
570 case *ast.ReturnStmt:
571 if len(curfn) == 0 {
572 // Probably can't happen.
573 return
574 }
575 f := curfn[len(curfn)-1]
576 res := n.Results
577 if f.Results != nil {
578 t := split(typeof[f.Results])
579 for i := 0; i < len(res) && i < len(t); i++ {
580 set(res[i], t[i], false)
581 }
582 }
583 }
584 }
585 walkBeforeAfter(f, before, after)
586 }
587
588 // Convert between function type strings and lists of types.
589 // Using strings makes this a little harder, but it makes
590 // a lot of the rest of the code easier. This will all go away
591 // when we can use go/typechecker directly.
592
593 // splitFunc splits "func(x,y,z) (a,b,c)" into ["x", "y", "z"] and ["a", "b", "c"].
594 func splitFunc(s string) (in, out []string) {
595 if !strings.HasPrefix(s, "func(") {
596 return nil, nil
597 }
598
599 i := len("func(") // index of beginning of 'in' arguments
600 nparen := 0
601 for j := i; j < len(s); j++ {
602 switch s[j] {
603 case '(':
604 nparen++
605 case ')':
606 nparen--
607 if nparen < 0 {
608 // found end of parameter list
609 out := strings.TrimSpace(s[j+1:])
610 if len(out) >= 2 && out[0] == '(' && out[len(out)-1] == ')' {
611 out = out[1 : len(out)-1]
612 }
613 return split(s[i:j]), split(out)
614 }
615 }
616 }
617 return nil, nil
618 }
619
620 // joinFunc is the inverse of splitFunc.
621 func joinFunc(in, out []string) string {
622 outs := ""
623 if len(out) == 1 {
624 outs = " " + out[0]
625 } else if len(out) > 1 {
626 outs = " (" + join(out) + ")"
627 }
628 return "func(" + join(in) + ")" + outs
629 }
630
631 // split splits "int, float" into ["int", "float"] and splits "" into [].
632 func split(s string) []string {
633 out := []string{}
634 i := 0 // current type being scanned is s[i:j].
635 nparen := 0
636 for j := 0; j < len(s); j++ {
637 switch s[j] {
638 case ' ':
639 if i == j {
640 i++
641 }
642 case '(':
643 nparen++
644 case ')':
645 nparen--
646 if nparen < 0 {
647 // probably can't happen
648 return nil
649 }
650 case ',':
651 if nparen == 0 {
652 if i < j {
653 out = append(out, s[i:j])
654 }
655 i = j + 1
656 }
657 }
658 }
659 if nparen != 0 {
660 // probably can't happen
661 return nil
662 }
663 if i < len(s) {
664 out = append(out, s[i:])
665 }
666 return out
667 }
668
669 // join is the inverse of split.
670 func join(x []string) string {
671 return strings.Join(x, ", ")
672 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "context"
8 "errors"
9 "fmt"
10 "reflect"
11
12 "github.com/golang/protobuf/proto"
13
14 "google.golang.org/appengine/v2"
15 "google.golang.org/appengine/v2/internal"
16 pb "google.golang.org/appengine/v2/internal/datastore"
17 )
18
19 var (
20 // ErrInvalidEntityType is returned when functions like Get or Next are
21 // passed a dst or src argument of invalid type.
22 ErrInvalidEntityType = errors.New("datastore: invalid entity type")
23 // ErrInvalidKey is returned when an invalid key is presented.
24 ErrInvalidKey = errors.New("datastore: invalid key")
25 // ErrNoSuchEntity is returned when no entity was found for a given key.
26 ErrNoSuchEntity = errors.New("datastore: no such entity")
27 )
28
29 // ErrFieldMismatch is returned when a field is to be loaded into a different
30 // type than the one it was stored from, or when a field is missing or
31 // unexported in the destination struct.
32 // StructType is the type of the struct pointed to by the destination argument
33 // passed to Get or to Iterator.Next.
34 type ErrFieldMismatch struct {
35 StructType reflect.Type
36 FieldName string
37 Reason string
38 }
39
40 func (e *ErrFieldMismatch) Error() string {
41 return fmt.Sprintf("datastore: cannot load field %q into a %q: %s",
42 e.FieldName, e.StructType, e.Reason)
43 }
44
45 // protoToKey converts a Reference proto to a *Key. If the key is invalid,
46 // protoToKey will return the invalid key along with ErrInvalidKey.
47 func protoToKey(r *pb.Reference) (k *Key, err error) {
48 appID := r.GetApp()
49 namespace := r.GetNameSpace()
50 for _, e := range r.Path.Element {
51 k = &Key{
52 kind: e.GetType(),
53 stringID: e.GetName(),
54 intID: e.GetId(),
55 parent: k,
56 appID: appID,
57 namespace: namespace,
58 }
59 if !k.valid() {
60 return k, ErrInvalidKey
61 }
62 }
63 return
64 }
65
66 // keyToProto converts a *Key to a Reference proto.
67 func keyToProto(defaultAppID string, k *Key) *pb.Reference {
68 appID := k.appID
69 if appID == "" {
70 appID = defaultAppID
71 }
72 n := 0
73 for i := k; i != nil; i = i.parent {
74 n++
75 }
76 e := make([]*pb.Path_Element, n)
77 for i := k; i != nil; i = i.parent {
78 n--
79 e[n] = &pb.Path_Element{
80 Type: &i.kind,
81 }
82 // At most one of {Name,Id} should be set.
83 // Neither will be set for incomplete keys.
84 if i.stringID != "" {
85 e[n].Name = &i.stringID
86 } else if i.intID != 0 {
87 e[n].Id = &i.intID
88 }
89 }
90 var namespace *string
91 if k.namespace != "" {
92 namespace = proto.String(k.namespace)
93 }
94 return &pb.Reference{
95 App: proto.String(appID),
96 NameSpace: namespace,
97 Path: &pb.Path{
98 Element: e,
99 },
100 }
101 }
102
103 // multiKeyToProto is a batch version of keyToProto.
104 func multiKeyToProto(appID string, key []*Key) []*pb.Reference {
105 ret := make([]*pb.Reference, len(key))
106 for i, k := range key {
107 ret[i] = keyToProto(appID, k)
108 }
109 return ret
110 }
111
112 // multiValid is a batch version of Key.valid. It returns an error, not a
113 // []bool.
114 func multiValid(key []*Key) error {
115 invalid := false
116 for _, k := range key {
117 if !k.valid() {
118 invalid = true
119 break
120 }
121 }
122 if !invalid {
123 return nil
124 }
125 err := make(appengine.MultiError, len(key))
126 for i, k := range key {
127 if !k.valid() {
128 err[i] = ErrInvalidKey
129 }
130 }
131 return err
132 }
133
134 // It's unfortunate that the two semantically equivalent concepts pb.Reference
135 // and pb.PropertyValue_ReferenceValue aren't the same type. For example, the
136 // two have different protobuf field numbers.
137
138 // referenceValueToKey is the same as protoToKey except the input is a
139 // PropertyValue_ReferenceValue instead of a Reference.
140 func referenceValueToKey(r *pb.PropertyValue_ReferenceValue) (k *Key, err error) {
141 appID := r.GetApp()
142 namespace := r.GetNameSpace()
143 for _, e := range r.Pathelement {
144 k = &Key{
145 kind: e.GetType(),
146 stringID: e.GetName(),
147 intID: e.GetId(),
148 parent: k,
149 appID: appID,
150 namespace: namespace,
151 }
152 if !k.valid() {
153 return nil, ErrInvalidKey
154 }
155 }
156 return
157 }
158
159 // keyToReferenceValue is the same as keyToProto except the output is a
160 // PropertyValue_ReferenceValue instead of a Reference.
161 func keyToReferenceValue(defaultAppID string, k *Key) *pb.PropertyValue_ReferenceValue {
162 ref := keyToProto(defaultAppID, k)
163 pe := make([]*pb.PropertyValue_ReferenceValue_PathElement, len(ref.Path.Element))
164 for i, e := range ref.Path.Element {
165 pe[i] = &pb.PropertyValue_ReferenceValue_PathElement{
166 Type: e.Type,
167 Id: e.Id,
168 Name: e.Name,
169 }
170 }
171 return &pb.PropertyValue_ReferenceValue{
172 App: ref.App,
173 NameSpace: ref.NameSpace,
174 Pathelement: pe,
175 }
176 }
177
178 type multiArgType int
179
180 const (
181 multiArgTypeInvalid multiArgType = iota
182 multiArgTypePropertyLoadSaver
183 multiArgTypeStruct
184 multiArgTypeStructPtr
185 multiArgTypeInterface
186 )
187
188 // checkMultiArg checks that v has type []S, []*S, []I, or []P, for some struct
189 // type S, for some interface type I, or some non-interface non-pointer type P
190 // such that P or *P implements PropertyLoadSaver.
191 //
192 // It returns what category the slice's elements are, and the reflect.Type
193 // that represents S, I or P.
194 //
195 // As a special case, PropertyList is an invalid type for v.
196 func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) {
197 if v.Kind() != reflect.Slice {
198 return multiArgTypeInvalid, nil
199 }
200 if v.Type() == typeOfPropertyList {
201 return multiArgTypeInvalid, nil
202 }
203 elemType = v.Type().Elem()
204 if reflect.PtrTo(elemType).Implements(typeOfPropertyLoadSaver) {
205 return multiArgTypePropertyLoadSaver, elemType
206 }
207 switch elemType.Kind() {
208 case reflect.Struct:
209 return multiArgTypeStruct, elemType
210 case reflect.Interface:
211 return multiArgTypeInterface, elemType
212 case reflect.Ptr:
213 elemType = elemType.Elem()
214 if elemType.Kind() == reflect.Struct {
215 return multiArgTypeStructPtr, elemType
216 }
217 }
218 return multiArgTypeInvalid, nil
219 }
220
221 // Get loads the entity stored for k into dst, which must be a struct pointer
222 // or implement PropertyLoadSaver. If there is no such entity for the key, Get
223 // returns ErrNoSuchEntity.
224 //
225 // The values of dst's unmatched struct fields are not modified, and matching
226 // slice-typed fields are not reset before appending to them. In particular, it
227 // is recommended to pass a pointer to a zero valued struct on each Get call.
228 //
229 // ErrFieldMismatch is returned when a field is to be loaded into a different
230 // type than the one it was stored from, or when a field is missing or
231 // unexported in the destination struct. ErrFieldMismatch is only returned if
232 // dst is a struct pointer.
233 func Get(c context.Context, key *Key, dst interface{}) error {
234 if dst == nil { // GetMulti catches nil interface; we need to catch nil ptr here
235 return ErrInvalidEntityType
236 }
237 err := GetMulti(c, []*Key{key}, []interface{}{dst})
238 if me, ok := err.(appengine.MultiError); ok {
239 return me[0]
240 }
241 return err
242 }
243
244 // GetMulti is a batch version of Get.
245 //
246 // dst must be a []S, []*S, []I or []P, for some struct type S, some interface
247 // type I, or some non-interface non-pointer type P such that P or *P
248 // implements PropertyLoadSaver. If an []I, each element must be a valid dst
249 // for Get: it must be a struct pointer or implement PropertyLoadSaver.
250 //
251 // As a special case, PropertyList is an invalid type for dst, even though a
252 // PropertyList is a slice of structs. It is treated as invalid to avoid being
253 // mistakenly passed when []PropertyList was intended.
254 func GetMulti(c context.Context, key []*Key, dst interface{}) error {
255 v := reflect.ValueOf(dst)
256 multiArgType, _ := checkMultiArg(v)
257 if multiArgType == multiArgTypeInvalid {
258 return errors.New("datastore: dst has invalid type")
259 }
260 if len(key) != v.Len() {
261 return errors.New("datastore: key and dst slices have different length")
262 }
263 if len(key) == 0 {
264 return nil
265 }
266 if err := multiValid(key); err != nil {
267 return err
268 }
269 req := &pb.GetRequest{
270 Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key),
271 }
272 res := &pb.GetResponse{}
273 if err := internal.Call(c, "datastore_v3", "Get", req, res); err != nil {
274 return err
275 }
276 if len(key) != len(res.Entity) {
277 return errors.New("datastore: internal error: server returned the wrong number of entities")
278 }
279 multiErr, any := make(appengine.MultiError, len(key)), false
280 for i, e := range res.Entity {
281 if e.Entity == nil {
282 multiErr[i] = ErrNoSuchEntity
283 } else {
284 elem := v.Index(i)
285 if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct {
286 elem = elem.Addr()
287 }
288 if multiArgType == multiArgTypeStructPtr && elem.IsNil() {
289 elem.Set(reflect.New(elem.Type().Elem()))
290 }
291 multiErr[i] = loadEntity(elem.Interface(), e.Entity)
292 }
293 if multiErr[i] != nil {
294 any = true
295 }
296 }
297 if any {
298 return multiErr
299 }
300 return nil
301 }
302
303 // Put saves the entity src into the datastore with key k. src must be a struct
304 // pointer or implement PropertyLoadSaver; if a struct pointer then any
305 // unexported fields of that struct will be skipped. If k is an incomplete key,
306 // the returned key will be a unique key generated by the datastore.
307 func Put(c context.Context, key *Key, src interface{}) (*Key, error) {
308 k, err := PutMulti(c, []*Key{key}, []interface{}{src})
309 if err != nil {
310 if me, ok := err.(appengine.MultiError); ok {
311 return nil, me[0]
312 }
313 return nil, err
314 }
315 return k[0], nil
316 }
317
318 // PutMulti is a batch version of Put.
319 //
320 // src must satisfy the same conditions as the dst argument to GetMulti.
321 func PutMulti(c context.Context, key []*Key, src interface{}) ([]*Key, error) {
322 v := reflect.ValueOf(src)
323 multiArgType, _ := checkMultiArg(v)
324 if multiArgType == multiArgTypeInvalid {
325 return nil, errors.New("datastore: src has invalid type")
326 }
327 if len(key) != v.Len() {
328 return nil, errors.New("datastore: key and src slices have different length")
329 }
330 if len(key) == 0 {
331 return nil, nil
332 }
333 appID := internal.FullyQualifiedAppID(c)
334 if err := multiValid(key); err != nil {
335 return nil, err
336 }
337 req := &pb.PutRequest{}
338 for i := range key {
339 elem := v.Index(i)
340 if multiArgType == multiArgTypePropertyLoadSaver || multiArgType == multiArgTypeStruct {
341 elem = elem.Addr()
342 }
343 sProto, err := saveEntity(appID, key[i], elem.Interface())
344 if err != nil {
345 return nil, err
346 }
347 req.Entity = append(req.Entity, sProto)
348 }
349 res := &pb.PutResponse{}
350 if err := internal.Call(c, "datastore_v3", "Put", req, res); err != nil {
351 return nil, err
352 }
353 if len(key) != len(res.Key) {
354 return nil, errors.New("datastore: internal error: server returned the wrong number of keys")
355 }
356 ret := make([]*Key, len(key))
357 for i := range ret {
358 var err error
359 ret[i], err = protoToKey(res.Key[i])
360 if err != nil || ret[i].Incomplete() {
361 return nil, errors.New("datastore: internal error: server returned an invalid key")
362 }
363 }
364 return ret, nil
365 }
366
367 // Delete deletes the entity for the given key.
368 func Delete(c context.Context, key *Key) error {
369 err := DeleteMulti(c, []*Key{key})
370 if me, ok := err.(appengine.MultiError); ok {
371 return me[0]
372 }
373 return err
374 }
375
376 // DeleteMulti is a batch version of Delete.
377 func DeleteMulti(c context.Context, key []*Key) error {
378 if len(key) == 0 {
379 return nil
380 }
381 if err := multiValid(key); err != nil {
382 return err
383 }
384 req := &pb.DeleteRequest{
385 Key: multiKeyToProto(internal.FullyQualifiedAppID(c), key),
386 }
387 res := &pb.DeleteResponse{}
388 return internal.Call(c, "datastore_v3", "Delete", req, res)
389 }
390
391 func namespaceMod(m proto.Message, namespace string) {
392 // pb.Query is the only type that has a name_space field.
393 // All other namespace support in datastore is in the keys.
394 switch m := m.(type) {
395 case *pb.Query:
396 if m.NameSpace == nil {
397 m.NameSpace = &namespace
398 }
399 }
400 }
401
402 func init() {
403 internal.NamespaceMods["datastore_v3"] = namespaceMod
404 internal.RegisterErrorCodeMap("datastore_v3", pb.Error_ErrorCode_name)
405 internal.RegisterTimeoutErrorCode("datastore_v3", int32(pb.Error_TIMEOUT))
406 }
0 // Copyright 2011 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "encoding/json"
8 "errors"
9 "fmt"
10 "os"
11 "reflect"
12 "sort"
13 "strings"
14 "testing"
15 "time"
16
17 "google.golang.org/appengine/v2"
18 "google.golang.org/appengine/v2/internal/aetesting"
19 pb "google.golang.org/appengine/v2/internal/datastore"
20 )
21
22 const testAppID = "testApp"
23
24 type (
25 myBlob []byte
26 myByte byte
27 myString string
28 )
29
30 func makeMyByteSlice(n int) []myByte {
31 b := make([]myByte, n)
32 for i := range b {
33 b[i] = myByte(i)
34 }
35 return b
36 }
37
38 func makeInt8Slice(n int) []int8 {
39 b := make([]int8, n)
40 for i := range b {
41 b[i] = int8(i)
42 }
43 return b
44 }
45
46 func makeUint8Slice(n int) []uint8 {
47 b := make([]uint8, n)
48 for i := range b {
49 b[i] = uint8(i)
50 }
51 return b
52 }
53
54 func newKey(stringID string, parent *Key) *Key {
55 return &Key{
56 kind: "kind",
57 stringID: stringID,
58 intID: 0,
59 parent: parent,
60 appID: testAppID,
61 }
62 }
63
64 var (
65 testKey0 = newKey("name0", nil)
66 testKey1a = newKey("name1", nil)
67 testKey1b = newKey("name1", nil)
68 testKey2a = newKey("name2", testKey0)
69 testKey2b = newKey("name2", testKey0)
70 testGeoPt0 = appengine.GeoPoint{Lat: 1.2, Lng: 3.4}
71 testGeoPt1 = appengine.GeoPoint{Lat: 5, Lng: 10}
72 testBadGeoPt = appengine.GeoPoint{Lat: 1000, Lng: 34}
73
74 now = time.Unix(1e9, 0).UTC()
75 )
76
77 type B0 struct {
78 B []byte
79 }
80
81 type B1 struct {
82 B []int8
83 }
84
85 type B2 struct {
86 B myBlob
87 }
88
89 type B3 struct {
90 B []myByte
91 }
92
93 type B4 struct {
94 B [][]byte
95 }
96
97 type B5 struct {
98 B ByteString
99 }
100
101 type C0 struct {
102 I int
103 C chan int
104 }
105
106 type C1 struct {
107 I int
108 C *chan int
109 }
110
111 type C2 struct {
112 I int
113 C []chan int
114 }
115
116 type C3 struct {
117 C string
118 }
119
120 type E struct{}
121
122 type G0 struct {
123 G appengine.GeoPoint
124 }
125
126 type G1 struct {
127 G []appengine.GeoPoint
128 }
129
130 type K0 struct {
131 K *Key
132 }
133
134 type K1 struct {
135 K []*Key
136 }
137
138 type S struct {
139 St string
140 }
141
142 type NoOmit struct {
143 A string
144 B int `datastore:"Bb"`
145 C bool `datastore:",noindex"`
146 }
147
148 type OmitAll struct {
149 A string `datastore:",omitempty"`
150 B int `datastore:"Bb,omitempty"`
151 C bool `datastore:",omitempty,noindex"`
152 D time.Time `datastore:",omitempty"`
153 F []int `datastore:",omitempty"`
154 }
155
156 type Omit struct {
157 A string `datastore:",omitempty"`
158 B int `datastore:"Bb,omitempty"`
159 C bool `datastore:",omitempty,noindex"`
160 D time.Time `datastore:",omitempty"`
161 F []int `datastore:",omitempty"`
162 S `datastore:",omitempty"`
163 }
164
165 type NoOmits struct {
166 No []NoOmit `datastore:",omitempty"`
167 S `datastore:",omitempty"`
168 Ss S `datastore:",omitempty"`
169 }
170
171 type N0 struct {
172 X0
173 Nonymous X0
174 Ignore string `datastore:"-"`
175 Other string
176 }
177
178 type N1 struct {
179 X0
180 Nonymous []X0
181 Ignore string `datastore:"-"`
182 Other string
183 }
184
185 type N2 struct {
186 N1 `datastore:"red"`
187 Green N1 `datastore:"green"`
188 Blue N1
189 White N1 `datastore:"-"`
190 }
191
192 type O0 struct {
193 I int64
194 }
195
196 type O1 struct {
197 I int32
198 }
199
200 type U0 struct {
201 U uint
202 }
203
204 type U1 struct {
205 U string
206 }
207
208 type T struct {
209 T time.Time
210 }
211
212 type X0 struct {
213 S string
214 I int
215 i int
216 }
217
218 type X1 struct {
219 S myString
220 I int32
221 J int64
222 }
223
224 type X2 struct {
225 Z string
226 i int
227 }
228
229 type X3 struct {
230 S bool
231 I int
232 }
233
234 type Y0 struct {
235 B bool
236 F []float64
237 G []float64
238 }
239
240 type Y1 struct {
241 B bool
242 F float64
243 }
244
245 type Y2 struct {
246 B bool
247 F []int64
248 }
249
250 type Tagged struct {
251 A int `datastore:"a,noindex"`
252 B []int `datastore:"b"`
253 C int `datastore:",noindex"`
254 D int `datastore:""`
255 E int
256 // The "flatten" option is parsed but ignored for now.
257 F int `datastore:",noindex,flatten"`
258 G int `datastore:",flatten"`
259 I int `datastore:"-"`
260 J int `datastore:",noindex" json:"j"`
261
262 Y0 `datastore:"-"`
263 Z chan int `datastore:"-,"`
264 }
265
266 type InvalidTagged1 struct {
267 I int `datastore:"\t"`
268 }
269
270 type InvalidTagged2 struct {
271 I int
272 J int `datastore:"I"`
273 }
274
275 type Inner1 struct {
276 W int32
277 X string
278 }
279
280 type Inner2 struct {
281 Y float64
282 }
283
284 type Inner3 struct {
285 Z bool
286 }
287
288 type Outer struct {
289 A int16
290 I []Inner1
291 J Inner2
292 Inner3
293 }
294
295 type OuterEquivalent struct {
296 A int16
297 IDotW []int32 `datastore:"I.W"`
298 IDotX []string `datastore:"I.X"`
299 JDotY float64 `datastore:"J.Y"`
300 Z bool
301 }
302
303 type Dotted struct {
304 A DottedA `datastore:"A0.A1.A2"`
305 }
306
307 type DottedA struct {
308 B DottedB `datastore:"B3"`
309 }
310
311 type DottedB struct {
312 C int `datastore:"C4.C5"`
313 }
314
315 type SliceOfSlices struct {
316 I int
317 S []struct {
318 J int
319 F []float64
320 }
321 }
322
323 type Recursive struct {
324 I int
325 R []Recursive
326 }
327
328 type MutuallyRecursive0 struct {
329 I int
330 R []MutuallyRecursive1
331 }
332
333 type MutuallyRecursive1 struct {
334 I int
335 R []MutuallyRecursive0
336 }
337
338 type Doubler struct {
339 S string
340 I int64
341 B bool
342 }
343
344 type Repeat struct {
345 Key string
346 Value []byte
347 }
348
349 type Repeated struct {
350 Repeats []Repeat
351 }
352
353 func (d *Doubler) Load(props []Property) error {
354 return LoadStruct(d, props)
355 }
356
357 type EmbeddedTime struct {
358 time.Time
359 }
360
361 type SpecialTime struct {
362 MyTime EmbeddedTime
363 }
364
365 func (d *Doubler) Save() ([]Property, error) {
366 // Save the default Property slice to an in-memory buffer (a PropertyList).
367 props, err := SaveStruct(d)
368 if err != nil {
369 return nil, err
370 }
371 var list PropertyList
372 if err := list.Load(props); err != nil {
373 return nil, err
374 }
375
376 // Edit that PropertyList, and send it on.
377 for i := range list {
378 switch v := list[i].Value.(type) {
379 case string:
380 // + means string concatenation.
381 list[i].Value = v + v
382 case int64:
383 // + means integer addition.
384 list[i].Value = v + v
385 }
386 }
387 return list.Save()
388 }
389
390 var _ PropertyLoadSaver = (*Doubler)(nil)
391
392 type Deriver struct {
393 S, Derived, Ignored string
394 }
395
396 func (e *Deriver) Load(props []Property) error {
397 for _, p := range props {
398 if p.Name != "S" {
399 continue
400 }
401 e.S = p.Value.(string)
402 e.Derived = "derived+" + e.S
403 }
404 return nil
405 }
406
407 func (e *Deriver) Save() ([]Property, error) {
408 return []Property{
409 {
410 Name: "S",
411 Value: e.S,
412 },
413 }, nil
414 }
415
416 var _ PropertyLoadSaver = (*Deriver)(nil)
417
418 type BadMultiPropEntity struct{}
419
420 func (e *BadMultiPropEntity) Load(props []Property) error {
421 return errors.New("unimplemented")
422 }
423
424 func (e *BadMultiPropEntity) Save() ([]Property, error) {
425 // Write multiple properties with the same name "I", but Multiple is false.
426 var props []Property
427 for i := 0; i < 3; i++ {
428 props = append(props, Property{
429 Name: "I",
430 Value: int64(i),
431 })
432 }
433 return props, nil
434 }
435
436 var _ PropertyLoadSaver = (*BadMultiPropEntity)(nil)
437
438 type BK struct {
439 Key appengine.BlobKey
440 }
441
442 type testCase struct {
443 desc string
444 src interface{}
445 want interface{}
446 putErr string
447 getErr string
448 }
449
450 var testCases = []testCase{
451 {
452 "chan save fails",
453 &C0{I: -1},
454 &E{},
455 "unsupported struct field",
456 "",
457 },
458 {
459 "*chan save fails",
460 &C1{I: -1},
461 &E{},
462 "unsupported struct field",
463 "",
464 },
465 {
466 "[]chan save fails",
467 &C2{I: -1, C: make([]chan int, 8)},
468 &E{},
469 "unsupported struct field",
470 "",
471 },
472 {
473 "chan load fails",
474 &C3{C: "not a chan"},
475 &C0{},
476 "",
477 "type mismatch",
478 },
479 {
480 "*chan load fails",
481 &C3{C: "not a *chan"},
482 &C1{},
483 "",
484 "type mismatch",
485 },
486 {
487 "[]chan load fails",
488 &C3{C: "not a []chan"},
489 &C2{},
490 "",
491 "type mismatch",
492 },
493 {
494 "empty struct",
495 &E{},
496 &E{},
497 "",
498 "",
499 },
500 {
501 "geopoint",
502 &G0{G: testGeoPt0},
503 &G0{G: testGeoPt0},
504 "",
505 "",
506 },
507 {
508 "geopoint invalid",
509 &G0{G: testBadGeoPt},
510 &G0{},
511 "invalid GeoPoint value",
512 "",
513 },
514 {
515 "geopoint as props",
516 &G0{G: testGeoPt0},
517 &PropertyList{
518 Property{Name: "G", Value: testGeoPt0, NoIndex: false, Multiple: false},
519 },
520 "",
521 "",
522 },
523 {
524 "geopoint slice",
525 &G1{G: []appengine.GeoPoint{testGeoPt0, testGeoPt1}},
526 &G1{G: []appengine.GeoPoint{testGeoPt0, testGeoPt1}},
527 "",
528 "",
529 },
530 {
531 "omit empty, all",
532 &OmitAll{},
533 new(PropertyList),
534 "",
535 "",
536 },
537 {
538 "omit empty",
539 &Omit{},
540 &PropertyList{
541 Property{Name: "St", Value: "", NoIndex: false, Multiple: false},
542 },
543 "",
544 "",
545 },
546 {
547 "omit empty, fields populated",
548 &Omit{
549 A: "a",
550 B: 10,
551 C: true,
552 D: now,
553 F: []int{11},
554 },
555 &PropertyList{
556 Property{Name: "A", Value: "a", NoIndex: false, Multiple: false},
557 Property{Name: "Bb", Value: int64(10), NoIndex: false, Multiple: false},
558 Property{Name: "C", Value: true, NoIndex: true, Multiple: false},
559 Property{Name: "D", Value: now, NoIndex: false, Multiple: false},
560 Property{Name: "F", Value: int64(11), NoIndex: false, Multiple: true},
561 Property{Name: "St", Value: "", NoIndex: false, Multiple: false},
562 },
563 "",
564 "",
565 },
566 {
567 "omit empty, fields populated",
568 &Omit{
569 A: "a",
570 B: 10,
571 C: true,
572 D: now,
573 F: []int{11},
574 S: S{St: "string"},
575 },
576 &PropertyList{
577 Property{Name: "A", Value: "a", NoIndex: false, Multiple: false},
578 Property{Name: "Bb", Value: int64(10), NoIndex: false, Multiple: false},
579 Property{Name: "C", Value: true, NoIndex: true, Multiple: false},
580 Property{Name: "D", Value: now, NoIndex: false, Multiple: false},
581 Property{Name: "F", Value: int64(11), NoIndex: false, Multiple: true},
582 Property{Name: "St", Value: "string", NoIndex: false, Multiple: false},
583 },
584 "",
585 "",
586 },
587 {
588 "omit empty does not propagate",
589 &NoOmits{
590 No: []NoOmit{
591 NoOmit{},
592 },
593 S: S{},
594 Ss: S{},
595 },
596 &PropertyList{
597 Property{Name: "No.A", Value: "", NoIndex: false, Multiple: true},
598 Property{Name: "No.Bb", Value: int64(0), NoIndex: false, Multiple: true},
599 Property{Name: "No.C", Value: false, NoIndex: true, Multiple: true},
600 Property{Name: "Ss.St", Value: "", NoIndex: false, Multiple: false},
601 Property{Name: "St", Value: "", NoIndex: false, Multiple: false}},
602 "",
603 "",
604 },
605 {
606 "key",
607 &K0{K: testKey1a},
608 &K0{K: testKey1b},
609 "",
610 "",
611 },
612 {
613 "key with parent",
614 &K0{K: testKey2a},
615 &K0{K: testKey2b},
616 "",
617 "",
618 },
619 {
620 "nil key",
621 &K0{},
622 &K0{},
623 "",
624 "",
625 },
626 {
627 "all nil keys in slice",
628 &K1{[]*Key{nil, nil}},
629 &K1{[]*Key{nil, nil}},
630 "",
631 "",
632 },
633 {
634 "some nil keys in slice",
635 &K1{[]*Key{testKey1a, nil, testKey2a}},
636 &K1{[]*Key{testKey1b, nil, testKey2b}},
637 "",
638 "",
639 },
640 {
641 "overflow",
642 &O0{I: 1 << 48},
643 &O1{},
644 "",
645 "overflow",
646 },
647 {
648 "time",
649 &T{T: time.Unix(1e9, 0)},
650 &T{T: time.Unix(1e9, 0)},
651 "",
652 "",
653 },
654 {
655 "time as props",
656 &T{T: time.Unix(1e9, 0)},
657 &PropertyList{
658 Property{Name: "T", Value: time.Unix(1e9, 0).UTC(), NoIndex: false, Multiple: false},
659 },
660 "",
661 "",
662 },
663 {
664 "uint save",
665 &U0{U: 1},
666 &U0{},
667 "unsupported struct field",
668 "",
669 },
670 {
671 "uint load",
672 &U1{U: "not a uint"},
673 &U0{},
674 "",
675 "type mismatch",
676 },
677 {
678 "zero",
679 &X0{},
680 &X0{},
681 "",
682 "",
683 },
684 {
685 "basic",
686 &X0{S: "one", I: 2, i: 3},
687 &X0{S: "one", I: 2},
688 "",
689 "",
690 },
691 {
692 "save string/int load myString/int32",
693 &X0{S: "one", I: 2, i: 3},
694 &X1{S: "one", I: 2},
695 "",
696 "",
697 },
698 {
699 "missing fields",
700 &X0{S: "one", I: 2, i: 3},
701 &X2{},
702 "",
703 "no such struct field",
704 },
705 {
706 "save string load bool",
707 &X0{S: "one", I: 2, i: 3},
708 &X3{I: 2},
709 "",
710 "type mismatch",
711 },
712 {
713 "basic slice",
714 &Y0{B: true, F: []float64{7, 8, 9}},
715 &Y0{B: true, F: []float64{7, 8, 9}},
716 "",
717 "",
718 },
719 {
720 "save []float64 load float64",
721 &Y0{B: true, F: []float64{7, 8, 9}},
722 &Y1{B: true},
723 "",
724 "requires a slice",
725 },
726 {
727 "save []float64 load []int64",
728 &Y0{B: true, F: []float64{7, 8, 9}},
729 &Y2{B: true},
730 "",
731 "type mismatch",
732 },
733 {
734 "single slice is too long",
735 &Y0{F: make([]float64, maxIndexedProperties+1)},
736 &Y0{},
737 "too many indexed properties",
738 "",
739 },
740 {
741 "two slices are too long",
742 &Y0{F: make([]float64, maxIndexedProperties), G: make([]float64, maxIndexedProperties)},
743 &Y0{},
744 "too many indexed properties",
745 "",
746 },
747 {
748 "one slice and one scalar are too long",
749 &Y0{F: make([]float64, maxIndexedProperties), B: true},
750 &Y0{},
751 "too many indexed properties",
752 "",
753 },
754 {
755 "slice of slices of bytes",
756 &Repeated{
757 Repeats: []Repeat{
758 {
759 Key: "key 1",
760 Value: []byte("value 1"),
761 },
762 {
763 Key: "key 2",
764 Value: []byte("value 2"),
765 },
766 },
767 },
768 &Repeated{
769 Repeats: []Repeat{
770 {
771 Key: "key 1",
772 Value: []byte("value 1"),
773 },
774 {
775 Key: "key 2",
776 Value: []byte("value 2"),
777 },
778 },
779 },
780 "",
781 "",
782 },
783 {
784 "long blob",
785 &B0{B: makeUint8Slice(maxIndexedProperties + 1)},
786 &B0{B: makeUint8Slice(maxIndexedProperties + 1)},
787 "",
788 "",
789 },
790 {
791 "long []int8 is too long",
792 &B1{B: makeInt8Slice(maxIndexedProperties + 1)},
793 &B1{},
794 "too many indexed properties",
795 "",
796 },
797 {
798 "short []int8",
799 &B1{B: makeInt8Slice(3)},
800 &B1{B: makeInt8Slice(3)},
801 "",
802 "",
803 },
804 {
805 "long myBlob",
806 &B2{B: makeUint8Slice(maxIndexedProperties + 1)},
807 &B2{B: makeUint8Slice(maxIndexedProperties + 1)},
808 "",
809 "",
810 },
811 {
812 "short myBlob",
813 &B2{B: makeUint8Slice(3)},
814 &B2{B: makeUint8Slice(3)},
815 "",
816 "",
817 },
818 {
819 "long []myByte",
820 &B3{B: makeMyByteSlice(maxIndexedProperties + 1)},
821 &B3{B: makeMyByteSlice(maxIndexedProperties + 1)},
822 "",
823 "",
824 },
825 {
826 "short []myByte",
827 &B3{B: makeMyByteSlice(3)},
828 &B3{B: makeMyByteSlice(3)},
829 "",
830 "",
831 },
832 {
833 "slice of blobs",
834 &B4{B: [][]byte{
835 makeUint8Slice(3),
836 makeUint8Slice(4),
837 makeUint8Slice(5),
838 }},
839 &B4{B: [][]byte{
840 makeUint8Slice(3),
841 makeUint8Slice(4),
842 makeUint8Slice(5),
843 }},
844 "",
845 "",
846 },
847 {
848 "short ByteString",
849 &B5{B: ByteString(makeUint8Slice(3))},
850 &B5{B: ByteString(makeUint8Slice(3))},
851 "",
852 "",
853 },
854 {
855 "short ByteString as props",
856 &B5{B: ByteString(makeUint8Slice(3))},
857 &PropertyList{
858 Property{Name: "B", Value: ByteString(makeUint8Slice(3)), NoIndex: false, Multiple: false},
859 },
860 "",
861 "",
862 },
863 {
864 "short ByteString into string",
865 &B5{B: ByteString("legacy")},
866 &struct{ B string }{"legacy"},
867 "",
868 "",
869 },
870 {
871 "[]byte must be noindex",
872 &PropertyList{
873 Property{Name: "B", Value: makeUint8Slice(3), NoIndex: false},
874 },
875 nil,
876 "cannot index a []byte valued Property",
877 "",
878 },
879 {
880 "save tagged load props",
881 &Tagged{A: 1, B: []int{21, 22, 23}, C: 3, D: 4, E: 5, F: 6, G: 7, I: 8, J: 9},
882 &PropertyList{
883 // A and B are renamed to a and b; A and C are noindex, I is ignored.
884 // Indexed properties are loaded before raw properties. Thus, the
885 // result is: b, b, b, D, E, a, c.
886 Property{Name: "C", Value: int64(3), NoIndex: true, Multiple: false},
887 Property{Name: "D", Value: int64(4), NoIndex: false, Multiple: false},
888 Property{Name: "E", Value: int64(5), NoIndex: false, Multiple: false},
889 Property{Name: "F", Value: int64(6), NoIndex: true, Multiple: false},
890 Property{Name: "G", Value: int64(7), NoIndex: false, Multiple: false},
891 Property{Name: "J", Value: int64(9), NoIndex: true, Multiple: false},
892 Property{Name: "a", Value: int64(1), NoIndex: true, Multiple: false},
893 Property{Name: "b", Value: int64(21), NoIndex: false, Multiple: true},
894 Property{Name: "b", Value: int64(22), NoIndex: false, Multiple: true},
895 Property{Name: "b", Value: int64(23), NoIndex: false, Multiple: true},
896 },
897 "",
898 "",
899 },
900 {
901 "save tagged load tagged",
902 &Tagged{A: 1, B: []int{21, 22, 23}, C: 3, D: 4, E: 5, I: 6, J: 7},
903 &Tagged{A: 1, B: []int{21, 22, 23}, C: 3, D: 4, E: 5, J: 7},
904 "",
905 "",
906 },
907 {
908 "save props load tagged",
909 &PropertyList{
910 Property{Name: "A", Value: int64(11), NoIndex: true, Multiple: false},
911 Property{Name: "a", Value: int64(12), NoIndex: true, Multiple: false},
912 },
913 &Tagged{A: 12},
914 "",
915 `cannot load field "A"`,
916 },
917 {
918 "invalid tagged1",
919 &InvalidTagged1{I: 1},
920 &InvalidTagged1{},
921 "struct tag has invalid property name",
922 "",
923 },
924 {
925 "invalid tagged2",
926 &InvalidTagged2{I: 1, J: 2},
927 &InvalidTagged2{},
928 "struct tag has repeated property name",
929 "",
930 },
931 {
932 "doubler",
933 &Doubler{S: "s", I: 1, B: true},
934 &Doubler{S: "ss", I: 2, B: true},
935 "",
936 "",
937 },
938 {
939 "save struct load props",
940 &X0{S: "s", I: 1},
941 &PropertyList{
942 Property{Name: "I", Value: int64(1), NoIndex: false, Multiple: false},
943 Property{Name: "S", Value: "s", NoIndex: false, Multiple: false},
944 },
945 "",
946 "",
947 },
948 {
949 "save props load struct",
950 &PropertyList{
951 Property{Name: "S", Value: "s", NoIndex: false, Multiple: false},
952 Property{Name: "I", Value: int64(1), NoIndex: false, Multiple: false},
953 },
954 &X0{S: "s", I: 1},
955 "",
956 "",
957 },
958 {
959 "nil-value props",
960 &PropertyList{
961 Property{Name: "I", Value: nil, NoIndex: false, Multiple: false},
962 Property{Name: "B", Value: nil, NoIndex: false, Multiple: false},
963 Property{Name: "S", Value: nil, NoIndex: false, Multiple: false},
964 Property{Name: "F", Value: nil, NoIndex: false, Multiple: false},
965 Property{Name: "K", Value: nil, NoIndex: false, Multiple: false},
966 Property{Name: "T", Value: nil, NoIndex: false, Multiple: false},
967 Property{Name: "J", Value: nil, NoIndex: false, Multiple: true},
968 Property{Name: "J", Value: int64(7), NoIndex: false, Multiple: true},
969 Property{Name: "J", Value: nil, NoIndex: false, Multiple: true},
970 },
971 &struct {
972 I int64
973 B bool
974 S string
975 F float64
976 K *Key
977 T time.Time
978 J []int64
979 }{
980 J: []int64{0, 7, 0},
981 },
982 "",
983 "",
984 },
985 {
986 "save outer load props",
987 &Outer{
988 A: 1,
989 I: []Inner1{
990 {10, "ten"},
991 {20, "twenty"},
992 {30, "thirty"},
993 },
994 J: Inner2{
995 Y: 3.14,
996 },
997 Inner3: Inner3{
998 Z: true,
999 },
1000 },
1001 &PropertyList{
1002 Property{Name: "A", Value: int64(1), NoIndex: false, Multiple: false},
1003 Property{Name: "I.W", Value: int64(10), NoIndex: false, Multiple: true},
1004 Property{Name: "I.W", Value: int64(20), NoIndex: false, Multiple: true},
1005 Property{Name: "I.W", Value: int64(30), NoIndex: false, Multiple: true},
1006 Property{Name: "I.X", Value: "ten", NoIndex: false, Multiple: true},
1007 Property{Name: "I.X", Value: "twenty", NoIndex: false, Multiple: true},
1008 Property{Name: "I.X", Value: "thirty", NoIndex: false, Multiple: true},
1009 Property{Name: "J.Y", Value: float64(3.14), NoIndex: false, Multiple: false},
1010 Property{Name: "Z", Value: true, NoIndex: false, Multiple: false},
1011 },
1012 "",
1013 "",
1014 },
1015 {
1016 "save props load outer-equivalent",
1017 &PropertyList{
1018 Property{Name: "A", Value: int64(1), NoIndex: false, Multiple: false},
1019 Property{Name: "I.W", Value: int64(10), NoIndex: false, Multiple: true},
1020 Property{Name: "I.X", Value: "ten", NoIndex: false, Multiple: true},
1021 Property{Name: "I.W", Value: int64(20), NoIndex: false, Multiple: true},
1022 Property{Name: "I.X", Value: "twenty", NoIndex: false, Multiple: true},
1023 Property{Name: "I.W", Value: int64(30), NoIndex: false, Multiple: true},
1024 Property{Name: "I.X", Value: "thirty", NoIndex: false, Multiple: true},
1025 Property{Name: "J.Y", Value: float64(3.14), NoIndex: false, Multiple: false},
1026 Property{Name: "Z", Value: true, NoIndex: false, Multiple: false},
1027 },
1028 &OuterEquivalent{
1029 A: 1,
1030 IDotW: []int32{10, 20, 30},
1031 IDotX: []string{"ten", "twenty", "thirty"},
1032 JDotY: 3.14,
1033 Z: true,
1034 },
1035 "",
1036 "",
1037 },
1038 {
1039 "save outer-equivalent load outer",
1040 &OuterEquivalent{
1041 A: 1,
1042 IDotW: []int32{10, 20, 30},
1043 IDotX: []string{"ten", "twenty", "thirty"},
1044 JDotY: 3.14,
1045 Z: true,
1046 },
1047 &Outer{
1048 A: 1,
1049 I: []Inner1{
1050 {10, "ten"},
1051 {20, "twenty"},
1052 {30, "thirty"},
1053 },
1054 J: Inner2{
1055 Y: 3.14,
1056 },
1057 Inner3: Inner3{
1058 Z: true,
1059 },
1060 },
1061 "",
1062 "",
1063 },
1064 {
1065 "dotted names save",
1066 &Dotted{A: DottedA{B: DottedB{C: 88}}},
1067 &PropertyList{
1068 Property{Name: "A0.A1.A2.B3.C4.C5", Value: int64(88), NoIndex: false, Multiple: false},
1069 },
1070 "",
1071 "",
1072 },
1073 {
1074 "dotted names load",
1075 &PropertyList{
1076 Property{Name: "A0.A1.A2.B3.C4.C5", Value: int64(99), NoIndex: false, Multiple: false},
1077 },
1078 &Dotted{A: DottedA{B: DottedB{C: 99}}},
1079 "",
1080 "",
1081 },
1082 {
1083 "save struct load deriver",
1084 &X0{S: "s", I: 1},
1085 &Deriver{S: "s", Derived: "derived+s"},
1086 "",
1087 "",
1088 },
1089 {
1090 "save deriver load struct",
1091 &Deriver{S: "s", Derived: "derived+s", Ignored: "ignored"},
1092 &X0{S: "s"},
1093 "",
1094 "",
1095 },
1096 {
1097 "bad multi-prop entity",
1098 &BadMultiPropEntity{},
1099 &BadMultiPropEntity{},
1100 "Multiple is false",
1101 "",
1102 },
1103 // Regression: CL 25062824 broke handling of appengine.BlobKey fields.
1104 {
1105 "appengine.BlobKey",
1106 &BK{Key: "blah"},
1107 &BK{Key: "blah"},
1108 "",
1109 "",
1110 },
1111 {
1112 "zero time.Time",
1113 &T{T: time.Time{}},
1114 &T{T: time.Time{}},
1115 "",
1116 "",
1117 },
1118 {
1119 "time.Time near Unix zero time",
1120 &T{T: time.Unix(0, 4e3)},
1121 &T{T: time.Unix(0, 4e3)},
1122 "",
1123 "",
1124 },
1125 {
1126 "time.Time, far in the future",
1127 &T{T: time.Date(99999, 1, 1, 0, 0, 0, 0, time.UTC)},
1128 &T{T: time.Date(99999, 1, 1, 0, 0, 0, 0, time.UTC)},
1129 "",
1130 "",
1131 },
1132 {
1133 "time.Time, very far in the past",
1134 &T{T: time.Date(-300000, 1, 1, 0, 0, 0, 0, time.UTC)},
1135 &T{},
1136 "time value out of range",
1137 "",
1138 },
1139 {
1140 "time.Time, very far in the future",
1141 &T{T: time.Date(294248, 1, 1, 0, 0, 0, 0, time.UTC)},
1142 &T{},
1143 "time value out of range",
1144 "",
1145 },
1146 {
1147 "structs",
1148 &N0{
1149 X0: X0{S: "one", I: 2, i: 3},
1150 Nonymous: X0{S: "four", I: 5, i: 6},
1151 Ignore: "ignore",
1152 Other: "other",
1153 },
1154 &N0{
1155 X0: X0{S: "one", I: 2},
1156 Nonymous: X0{S: "four", I: 5},
1157 Other: "other",
1158 },
1159 "",
1160 "",
1161 },
1162 {
1163 "slice of structs",
1164 &N1{
1165 X0: X0{S: "one", I: 2, i: 3},
1166 Nonymous: []X0{
1167 {S: "four", I: 5, i: 6},
1168 {S: "seven", I: 8, i: 9},
1169 {S: "ten", I: 11, i: 12},
1170 {S: "thirteen", I: 14, i: 15},
1171 },
1172 Ignore: "ignore",
1173 Other: "other",
1174 },
1175 &N1{
1176 X0: X0{S: "one", I: 2},
1177 Nonymous: []X0{
1178 {S: "four", I: 5},
1179 {S: "seven", I: 8},
1180 {S: "ten", I: 11},
1181 {S: "thirteen", I: 14},
1182 },
1183 Other: "other",
1184 },
1185 "",
1186 "",
1187 },
1188 {
1189 "structs with slices of structs",
1190 &N2{
1191 N1: N1{
1192 X0: X0{S: "rouge"},
1193 Nonymous: []X0{
1194 {S: "rosso0"},
1195 {S: "rosso1"},
1196 },
1197 },
1198 Green: N1{
1199 X0: X0{S: "vert"},
1200 Nonymous: []X0{
1201 {S: "verde0"},
1202 {S: "verde1"},
1203 {S: "verde2"},
1204 },
1205 },
1206 Blue: N1{
1207 X0: X0{S: "bleu"},
1208 Nonymous: []X0{
1209 {S: "blu0"},
1210 {S: "blu1"},
1211 {S: "blu2"},
1212 {S: "blu3"},
1213 },
1214 },
1215 },
1216 &N2{
1217 N1: N1{
1218 X0: X0{S: "rouge"},
1219 Nonymous: []X0{
1220 {S: "rosso0"},
1221 {S: "rosso1"},
1222 },
1223 },
1224 Green: N1{
1225 X0: X0{S: "vert"},
1226 Nonymous: []X0{
1227 {S: "verde0"},
1228 {S: "verde1"},
1229 {S: "verde2"},
1230 },
1231 },
1232 Blue: N1{
1233 X0: X0{S: "bleu"},
1234 Nonymous: []X0{
1235 {S: "blu0"},
1236 {S: "blu1"},
1237 {S: "blu2"},
1238 {S: "blu3"},
1239 },
1240 },
1241 },
1242 "",
1243 "",
1244 },
1245 {
1246 "save structs load props",
1247 &N2{
1248 N1: N1{
1249 X0: X0{S: "rouge"},
1250 Nonymous: []X0{
1251 {S: "rosso0"},
1252 {S: "rosso1"},
1253 },
1254 },
1255 Green: N1{
1256 X0: X0{S: "vert"},
1257 Nonymous: []X0{
1258 {S: "verde0"},
1259 {S: "verde1"},
1260 {S: "verde2"},
1261 },
1262 },
1263 Blue: N1{
1264 X0: X0{S: "bleu"},
1265 Nonymous: []X0{
1266 {S: "blu0"},
1267 {S: "blu1"},
1268 {S: "blu2"},
1269 {S: "blu3"},
1270 },
1271 },
1272 },
1273 &PropertyList{
1274 Property{Name: "Blue.I", Value: int64(0), NoIndex: false, Multiple: false},
1275 Property{Name: "Blue.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1276 Property{Name: "Blue.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1277 Property{Name: "Blue.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1278 Property{Name: "Blue.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1279 Property{Name: "Blue.Nonymous.S", Value: "blu0", NoIndex: false, Multiple: true},
1280 Property{Name: "Blue.Nonymous.S", Value: "blu1", NoIndex: false, Multiple: true},
1281 Property{Name: "Blue.Nonymous.S", Value: "blu2", NoIndex: false, Multiple: true},
1282 Property{Name: "Blue.Nonymous.S", Value: "blu3", NoIndex: false, Multiple: true},
1283 Property{Name: "Blue.Other", Value: "", NoIndex: false, Multiple: false},
1284 Property{Name: "Blue.S", Value: "bleu", NoIndex: false, Multiple: false},
1285 Property{Name: "green.I", Value: int64(0), NoIndex: false, Multiple: false},
1286 Property{Name: "green.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1287 Property{Name: "green.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1288 Property{Name: "green.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1289 Property{Name: "green.Nonymous.S", Value: "verde0", NoIndex: false, Multiple: true},
1290 Property{Name: "green.Nonymous.S", Value: "verde1", NoIndex: false, Multiple: true},
1291 Property{Name: "green.Nonymous.S", Value: "verde2", NoIndex: false, Multiple: true},
1292 Property{Name: "green.Other", Value: "", NoIndex: false, Multiple: false},
1293 Property{Name: "green.S", Value: "vert", NoIndex: false, Multiple: false},
1294 Property{Name: "red.I", Value: int64(0), NoIndex: false, Multiple: false},
1295 Property{Name: "red.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1296 Property{Name: "red.Nonymous.I", Value: int64(0), NoIndex: false, Multiple: true},
1297 Property{Name: "red.Nonymous.S", Value: "rosso0", NoIndex: false, Multiple: true},
1298 Property{Name: "red.Nonymous.S", Value: "rosso1", NoIndex: false, Multiple: true},
1299 Property{Name: "red.Other", Value: "", NoIndex: false, Multiple: false},
1300 Property{Name: "red.S", Value: "rouge", NoIndex: false, Multiple: false},
1301 },
1302 "",
1303 "",
1304 },
1305 {
1306 "save props load structs with ragged fields",
1307 &PropertyList{
1308 Property{Name: "red.S", Value: "rot", NoIndex: false, Multiple: false},
1309 Property{Name: "green.Nonymous.I", Value: int64(10), NoIndex: false, Multiple: true},
1310 Property{Name: "green.Nonymous.I", Value: int64(11), NoIndex: false, Multiple: true},
1311 Property{Name: "green.Nonymous.I", Value: int64(12), NoIndex: false, Multiple: true},
1312 Property{Name: "green.Nonymous.I", Value: int64(13), NoIndex: false, Multiple: true},
1313 Property{Name: "Blue.Nonymous.S", Value: "blau0", NoIndex: false, Multiple: true},
1314 Property{Name: "Blue.Nonymous.I", Value: int64(20), NoIndex: false, Multiple: true},
1315 Property{Name: "Blue.Nonymous.S", Value: "blau1", NoIndex: false, Multiple: true},
1316 Property{Name: "Blue.Nonymous.I", Value: int64(21), NoIndex: false, Multiple: true},
1317 Property{Name: "Blue.Nonymous.S", Value: "blau2", NoIndex: false, Multiple: true},
1318 },
1319 &N2{
1320 N1: N1{
1321 X0: X0{S: "rot"},
1322 },
1323 Green: N1{
1324 Nonymous: []X0{
1325 {I: 10},
1326 {I: 11},
1327 {I: 12},
1328 {I: 13},
1329 },
1330 },
1331 Blue: N1{
1332 Nonymous: []X0{
1333 {S: "blau0", I: 20},
1334 {S: "blau1", I: 21},
1335 {S: "blau2"},
1336 },
1337 },
1338 },
1339 "",
1340 "",
1341 },
1342 {
1343 "save structs with noindex tags",
1344 &struct {
1345 A struct {
1346 X string `datastore:",noindex"`
1347 Y string
1348 } `datastore:",noindex"`
1349 B struct {
1350 X string `datastore:",noindex"`
1351 Y string
1352 }
1353 }{},
1354 &PropertyList{
1355 Property{Name: "A.X", Value: "", NoIndex: true, Multiple: false},
1356 Property{Name: "A.Y", Value: "", NoIndex: true, Multiple: false},
1357 Property{Name: "B.X", Value: "", NoIndex: true, Multiple: false},
1358 Property{Name: "B.Y", Value: "", NoIndex: false, Multiple: false},
1359 },
1360 "",
1361 "",
1362 },
1363 {
1364 "embedded struct with name override",
1365 &struct {
1366 Inner1 `datastore:"foo"`
1367 }{},
1368 &PropertyList{
1369 Property{Name: "foo.W", Value: int64(0), NoIndex: false, Multiple: false},
1370 Property{Name: "foo.X", Value: "", NoIndex: false, Multiple: false},
1371 },
1372 "",
1373 "",
1374 },
1375 {
1376 "slice of slices",
1377 &SliceOfSlices{},
1378 nil,
1379 "flattening nested structs leads to a slice of slices",
1380 "",
1381 },
1382 {
1383 "recursive struct",
1384 &Recursive{},
1385 nil,
1386 "recursive struct",
1387 "",
1388 },
1389 {
1390 "mutually recursive struct",
1391 &MutuallyRecursive0{},
1392 nil,
1393 "recursive struct",
1394 "",
1395 },
1396 {
1397 "non-exported struct fields",
1398 &struct {
1399 i, J int64
1400 }{i: 1, J: 2},
1401 &PropertyList{
1402 Property{Name: "J", Value: int64(2), NoIndex: false, Multiple: false},
1403 },
1404 "",
1405 "",
1406 },
1407 {
1408 "json.RawMessage",
1409 &struct {
1410 J json.RawMessage
1411 }{
1412 J: json.RawMessage("rawr"),
1413 },
1414 &PropertyList{
1415 Property{Name: "J", Value: []byte("rawr"), NoIndex: true, Multiple: false},
1416 },
1417 "",
1418 "",
1419 },
1420 {
1421 "json.RawMessage to myBlob",
1422 &struct {
1423 B json.RawMessage
1424 }{
1425 B: json.RawMessage("rawr"),
1426 },
1427 &B2{B: myBlob("rawr")},
1428 "",
1429 "",
1430 },
1431 {
1432 "embedded time field",
1433 &SpecialTime{MyTime: EmbeddedTime{now}},
1434 &SpecialTime{MyTime: EmbeddedTime{now}},
1435 "",
1436 "",
1437 },
1438 {
1439 "embedded time load",
1440 &PropertyList{
1441 Property{Name: "MyTime.", Value: now, NoIndex: false, Multiple: false},
1442 },
1443 &SpecialTime{MyTime: EmbeddedTime{now}},
1444 "",
1445 "",
1446 },
1447 }
1448
1449 // checkErr returns the empty string if either both want and err are zero,
1450 // or if want is a non-empty substring of err's string representation.
1451 func checkErr(want string, err error) string {
1452 if err != nil {
1453 got := err.Error()
1454 if want == "" || strings.Index(got, want) == -1 {
1455 return got
1456 }
1457 } else if want != "" {
1458 return fmt.Sprintf("want error %q", want)
1459 }
1460 return ""
1461 }
1462
1463 func TestRoundTrip(t *testing.T) {
1464 for _, tc := range testCases {
1465 p, err := saveEntity(testAppID, testKey0, tc.src)
1466 if s := checkErr(tc.putErr, err); s != "" {
1467 t.Errorf("%s: save: %s", tc.desc, s)
1468 continue
1469 }
1470 if p == nil {
1471 continue
1472 }
1473 var got interface{}
1474 if _, ok := tc.want.(*PropertyList); ok {
1475 got = new(PropertyList)
1476 } else {
1477 got = reflect.New(reflect.TypeOf(tc.want).Elem()).Interface()
1478 }
1479 err = loadEntity(got, p)
1480 if s := checkErr(tc.getErr, err); s != "" {
1481 t.Errorf("%s: load: %s", tc.desc, s)
1482 continue
1483 }
1484 if pl, ok := got.(*PropertyList); ok {
1485 // Sort by name to make sure we have a deterministic order.
1486 sort.Stable(byName(*pl))
1487 }
1488 equal := false
1489 if gotT, ok := got.(*T); ok {
1490 // Round tripping a time.Time can result in a different time.Location: Local instead of UTC.
1491 // We therefore test equality explicitly, instead of relying on reflect.DeepEqual.
1492 equal = gotT.T.Equal(tc.want.(*T).T)
1493 } else {
1494 equal = reflect.DeepEqual(got, tc.want)
1495 }
1496 if !equal {
1497 t.Errorf("%s: compare: got %v want %v", tc.desc, got, tc.want)
1498 continue
1499 }
1500 }
1501 }
1502
1503 type byName PropertyList
1504
1505 func (s byName) Len() int { return len(s) }
1506 func (s byName) Less(i, j int) bool { return s[i].Name < s[j].Name }
1507 func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
1508
1509 func TestQueryConstruction(t *testing.T) {
1510 tests := []struct {
1511 q, exp *Query
1512 err string
1513 }{
1514 {
1515 q: NewQuery("Foo"),
1516 exp: &Query{
1517 kind: "Foo",
1518 limit: -1,
1519 },
1520 },
1521 {
1522 // Regular filtered query with standard spacing.
1523 q: NewQuery("Foo").Filter("foo >", 7),
1524 exp: &Query{
1525 kind: "Foo",
1526 filter: []filter{
1527 {
1528 FieldName: "foo",
1529 Op: greaterThan,
1530 Value: 7,
1531 },
1532 },
1533 limit: -1,
1534 },
1535 },
1536 {
1537 // Filtered query with no spacing.
1538 q: NewQuery("Foo").Filter("foo=", 6),
1539 exp: &Query{
1540 kind: "Foo",
1541 filter: []filter{
1542 {
1543 FieldName: "foo",
1544 Op: equal,
1545 Value: 6,
1546 },
1547 },
1548 limit: -1,
1549 },
1550 },
1551 {
1552 // Filtered query with funky spacing.
1553 q: NewQuery("Foo").Filter(" foo< ", 8),
1554 exp: &Query{
1555 kind: "Foo",
1556 filter: []filter{
1557 {
1558 FieldName: "foo",
1559 Op: lessThan,
1560 Value: 8,
1561 },
1562 },
1563 limit: -1,
1564 },
1565 },
1566 {
1567 // Filtered query with multicharacter op.
1568 q: NewQuery("Foo").Filter("foo >=", 9),
1569 exp: &Query{
1570 kind: "Foo",
1571 filter: []filter{
1572 {
1573 FieldName: "foo",
1574 Op: greaterEq,
1575 Value: 9,
1576 },
1577 },
1578 limit: -1,
1579 },
1580 },
1581 {
1582 // Query with ordering.
1583 q: NewQuery("Foo").Order("bar"),
1584 exp: &Query{
1585 kind: "Foo",
1586 order: []order{
1587 {
1588 FieldName: "bar",
1589 Direction: ascending,
1590 },
1591 },
1592 limit: -1,
1593 },
1594 },
1595 {
1596 // Query with reverse ordering, and funky spacing.
1597 q: NewQuery("Foo").Order(" - bar"),
1598 exp: &Query{
1599 kind: "Foo",
1600 order: []order{
1601 {
1602 FieldName: "bar",
1603 Direction: descending,
1604 },
1605 },
1606 limit: -1,
1607 },
1608 },
1609 {
1610 // Query with an empty ordering.
1611 q: NewQuery("Foo").Order(""),
1612 err: "empty order",
1613 },
1614 {
1615 // Query with a + ordering.
1616 q: NewQuery("Foo").Order("+bar"),
1617 err: "invalid order",
1618 },
1619 }
1620 for i, test := range tests {
1621 if test.q.err != nil {
1622 got := test.q.err.Error()
1623 if !strings.Contains(got, test.err) {
1624 t.Errorf("%d: error mismatch: got %q want something containing %q", i, got, test.err)
1625 }
1626 continue
1627 }
1628 if !reflect.DeepEqual(test.q, test.exp) {
1629 t.Errorf("%d: mismatch: got %v want %v", i, test.q, test.exp)
1630 }
1631 }
1632 }
1633
1634 func TestStringMeaning(t *testing.T) {
1635 var xx [4]interface{}
1636 xx[0] = &struct {
1637 X string
1638 }{"xx0"}
1639 xx[1] = &struct {
1640 X string `datastore:",noindex"`
1641 }{"xx1"}
1642 xx[2] = &struct {
1643 X []byte
1644 }{[]byte("xx2")}
1645 xx[3] = &struct {
1646 X []byte `datastore:",noindex"`
1647 }{[]byte("xx3")}
1648
1649 indexed := [4]bool{
1650 true,
1651 false,
1652 false, // A []byte is always no-index.
1653 false,
1654 }
1655 want := [4]pb.Property_Meaning{
1656 pb.Property_NO_MEANING,
1657 pb.Property_TEXT,
1658 pb.Property_BLOB,
1659 pb.Property_BLOB,
1660 }
1661
1662 for i, x := range xx {
1663 props, err := SaveStruct(x)
1664 if err != nil {
1665 t.Errorf("i=%d: SaveStruct: %v", i, err)
1666 continue
1667 }
1668 e, err := propertiesToProto("appID", testKey0, props)
1669 if err != nil {
1670 t.Errorf("i=%d: propertiesToProto: %v", i, err)
1671 continue
1672 }
1673 var p *pb.Property
1674 switch {
1675 case indexed[i] && len(e.Property) == 1:
1676 p = e.Property[0]
1677 case !indexed[i] && len(e.RawProperty) == 1:
1678 p = e.RawProperty[0]
1679 default:
1680 t.Errorf("i=%d: EntityProto did not have expected property slice", i)
1681 continue
1682 }
1683 if got := p.GetMeaning(); got != want[i] {
1684 t.Errorf("i=%d: meaning: got %v, want %v", i, got, want[i])
1685 continue
1686 }
1687 }
1688 }
1689
1690 func TestNamespaceResetting(t *testing.T) {
1691 // These environment variables are necessary because *Query.Run will
1692 // call internal.FullyQualifiedAppID which checks these variables or falls
1693 // back to the Metadata service that is not available in tests.
1694 environ := []struct {
1695 key, value string
1696 }{
1697 {"GAE_LONG_APP_ID", "my-app-id"},
1698 {"GAE_PARTITION", "1"},
1699 }
1700 for _, v := range environ {
1701 old := os.Getenv(v.key)
1702 os.Setenv(v.key, v.value)
1703 v.value = old
1704 }
1705 defer func() { // Restore old environment after the test completes.
1706 for _, v := range environ {
1707 if v.value == "" {
1708 os.Unsetenv(v.key)
1709 continue
1710 }
1711 os.Setenv(v.key, v.value)
1712 }
1713 }()
1714
1715 namec := make(chan *string, 1)
1716 c0 := aetesting.FakeSingleContext(t, "datastore_v3", "RunQuery", func(req *pb.Query, res *pb.QueryResult) error {
1717 namec <- req.NameSpace
1718 return fmt.Errorf("RPC error")
1719 })
1720
1721 // Check that wrapping c0 in a namespace twice works correctly.
1722 c1, err := appengine.Namespace(c0, "A")
1723 if err != nil {
1724 t.Fatalf("appengine.Namespace: %v", err)
1725 }
1726 c2, err := appengine.Namespace(c1, "") // should act as the original context
1727 if err != nil {
1728 t.Fatalf("appengine.Namespace: %v", err)
1729 }
1730
1731 q := NewQuery("SomeKind")
1732
1733 q.Run(c0)
1734 if ns := <-namec; ns != nil {
1735 t.Errorf(`RunQuery with c0: ns = %q, want nil`, *ns)
1736 }
1737
1738 q.Run(c1)
1739 if ns := <-namec; ns == nil {
1740 t.Error(`RunQuery with c1: ns = nil, want "A"`)
1741 } else if *ns != "A" {
1742 t.Errorf(`RunQuery with c1: ns = %q, want "A"`, *ns)
1743 }
1744
1745 q.Run(c2)
1746 if ns := <-namec; ns != nil {
1747 t.Errorf(`RunQuery with c2: ns = %q, want nil`, *ns)
1748 }
1749 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 /*
5 Package datastore provides a client for App Engine's datastore service.
6
7 # Basic Operations
8
9 Entities are the unit of storage and are associated with a key. A key
10 consists of an optional parent key, a string application ID, a string kind
11 (also known as an entity type), and either a StringID or an IntID. A
12 StringID is also known as an entity name or key name.
13
14 It is valid to create a key with a zero StringID and a zero IntID; this is
15 called an incomplete key, and does not refer to any saved entity. Putting an
16 entity into the datastore under an incomplete key will cause a unique key
17 to be generated for that entity, with a non-zero IntID.
18
19 An entity's contents are a mapping from case-sensitive field names to values.
20 Valid value types are:
21 - signed integers (int, int8, int16, int32 and int64),
22 - bool,
23 - string,
24 - float32 and float64,
25 - []byte (up to 1 megabyte in length),
26 - any type whose underlying type is one of the above predeclared types,
27 - ByteString,
28 - *Key,
29 - time.Time (stored with microsecond precision),
30 - appengine.BlobKey,
31 - appengine.GeoPoint,
32 - structs whose fields are all valid value types,
33 - slices of any of the above.
34
35 Slices of structs are valid, as are structs that contain slices. However, if
36 one struct contains another, then at most one of those can be repeated. This
37 disqualifies recursively defined struct types: any struct T that (directly or
38 indirectly) contains a []T.
39
40 The Get and Put functions load and save an entity's contents. An entity's
41 contents are typically represented by a struct pointer.
42
43 Example code:
44
45 type Entity struct {
46 Value string
47 }
48
49 func handle(w http.ResponseWriter, r *http.Request) {
50 ctx := appengine.NewContext(r)
51
52 k := datastore.NewKey(ctx, "Entity", "stringID", 0, nil)
53 e := new(Entity)
54 if err := datastore.Get(ctx, k, e); err != nil {
55 http.Error(w, err.Error(), 500)
56 return
57 }
58
59 old := e.Value
60 e.Value = r.URL.Path
61
62 if _, err := datastore.Put(ctx, k, e); err != nil {
63 http.Error(w, err.Error(), 500)
64 return
65 }
66
67 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
68 fmt.Fprintf(w, "old=%q\nnew=%q\n", old, e.Value)
69 }
70
71 GetMulti, PutMulti and DeleteMulti are batch versions of the Get, Put and
72 Delete functions. They take a []*Key instead of a *Key, and may return an
73 appengine.MultiError when encountering partial failure.
74
75 # Properties
76
77 An entity's contents can be represented by a variety of types. These are
78 typically struct pointers, but can also be any type that implements the
79 PropertyLoadSaver interface. If using a struct pointer, you do not have to
80 explicitly implement the PropertyLoadSaver interface; the datastore will
81 automatically convert via reflection. If a struct pointer does implement that
82 interface then those methods will be used in preference to the default
83 behavior for struct pointers. Struct pointers are more strongly typed and are
84 easier to use; PropertyLoadSavers are more flexible.
85
86 The actual types passed do not have to match between Get and Put calls or even
87 across different calls to datastore. It is valid to put a *PropertyList and
88 get that same entity as a *myStruct, or put a *myStruct0 and get a *myStruct1.
89 Conceptually, any entity is saved as a sequence of properties, and is loaded
90 into the destination value on a property-by-property basis. When loading into
91 a struct pointer, an entity that cannot be completely represented (such as a
92 missing field) will result in an ErrFieldMismatch error but it is up to the
93 caller whether this error is fatal, recoverable or ignorable.
94
95 By default, for struct pointers, all properties are potentially indexed, and
96 the property name is the same as the field name (and hence must start with an
97 upper case letter).
98
99 Fields may have a `datastore:"name,options"` tag. The tag name is the
100 property name, which must be one or more valid Go identifiers joined by ".",
101 but may start with a lower case letter. An empty tag name means to just use the
102 field name. A "-" tag name means that the datastore will ignore that field.
103
104 The only valid options are "omitempty" and "noindex".
105
106 If the options include "omitempty" and the value of the field is empty, then the field will be omitted on Save.
107 The empty values are false, 0, any nil interface value, and any array, slice, map, or string of length zero.
108 Struct field values will never be empty.
109
110 If options include "noindex" then the field will not be indexed. All fields are indexed
111 by default. Strings or byte slices longer than 1500 bytes cannot be indexed;
112 fields used to store long strings and byte slices must be tagged with "noindex"
113 or they will cause Put operations to fail.
114
115 To use multiple options together, separate them by a comma.
116 The order does not matter.
117
118 If the options is "" then the comma may be omitted.
119
120 Example code:
121
122 // A and B are renamed to a and b.
123 // A, C and J are not indexed.
124 // D's tag is equivalent to having no tag at all (E).
125 // I is ignored entirely by the datastore.
126 // J has tag information for both the datastore and json packages.
127 type TaggedStruct struct {
128 A int `datastore:"a,noindex"`
129 B int `datastore:"b"`
130 C int `datastore:",noindex"`
131 D int `datastore:""`
132 E int
133 I int `datastore:"-"`
134 J int `datastore:",noindex" json:"j"`
135 }
136
137 # Structured Properties
138
139 If the struct pointed to contains other structs, then the nested or embedded
140 structs are flattened. For example, given these definitions:
141
142 type Inner1 struct {
143 W int32
144 X string
145 }
146
147 type Inner2 struct {
148 Y float64
149 }
150
151 type Inner3 struct {
152 Z bool
153 }
154
155 type Outer struct {
156 A int16
157 I []Inner1
158 J Inner2
159 Inner3
160 }
161
162 then an Outer's properties would be equivalent to those of:
163
164 type OuterEquivalent struct {
165 A int16
166 IDotW []int32 `datastore:"I.W"`
167 IDotX []string `datastore:"I.X"`
168 JDotY float64 `datastore:"J.Y"`
169 Z bool
170 }
171
172 If Outer's embedded Inner3 field was tagged as `datastore:"Foo"` then the
173 equivalent field would instead be: FooDotZ bool `datastore:"Foo.Z"`.
174
175 If an outer struct is tagged "noindex" then all of its implicit flattened
176 fields are effectively "noindex".
177
178 # The PropertyLoadSaver Interface
179
180 An entity's contents can also be represented by any type that implements the
181 PropertyLoadSaver interface. This type may be a struct pointer, but it does
182 not have to be. The datastore package will call Load when getting the entity's
183 contents, and Save when putting the entity's contents.
184 Possible uses include deriving non-stored fields, verifying fields, or indexing
185 a field only if its value is positive.
186
187 Example code:
188
189 type CustomPropsExample struct {
190 I, J int
191 // Sum is not stored, but should always be equal to I + J.
192 Sum int `datastore:"-"`
193 }
194
195 func (x *CustomPropsExample) Load(ps []datastore.Property) error {
196 // Load I and J as usual.
197 if err := datastore.LoadStruct(x, ps); err != nil {
198 return err
199 }
200 // Derive the Sum field.
201 x.Sum = x.I + x.J
202 return nil
203 }
204
205 func (x *CustomPropsExample) Save() ([]datastore.Property, error) {
206 // Validate the Sum field.
207 if x.Sum != x.I + x.J {
208 return nil, errors.New("CustomPropsExample has inconsistent sum")
209 }
210 // Save I and J as usual. The code below is equivalent to calling
211 // "return datastore.SaveStruct(x)", but is done manually for
212 // demonstration purposes.
213 return []datastore.Property{
214 {
215 Name: "I",
216 Value: int64(x.I),
217 },
218 {
219 Name: "J",
220 Value: int64(x.J),
221 },
222 }, nil
223 }
224
225 The *PropertyList type implements PropertyLoadSaver, and can therefore hold an
226 arbitrary entity's contents.
227
228 # Queries
229
230 Queries retrieve entities based on their properties or key's ancestry. Running
231 a query yields an iterator of results: either keys or (key, entity) pairs.
232 Queries are re-usable and it is safe to call Query.Run from concurrent
233 goroutines. Iterators are not safe for concurrent use.
234
235 Queries are immutable, and are either created by calling NewQuery, or derived
236 from an existing query by calling a method like Filter or Order that returns a
237 new query value. A query is typically constructed by calling NewQuery followed
238 by a chain of zero or more such methods. These methods are:
239 - Ancestor and Filter constrain the entities returned by running a query.
240 - Order affects the order in which they are returned.
241 - Project constrains the fields returned.
242 - Distinct de-duplicates projected entities.
243 - KeysOnly makes the iterator return only keys, not (key, entity) pairs.
244 - Start, End, Offset and Limit define which sub-sequence of matching entities
245 to return. Start and End take cursors, Offset and Limit take integers. Start
246 and Offset affect the first result, End and Limit affect the last result.
247 If both Start and Offset are set, then the offset is relative to Start.
248 If both End and Limit are set, then the earliest constraint wins. Limit is
249 relative to Start+Offset, not relative to End. As a special case, a
250 negative limit means unlimited.
251
252 Example code:
253
254 type Widget struct {
255 Description string
256 Price int
257 }
258
259 func handle(w http.ResponseWriter, r *http.Request) {
260 ctx := appengine.NewContext(r)
261 q := datastore.NewQuery("Widget").
262 Filter("Price <", 1000).
263 Order("-Price")
264 b := new(bytes.Buffer)
265 for t := q.Run(ctx); ; {
266 var x Widget
267 key, err := t.Next(&x)
268 if err == datastore.Done {
269 break
270 }
271 if err != nil {
272 serveError(ctx, w, err)
273 return
274 }
275 fmt.Fprintf(b, "Key=%v\nWidget=%#v\n\n", key, x)
276 }
277 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
278 io.Copy(w, b)
279 }
280
281 # Transactions
282
283 RunInTransaction runs a function in a transaction.
284
285 Example code:
286
287 type Counter struct {
288 Count int
289 }
290
291 func inc(ctx context.Context, key *datastore.Key) (int, error) {
292 var x Counter
293 if err := datastore.Get(ctx, key, &x); err != nil && err != datastore.ErrNoSuchEntity {
294 return 0, err
295 }
296 x.Count++
297 if _, err := datastore.Put(ctx, key, &x); err != nil {
298 return 0, err
299 }
300 return x.Count, nil
301 }
302
303 func handle(w http.ResponseWriter, r *http.Request) {
304 ctx := appengine.NewContext(r)
305 var count int
306 err := datastore.RunInTransaction(ctx, func(ctx context.Context) error {
307 var err1 error
308 count, err1 = inc(ctx, datastore.NewKey(ctx, "Counter", "singleton", 0, nil))
309 return err1
310 }, nil)
311 if err != nil {
312 serveError(ctx, w, err)
313 return
314 }
315 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
316 fmt.Fprintf(w, "Count=%d", count)
317 }
318
319 # Metadata
320
321 The datastore package provides access to some of App Engine's datastore
322 metadata. This metadata includes information about the entity groups,
323 namespaces, entity kinds, and properties in the datastore, as well as the
324 property representations for each property.
325
326 Example code:
327
328 func handle(w http.ResponseWriter, r *http.Request) {
329 // Print all the kinds in the datastore, with all the indexed
330 // properties (and their representations) for each.
331 ctx := appengine.NewContext(r)
332
333 kinds, err := datastore.Kinds(ctx)
334 if err != nil {
335 serveError(ctx, w, err)
336 return
337 }
338
339 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
340 for _, kind := range kinds {
341 fmt.Fprintf(w, "%s:\n", kind)
342 props, err := datastore.KindProperties(ctx, kind)
343 if err != nil {
344 fmt.Fprintln(w, "\t(unable to retrieve properties)")
345 continue
346 }
347 for p, rep := range props {
348 fmt.Fprintf(w, "\t-%s (%s)\n", p, strings.Join(rep, ", "))
349 }
350 }
351 }
352 */
353 package datastore // import "google.golang.org/appengine/v2/datastore"
0 // Copyright 2019 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package cloudpb is a subset of types and functions, copied from cloud.google.com/go/datastore.
5 //
6 // They are copied here to provide compatibility to decode keys generated by the cloud.google.com/go/datastore package.
7 package cloudkey
8
9 import (
10 "encoding/base64"
11 "errors"
12 "strings"
13
14 "github.com/golang/protobuf/proto"
15 cloudpb "google.golang.org/appengine/v2/datastore/internal/cloudpb"
16 )
17
18 /////////////////////////////////////////////////////////////////////
19 // Code below is copied from https://github.com/googleapis/google-cloud-go/blob/master/datastore/datastore.go
20 /////////////////////////////////////////////////////////////////////
21
22 var (
23 // ErrInvalidKey is returned when an invalid key is presented.
24 ErrInvalidKey = errors.New("datastore: invalid key")
25 )
26
27 /////////////////////////////////////////////////////////////////////
28 // Code below is copied from https://github.com/googleapis/google-cloud-go/blob/master/datastore/key.go
29 /////////////////////////////////////////////////////////////////////
30
31 // Key represents the datastore key for a stored entity.
32 type Key struct {
33 // Kind cannot be empty.
34 Kind string
35 // Either ID or Name must be zero for the Key to be valid.
36 // If both are zero, the Key is incomplete.
37 ID int64
38 Name string
39 // Parent must either be a complete Key or nil.
40 Parent *Key
41
42 // Namespace provides the ability to partition your data for multiple
43 // tenants. In most cases, it is not necessary to specify a namespace.
44 // See docs on datastore multitenancy for details:
45 // https://cloud.google.com/datastore/docs/concepts/multitenancy
46 Namespace string
47 }
48
49 // DecodeKey decodes a key from the opaque representation returned by Encode.
50 func DecodeKey(encoded string) (*Key, error) {
51 // Re-add padding.
52 if m := len(encoded) % 4; m != 0 {
53 encoded += strings.Repeat("=", 4-m)
54 }
55
56 b, err := base64.URLEncoding.DecodeString(encoded)
57 if err != nil {
58 return nil, err
59 }
60
61 pKey := new(cloudpb.Key)
62 if err := proto.Unmarshal(b, pKey); err != nil {
63 return nil, err
64 }
65 return protoToKey(pKey)
66 }
67
68 // valid returns whether the key is valid.
69 func (k *Key) valid() bool {
70 if k == nil {
71 return false
72 }
73 for ; k != nil; k = k.Parent {
74 if k.Kind == "" {
75 return false
76 }
77 if k.Name != "" && k.ID != 0 {
78 return false
79 }
80 if k.Parent != nil {
81 if k.Parent.Incomplete() {
82 return false
83 }
84 if k.Parent.Namespace != k.Namespace {
85 return false
86 }
87 }
88 }
89 return true
90 }
91
92 // Incomplete reports whether the key does not refer to a stored entity.
93 func (k *Key) Incomplete() bool {
94 return k.Name == "" && k.ID == 0
95 }
96
97 // protoToKey decodes a protocol buffer representation of a key into an
98 // equivalent *Key object. If the key is invalid, protoToKey will return the
99 // invalid key along with ErrInvalidKey.
100 func protoToKey(p *cloudpb.Key) (*Key, error) {
101 var key *Key
102 var namespace string
103 if partition := p.PartitionId; partition != nil {
104 namespace = partition.NamespaceId
105 }
106 for _, el := range p.Path {
107 key = &Key{
108 Namespace: namespace,
109 Kind: el.Kind,
110 ID: el.GetId(),
111 Name: el.GetName(),
112 Parent: key,
113 }
114 }
115 if !key.valid() { // Also detects key == nil.
116 return key, ErrInvalidKey
117 }
118 return key, nil
119 }
0 // Copyright 2019 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package cloudpb is a subset of protobufs, copied from google.golang.org/genproto/googleapis/datastore/v1.
5 //
6 // They are copied here to provide compatibility to decode keys generated by the cloud.google.com/go/datastore package.
7 package cloudpb
8
9 import (
10 "fmt"
11
12 "github.com/golang/protobuf/proto"
13 )
14
15 // A partition ID identifies a grouping of entities. The grouping is always
16 // by project and namespace, however the namespace ID may be empty.
17 //
18 // A partition ID contains several dimensions:
19 // project ID and namespace ID.
20 //
21 // Partition dimensions:
22 //
23 // - May be `""`.
24 // - Must be valid UTF-8 bytes.
25 // - Must have values that match regex `[A-Za-z\d\.\-_]{1,100}`
26 // If the value of any dimension matches regex `__.*__`, the partition is
27 // reserved/read-only.
28 // A reserved/read-only partition ID is forbidden in certain documented
29 // contexts.
30 //
31 // Foreign partition IDs (in which the project ID does
32 // not match the context project ID ) are discouraged.
33 // Reads and writes of foreign partition IDs may fail if the project is not in
34 // an active state.
35 type PartitionId struct {
36 // The ID of the project to which the entities belong.
37 ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"`
38 // If not empty, the ID of the namespace to which the entities belong.
39 NamespaceId string `protobuf:"bytes,4,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"`
40 XXX_NoUnkeyedLiteral struct{} `json:"-"`
41 XXX_unrecognized []byte `json:"-"`
42 XXX_sizecache int32 `json:"-"`
43 }
44
45 func (m *PartitionId) Reset() { *m = PartitionId{} }
46 func (m *PartitionId) String() string { return proto.CompactTextString(m) }
47 func (*PartitionId) ProtoMessage() {}
48 func (*PartitionId) Descriptor() ([]byte, []int) {
49 return fileDescriptor_entity_096a297364b049a5, []int{0}
50 }
51 func (m *PartitionId) XXX_Unmarshal(b []byte) error {
52 return xxx_messageInfo_PartitionId.Unmarshal(m, b)
53 }
54 func (m *PartitionId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
55 return xxx_messageInfo_PartitionId.Marshal(b, m, deterministic)
56 }
57 func (dst *PartitionId) XXX_Merge(src proto.Message) {
58 xxx_messageInfo_PartitionId.Merge(dst, src)
59 }
60 func (m *PartitionId) XXX_Size() int {
61 return xxx_messageInfo_PartitionId.Size(m)
62 }
63 func (m *PartitionId) XXX_DiscardUnknown() {
64 xxx_messageInfo_PartitionId.DiscardUnknown(m)
65 }
66
67 var xxx_messageInfo_PartitionId proto.InternalMessageInfo
68
69 func (m *PartitionId) GetProjectId() string {
70 if m != nil {
71 return m.ProjectId
72 }
73 return ""
74 }
75
76 func (m *PartitionId) GetNamespaceId() string {
77 if m != nil {
78 return m.NamespaceId
79 }
80 return ""
81 }
82
83 // A unique identifier for an entity.
84 // If a key's partition ID or any of its path kinds or names are
85 // reserved/read-only, the key is reserved/read-only.
86 // A reserved/read-only key is forbidden in certain documented contexts.
87 type Key struct {
88 // Entities are partitioned into subsets, currently identified by a project
89 // ID and namespace ID.
90 // Queries are scoped to a single partition.
91 PartitionId *PartitionId `protobuf:"bytes,1,opt,name=partition_id,json=partitionId,proto3" json:"partition_id,omitempty"`
92 // The entity path.
93 // An entity path consists of one or more elements composed of a kind and a
94 // string or numerical identifier, which identify entities. The first
95 // element identifies a _root entity_, the second element identifies
96 // a _child_ of the root entity, the third element identifies a child of the
97 // second entity, and so forth. The entities identified by all prefixes of
98 // the path are called the element's _ancestors_.
99 //
100 // An entity path is always fully complete: *all* of the entity's ancestors
101 // are required to be in the path along with the entity identifier itself.
102 // The only exception is that in some documented cases, the identifier in the
103 // last path element (for the entity) itself may be omitted. For example,
104 // the last path element of the key of `Mutation.insert` may have no
105 // identifier.
106 //
107 // A path can never be empty, and a path can have at most 100 elements.
108 Path []*Key_PathElement `protobuf:"bytes,2,rep,name=path,proto3" json:"path,omitempty"`
109 XXX_NoUnkeyedLiteral struct{} `json:"-"`
110 XXX_unrecognized []byte `json:"-"`
111 XXX_sizecache int32 `json:"-"`
112 }
113
114 func (m *Key) Reset() { *m = Key{} }
115 func (m *Key) String() string { return proto.CompactTextString(m) }
116 func (*Key) ProtoMessage() {}
117 func (*Key) Descriptor() ([]byte, []int) {
118 return fileDescriptor_entity_096a297364b049a5, []int{1}
119 }
120 func (m *Key) XXX_Unmarshal(b []byte) error {
121 return xxx_messageInfo_Key.Unmarshal(m, b)
122 }
123 func (m *Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
124 return xxx_messageInfo_Key.Marshal(b, m, deterministic)
125 }
126 func (dst *Key) XXX_Merge(src proto.Message) {
127 xxx_messageInfo_Key.Merge(dst, src)
128 }
129 func (m *Key) XXX_Size() int {
130 return xxx_messageInfo_Key.Size(m)
131 }
132 func (m *Key) XXX_DiscardUnknown() {
133 xxx_messageInfo_Key.DiscardUnknown(m)
134 }
135
136 // A (kind, ID/name) pair used to construct a key path.
137 //
138 // If either name or ID is set, the element is complete.
139 // If neither is set, the element is incomplete.
140 type Key_PathElement struct {
141 // The kind of the entity.
142 // A kind matching regex `__.*__` is reserved/read-only.
143 // A kind must not contain more than 1500 bytes when UTF-8 encoded.
144 // Cannot be `""`.
145 Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"`
146 // The type of ID.
147 //
148 // Types that are valid to be assigned to IdType:
149 // *Key_PathElement_Id
150 // *Key_PathElement_Name
151 IdType isKey_PathElement_IdType `protobuf_oneof:"id_type"`
152 XXX_NoUnkeyedLiteral struct{} `json:"-"`
153 XXX_unrecognized []byte `json:"-"`
154 XXX_sizecache int32 `json:"-"`
155 }
156
157 func (m *Key_PathElement) Reset() { *m = Key_PathElement{} }
158 func (m *Key_PathElement) String() string { return proto.CompactTextString(m) }
159 func (*Key_PathElement) ProtoMessage() {}
160 func (*Key_PathElement) Descriptor() ([]byte, []int) {
161 return fileDescriptor_entity_096a297364b049a5, []int{1, 0}
162 }
163 func (m *Key_PathElement) XXX_Unmarshal(b []byte) error {
164 return xxx_messageInfo_Key_PathElement.Unmarshal(m, b)
165 }
166 func (m *Key_PathElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
167 return xxx_messageInfo_Key_PathElement.Marshal(b, m, deterministic)
168 }
169 func (dst *Key_PathElement) XXX_Merge(src proto.Message) {
170 xxx_messageInfo_Key_PathElement.Merge(dst, src)
171 }
172 func (m *Key_PathElement) XXX_Size() int {
173 return xxx_messageInfo_Key_PathElement.Size(m)
174 }
175 func (m *Key_PathElement) XXX_DiscardUnknown() {
176 xxx_messageInfo_Key_PathElement.DiscardUnknown(m)
177 }
178
179 var xxx_messageInfo_Key_PathElement proto.InternalMessageInfo
180
181 func (m *Key_PathElement) GetKind() string {
182 if m != nil {
183 return m.Kind
184 }
185 return ""
186 }
187
188 type isKey_PathElement_IdType interface {
189 isKey_PathElement_IdType()
190 }
191
192 type Key_PathElement_Id struct {
193 Id int64 `protobuf:"varint,2,opt,name=id,proto3,oneof"`
194 }
195
196 type Key_PathElement_Name struct {
197 Name string `protobuf:"bytes,3,opt,name=name,proto3,oneof"`
198 }
199
200 func (*Key_PathElement_Id) isKey_PathElement_IdType() {}
201
202 func (*Key_PathElement_Name) isKey_PathElement_IdType() {}
203
204 func (m *Key_PathElement) GetIdType() isKey_PathElement_IdType {
205 if m != nil {
206 return m.IdType
207 }
208 return nil
209 }
210
211 func (m *Key_PathElement) GetId() int64 {
212 if x, ok := m.GetIdType().(*Key_PathElement_Id); ok {
213 return x.Id
214 }
215 return 0
216 }
217
218 func (m *Key_PathElement) GetName() string {
219 if x, ok := m.GetIdType().(*Key_PathElement_Name); ok {
220 return x.Name
221 }
222 return ""
223 }
224
225 // XXX_OneofFuncs is for the internal use of the proto package.
226 func (*Key_PathElement) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
227 return _Key_PathElement_OneofMarshaler, _Key_PathElement_OneofUnmarshaler, _Key_PathElement_OneofSizer, []interface{}{
228 (*Key_PathElement_Id)(nil),
229 (*Key_PathElement_Name)(nil),
230 }
231 }
232
233 func _Key_PathElement_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
234 m := msg.(*Key_PathElement)
235 // id_type
236 switch x := m.IdType.(type) {
237 case *Key_PathElement_Id:
238 b.EncodeVarint(2<<3 | proto.WireVarint)
239 b.EncodeVarint(uint64(x.Id))
240 case *Key_PathElement_Name:
241 b.EncodeVarint(3<<3 | proto.WireBytes)
242 b.EncodeStringBytes(x.Name)
243 case nil:
244 default:
245 return fmt.Errorf("Key_PathElement.IdType has unexpected type %T", x)
246 }
247 return nil
248 }
249
250 func _Key_PathElement_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
251 m := msg.(*Key_PathElement)
252 switch tag {
253 case 2: // id_type.id
254 if wire != proto.WireVarint {
255 return true, proto.ErrInternalBadWireType
256 }
257 x, err := b.DecodeVarint()
258 m.IdType = &Key_PathElement_Id{int64(x)}
259 return true, err
260 case 3: // id_type.name
261 if wire != proto.WireBytes {
262 return true, proto.ErrInternalBadWireType
263 }
264 x, err := b.DecodeStringBytes()
265 m.IdType = &Key_PathElement_Name{x}
266 return true, err
267 default:
268 return false, nil
269 }
270 }
271
272 func _Key_PathElement_OneofSizer(msg proto.Message) (n int) {
273 m := msg.(*Key_PathElement)
274 // id_type
275 switch x := m.IdType.(type) {
276 case *Key_PathElement_Id:
277 n += 1 // tag and wire
278 n += proto.SizeVarint(uint64(x.Id))
279 case *Key_PathElement_Name:
280 n += 1 // tag and wire
281 n += proto.SizeVarint(uint64(len(x.Name)))
282 n += len(x.Name)
283 case nil:
284 default:
285 panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
286 }
287 return n
288 }
289
290 var fileDescriptor_entity_096a297364b049a5 = []byte{
291 // 780 bytes of a gzipped FileDescriptorProto
292 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xff, 0x6e, 0xdc, 0x44,
293 0x10, 0xc7, 0xed, 0xbb, 0x5c, 0x1a, 0x8f, 0xdd, 0xa4, 0x6c, 0x2a, 0x61, 0x02, 0x28, 0x26, 0x80,
294 0x74, 0x02, 0xc9, 0x6e, 0xc2, 0x1f, 0x54, 0x14, 0xa4, 0x72, 0x25, 0xe0, 0x28, 0x15, 0x9c, 0x56,
295 0x55, 0x24, 0x50, 0xa4, 0xd3, 0xde, 0x79, 0xeb, 0x2e, 0x67, 0xef, 0x5a, 0xf6, 0x3a, 0xaa, 0xdf,
296 0x05, 0xf1, 0x00, 0x3c, 0x0a, 0x8f, 0x80, 0x78, 0x18, 0xb4, 0x3f, 0xec, 0x0b, 0xed, 0x35, 0xff,
297 0x79, 0x67, 0x3e, 0xdf, 0xd9, 0xef, 0xec, 0xce, 0x1a, 0xa2, 0x5c, 0x88, 0xbc, 0xa0, 0x49, 0x46,
298 0x24, 0x69, 0xa4, 0xa8, 0x69, 0x72, 0x73, 0x9a, 0x50, 0x2e, 0x99, 0xec, 0xe2, 0xaa, 0x16, 0x52,
299 0xa0, 0x43, 0x43, 0xc4, 0x03, 0x11, 0xdf, 0x9c, 0x1e, 0x7d, 0x64, 0x65, 0xa4, 0x62, 0x09, 0xe1,
300 0x5c, 0x48, 0x22, 0x99, 0xe0, 0x8d, 0x91, 0x0c, 0x59, 0xbd, 0x5a, 0xb6, 0x2f, 0x93, 0x46, 0xd6,
301 0xed, 0x4a, 0xda, 0xec, 0xf1, 0x9b, 0x59, 0xc9, 0x4a, 0xda, 0x48, 0x52, 0x56, 0x16, 0x08, 0x2d,
302 0x20, 0xbb, 0x8a, 0x26, 0x05, 0x91, 0x05, 0xcf, 0x4d, 0xe6, 0xe4, 0x17, 0xf0, 0xe7, 0xa4, 0x96,
303 0x4c, 0x6d, 0x76, 0x91, 0xa1, 0x8f, 0x01, 0xaa, 0x5a, 0xfc, 0x4e, 0x57, 0x72, 0xc1, 0xb2, 0x70,
304 0x14, 0xb9, 0x53, 0x0f, 0x7b, 0x36, 0x72, 0x91, 0xa1, 0x4f, 0x20, 0xe0, 0xa4, 0xa4, 0x4d, 0x45,
305 0x56, 0x54, 0x01, 0x3b, 0x1a, 0xf0, 0x87, 0xd8, 0x45, 0x76, 0xf2, 0x8f, 0x0b, 0xe3, 0x4b, 0xda,
306 0xa1, 0x67, 0x10, 0x54, 0x7d, 0x61, 0x85, 0xba, 0x91, 0x3b, 0xf5, 0xcf, 0xa2, 0x78, 0x4b, 0xef,
307 0xf1, 0x2d, 0x07, 0xd8, 0xaf, 0x6e, 0xd9, 0x79, 0x0c, 0x3b, 0x15, 0x91, 0xaf, 0xc2, 0x51, 0x34,
308 0x9e, 0xfa, 0x67, 0x9f, 0x6d, 0x15, 0x5f, 0xd2, 0x2e, 0x9e, 0x13, 0xf9, 0xea, 0xbc, 0xa0, 0x25,
309 0xe5, 0x12, 0x6b, 0xc5, 0xd1, 0x0b, 0xd5, 0xd7, 0x10, 0x44, 0x08, 0x76, 0xd6, 0x8c, 0x1b, 0x17,
310 0x1e, 0xd6, 0xdf, 0xe8, 0x01, 0x8c, 0x6c, 0x8f, 0xe3, 0xd4, 0xc1, 0x23, 0x96, 0xa1, 0x87, 0xb0,
311 0xa3, 0x5a, 0x09, 0xc7, 0x8a, 0x4a, 0x1d, 0xac, 0x57, 0x33, 0x0f, 0xee, 0xb1, 0x6c, 0xa1, 0x8e,
312 0xee, 0xe4, 0x29, 0xc0, 0xf7, 0x75, 0x4d, 0xba, 0x2b, 0x52, 0xb4, 0x14, 0x9d, 0xc1, 0xee, 0x8d,
313 0xfa, 0x68, 0x42, 0x57, 0xfb, 0x3b, 0xda, 0xea, 0x4f, 0xb3, 0xd8, 0x92, 0x27, 0x7f, 0x4c, 0x60,
314 0x62, 0xd4, 0x4f, 0x00, 0x78, 0x5b, 0x14, 0x0b, 0x9d, 0x08, 0xfd, 0xc8, 0x9d, 0xee, 0x6f, 0x2a,
315 0xf4, 0x37, 0x19, 0xff, 0xdc, 0x16, 0x85, 0xe6, 0x53, 0x07, 0x7b, 0xbc, 0x5f, 0xa0, 0xcf, 0xe1,
316 0xfe, 0x52, 0x88, 0x82, 0x12, 0x6e, 0xf5, 0xaa, 0xb1, 0xbd, 0xd4, 0xc1, 0x81, 0x0d, 0x0f, 0x18,
317 0xe3, 0x92, 0xe6, 0xb4, 0xb6, 0x58, 0xdf, 0x6d, 0x60, 0xc3, 0x06, 0xfb, 0x14, 0x82, 0x4c, 0xb4,
318 0xcb, 0x82, 0x5a, 0x4a, 0xf5, 0xef, 0xa6, 0x0e, 0xf6, 0x4d, 0xd4, 0x40, 0xe7, 0x70, 0x30, 0x8c,
319 0x95, 0xe5, 0x40, 0xdf, 0xe9, 0xdb, 0xa6, 0x5f, 0xf4, 0x5c, 0xea, 0xe0, 0xfd, 0x41, 0x64, 0xca,
320 0x7c, 0x0d, 0xde, 0x9a, 0x76, 0xb6, 0xc0, 0x44, 0x17, 0x08, 0xdf, 0x75, 0xaf, 0xa9, 0x83, 0xf7,
321 0xd6, 0xb4, 0x1b, 0x4c, 0x36, 0xb2, 0x66, 0x3c, 0xb7, 0xda, 0xf7, 0xec, 0x25, 0xf9, 0x26, 0x6a,
322 0xa0, 0x63, 0x80, 0x65, 0x21, 0x96, 0x16, 0x41, 0x91, 0x3b, 0x0d, 0xd4, 0xc1, 0xa9, 0x98, 0x01,
323 0xbe, 0x83, 0x83, 0x9c, 0x8a, 0x45, 0x25, 0x18, 0x97, 0x96, 0xda, 0xd3, 0x26, 0x0e, 0x7b, 0x13,
324 0xea, 0xa2, 0xe3, 0xe7, 0x44, 0x3e, 0xe7, 0x79, 0xea, 0xe0, 0xfb, 0x39, 0x15, 0x73, 0x05, 0x1b,
325 0xf9, 0x53, 0x08, 0xcc, 0x53, 0xb6, 0xda, 0x5d, 0xad, 0xfd, 0x70, 0x6b, 0x03, 0xe7, 0x1a, 0x54,
326 0x0e, 0x8d, 0xc4, 0x54, 0x98, 0x81, 0x4f, 0xd4, 0x08, 0xd9, 0x02, 0x9e, 0x2e, 0x70, 0xbc, 0xb5,
327 0xc0, 0x66, 0xd4, 0x52, 0x07, 0x03, 0xd9, 0x0c, 0x5e, 0x08, 0xf7, 0x4a, 0x4a, 0x38, 0xe3, 0x79,
328 0xb8, 0x1f, 0xb9, 0xd3, 0x09, 0xee, 0x97, 0xe8, 0x11, 0x3c, 0xa4, 0xaf, 0x57, 0x45, 0x9b, 0xd1,
329 0xc5, 0xcb, 0x5a, 0x94, 0x0b, 0xc6, 0x33, 0xfa, 0x9a, 0x36, 0xe1, 0xa1, 0x1a, 0x0f, 0x8c, 0x6c,
330 0xee, 0xc7, 0x5a, 0x94, 0x17, 0x26, 0x33, 0x0b, 0x00, 0xb4, 0x13, 0x33, 0xe0, 0xff, 0xba, 0xb0,
331 0x6b, 0x7c, 0xa3, 0x2f, 0x60, 0xbc, 0xa6, 0x9d, 0x7d, 0xb7, 0xef, 0xbc, 0x22, 0xac, 0x20, 0x74,
332 0xa9, 0x7f, 0x1b, 0x15, 0xad, 0x25, 0xa3, 0x4d, 0x38, 0xd6, 0xaf, 0xe1, 0xcb, 0x3b, 0x0e, 0x25,
333 0x9e, 0x0f, 0xf4, 0x39, 0x97, 0x75, 0x87, 0x6f, 0xc9, 0x8f, 0x7e, 0x85, 0x83, 0x37, 0xd2, 0xe8,
334 0xc1, 0xc6, 0x8b, 0x67, 0x76, 0x7c, 0x04, 0x93, 0xcd, 0x44, 0xdf, 0xfd, 0xf4, 0x0c, 0xf8, 0xcd,
335 0xe8, 0xb1, 0x3b, 0xfb, 0xd3, 0x85, 0xf7, 0x57, 0xa2, 0xdc, 0x06, 0xcf, 0x7c, 0x63, 0x6d, 0xae,
336 0x86, 0x78, 0xee, 0xfe, 0xf6, 0xad, 0x65, 0x72, 0x51, 0x10, 0x9e, 0xc7, 0xa2, 0xce, 0x93, 0x9c,
337 0x72, 0x3d, 0xe2, 0x89, 0x49, 0x91, 0x8a, 0x35, 0xff, 0xfb, 0xcb, 0x3f, 0x19, 0x16, 0x7f, 0x8d,
338 0x3e, 0xf8, 0xc9, 0xc8, 0x9f, 0x15, 0xa2, 0xcd, 0xe2, 0x1f, 0x86, 0x8d, 0xae, 0x4e, 0xff, 0xee,
339 0x73, 0xd7, 0x3a, 0x77, 0x3d, 0xe4, 0xae, 0xaf, 0x4e, 0x97, 0xbb, 0x7a, 0x83, 0xaf, 0xfe, 0x0b,
340 0x00, 0x00, 0xff, 0xff, 0xf3, 0xdd, 0x11, 0x96, 0x45, 0x06, 0x00, 0x00,
341 }
342
343 var xxx_messageInfo_Key proto.InternalMessageInfo
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "bytes"
8 "context"
9 "encoding/base64"
10 "encoding/gob"
11 "errors"
12 "fmt"
13 "strconv"
14 "strings"
15
16 "github.com/golang/protobuf/proto"
17
18 "google.golang.org/appengine/v2/internal"
19 pb "google.golang.org/appengine/v2/internal/datastore"
20 )
21
22 type KeyRangeCollisionError struct {
23 start int64
24 end int64
25 }
26
27 func (e *KeyRangeCollisionError) Error() string {
28 return fmt.Sprintf("datastore: Collision when attempting to allocate range [%d, %d]",
29 e.start, e.end)
30 }
31
32 type KeyRangeContentionError struct {
33 start int64
34 end int64
35 }
36
37 func (e *KeyRangeContentionError) Error() string {
38 return fmt.Sprintf("datastore: Contention when attempting to allocate range [%d, %d]",
39 e.start, e.end)
40 }
41
42 // Key represents the datastore key for a stored entity, and is immutable.
43 type Key struct {
44 kind string
45 stringID string
46 intID int64
47 parent *Key
48 appID string
49 namespace string
50 }
51
52 // Kind returns the key's kind (also known as entity type).
53 func (k *Key) Kind() string {
54 return k.kind
55 }
56
57 // StringID returns the key's string ID (also known as an entity name or key
58 // name), which may be "".
59 func (k *Key) StringID() string {
60 return k.stringID
61 }
62
63 // IntID returns the key's integer ID, which may be 0.
64 func (k *Key) IntID() int64 {
65 return k.intID
66 }
67
68 // Parent returns the key's parent key, which may be nil.
69 func (k *Key) Parent() *Key {
70 return k.parent
71 }
72
73 // AppID returns the key's application ID.
74 func (k *Key) AppID() string {
75 return k.appID
76 }
77
78 // Namespace returns the key's namespace.
79 func (k *Key) Namespace() string {
80 return k.namespace
81 }
82
83 // Incomplete returns whether the key does not refer to a stored entity.
84 // In particular, whether the key has a zero StringID and a zero IntID.
85 func (k *Key) Incomplete() bool {
86 return k.stringID == "" && k.intID == 0
87 }
88
89 // valid returns whether the key is valid.
90 func (k *Key) valid() bool {
91 if k == nil {
92 return false
93 }
94 for ; k != nil; k = k.parent {
95 if k.kind == "" || k.appID == "" {
96 return false
97 }
98 if k.stringID != "" && k.intID != 0 {
99 return false
100 }
101 if k.parent != nil {
102 if k.parent.Incomplete() {
103 return false
104 }
105 if k.parent.appID != k.appID || k.parent.namespace != k.namespace {
106 return false
107 }
108 }
109 }
110 return true
111 }
112
113 // Equal returns whether two keys are equal.
114 func (k *Key) Equal(o *Key) bool {
115 for k != nil && o != nil {
116 if k.kind != o.kind || k.stringID != o.stringID || k.intID != o.intID || k.appID != o.appID || k.namespace != o.namespace {
117 return false
118 }
119 k, o = k.parent, o.parent
120 }
121 return k == o
122 }
123
124 // root returns the furthest ancestor of a key, which may be itself.
125 func (k *Key) root() *Key {
126 for k.parent != nil {
127 k = k.parent
128 }
129 return k
130 }
131
132 // marshal marshals the key's string representation to the buffer.
133 func (k *Key) marshal(b *bytes.Buffer) {
134 if k.parent != nil {
135 k.parent.marshal(b)
136 }
137 b.WriteByte('/')
138 b.WriteString(k.kind)
139 b.WriteByte(',')
140 if k.stringID != "" {
141 b.WriteString(k.stringID)
142 } else {
143 b.WriteString(strconv.FormatInt(k.intID, 10))
144 }
145 }
146
147 // String returns a string representation of the key.
148 func (k *Key) String() string {
149 if k == nil {
150 return ""
151 }
152 b := bytes.NewBuffer(make([]byte, 0, 512))
153 k.marshal(b)
154 return b.String()
155 }
156
157 type gobKey struct {
158 Kind string
159 StringID string
160 IntID int64
161 Parent *gobKey
162 AppID string
163 Namespace string
164 }
165
166 func keyToGobKey(k *Key) *gobKey {
167 if k == nil {
168 return nil
169 }
170 return &gobKey{
171 Kind: k.kind,
172 StringID: k.stringID,
173 IntID: k.intID,
174 Parent: keyToGobKey(k.parent),
175 AppID: k.appID,
176 Namespace: k.namespace,
177 }
178 }
179
180 func gobKeyToKey(gk *gobKey) *Key {
181 if gk == nil {
182 return nil
183 }
184 return &Key{
185 kind: gk.Kind,
186 stringID: gk.StringID,
187 intID: gk.IntID,
188 parent: gobKeyToKey(gk.Parent),
189 appID: gk.AppID,
190 namespace: gk.Namespace,
191 }
192 }
193
194 func (k *Key) GobEncode() ([]byte, error) {
195 buf := new(bytes.Buffer)
196 if err := gob.NewEncoder(buf).Encode(keyToGobKey(k)); err != nil {
197 return nil, err
198 }
199 return buf.Bytes(), nil
200 }
201
202 func (k *Key) GobDecode(buf []byte) error {
203 gk := new(gobKey)
204 if err := gob.NewDecoder(bytes.NewBuffer(buf)).Decode(gk); err != nil {
205 return err
206 }
207 *k = *gobKeyToKey(gk)
208 return nil
209 }
210
211 func (k *Key) MarshalJSON() ([]byte, error) {
212 return []byte(`"` + k.Encode() + `"`), nil
213 }
214
215 func (k *Key) UnmarshalJSON(buf []byte) error {
216 if len(buf) < 2 || buf[0] != '"' || buf[len(buf)-1] != '"' {
217 return errors.New("datastore: bad JSON key")
218 }
219 k2, err := DecodeKey(string(buf[1 : len(buf)-1]))
220 if err != nil {
221 return err
222 }
223 *k = *k2
224 return nil
225 }
226
227 // Encode returns an opaque representation of the key
228 // suitable for use in HTML and URLs.
229 // This is compatible with the Python and Java runtimes.
230 func (k *Key) Encode() string {
231 ref := keyToProto("", k)
232
233 b, err := proto.Marshal(ref)
234 if err != nil {
235 panic(err)
236 }
237
238 // Trailing padding is stripped.
239 return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
240 }
241
242 // DecodeKey decodes a key from the opaque representation returned by Encode.
243 func DecodeKey(encoded string) (*Key, error) {
244 // Re-add padding.
245 if m := len(encoded) % 4; m != 0 {
246 encoded += strings.Repeat("=", 4-m)
247 }
248
249 b, err := base64.URLEncoding.DecodeString(encoded)
250 if err != nil {
251 return nil, err
252 }
253
254 ref := new(pb.Reference)
255 if err := proto.Unmarshal(b, ref); err != nil {
256 // Couldn't decode it as an App Engine key, try decoding it as a key encoded by cloud.google.com/go/datastore.
257 if k := decodeCloudKey(encoded); k != nil {
258 return k, nil
259 }
260 return nil, err
261 }
262
263 return protoToKey(ref)
264 }
265
266 // NewIncompleteKey creates a new incomplete key.
267 // kind cannot be empty.
268 func NewIncompleteKey(c context.Context, kind string, parent *Key) *Key {
269 return NewKey(c, kind, "", 0, parent)
270 }
271
272 // NewKey creates a new key.
273 // kind cannot be empty.
274 // Either one or both of stringID and intID must be zero. If both are zero,
275 // the key returned is incomplete.
276 // parent must either be a complete key or nil.
277 func NewKey(c context.Context, kind, stringID string, intID int64, parent *Key) *Key {
278 // If there's a parent key, use its namespace.
279 // Otherwise, use any namespace attached to the context.
280 var namespace string
281 if parent != nil {
282 namespace = parent.namespace
283 } else {
284 namespace = internal.NamespaceFromContext(c)
285 }
286
287 return &Key{
288 kind: kind,
289 stringID: stringID,
290 intID: intID,
291 parent: parent,
292 appID: internal.FullyQualifiedAppID(c),
293 namespace: namespace,
294 }
295 }
296
297 // AllocateIDs returns a range of n integer IDs with the given kind and parent
298 // combination. kind cannot be empty; parent may be nil. The IDs in the range
299 // returned will not be used by the datastore's automatic ID sequence generator
300 // and may be used with NewKey without conflict.
301 //
302 // The range is inclusive at the low end and exclusive at the high end. In
303 // other words, valid intIDs x satisfy low <= x && x < high.
304 //
305 // If no error is returned, low + n == high.
306 func AllocateIDs(c context.Context, kind string, parent *Key, n int) (low, high int64, err error) {
307 if kind == "" {
308 return 0, 0, errors.New("datastore: AllocateIDs given an empty kind")
309 }
310 if n < 0 {
311 return 0, 0, fmt.Errorf("datastore: AllocateIDs given a negative count: %d", n)
312 }
313 if n == 0 {
314 return 0, 0, nil
315 }
316 req := &pb.AllocateIdsRequest{
317 ModelKey: keyToProto("", NewIncompleteKey(c, kind, parent)),
318 Size: proto.Int64(int64(n)),
319 }
320 res := &pb.AllocateIdsResponse{}
321 if err := internal.Call(c, "datastore_v3", "AllocateIds", req, res); err != nil {
322 return 0, 0, err
323 }
324 // The protobuf is inclusive at both ends. Idiomatic Go (e.g. slices, for loops)
325 // is inclusive at the low end and exclusive at the high end, so we add 1.
326 low = res.GetStart()
327 high = res.GetEnd() + 1
328 if low+int64(n) != high {
329 return 0, 0, fmt.Errorf("datastore: internal error: could not allocate %d IDs", n)
330 }
331 return low, high, nil
332 }
333
334 // AllocateIDRange allocates a range of IDs with specific endpoints.
335 // The range is inclusive at both the low and high end. Once these IDs have been
336 // allocated, you can manually assign them to newly created entities.
337 //
338 // The Datastore's automatic ID allocator never assigns a key that has already
339 // been allocated (either through automatic ID allocation or through an explicit
340 // AllocateIDs call). As a result, entities written to the given key range will
341 // never be overwritten. However, writing entities with manually assigned keys in
342 // this range may overwrite existing entities (or new entities written by a separate
343 // request), depending on the error returned.
344 //
345 // Use this only if you have an existing numeric ID range that you want to reserve
346 // (for example, bulk loading entities that already have IDs). If you don't care
347 // about which IDs you receive, use AllocateIDs instead.
348 //
349 // AllocateIDRange returns nil if the range is successfully allocated. If one or more
350 // entities with an ID in the given range already exist, it returns a KeyRangeCollisionError.
351 // If the Datastore has already cached IDs in this range (e.g. from a previous call to
352 // AllocateIDRange), it returns a KeyRangeContentionError. Errors of other types indicate
353 // problems with arguments or an error returned directly from the Datastore.
354 func AllocateIDRange(c context.Context, kind string, parent *Key, start, end int64) (err error) {
355 if kind == "" {
356 return errors.New("datastore: AllocateIDRange given an empty kind")
357 }
358
359 if start < 1 || end < 1 {
360 return errors.New("datastore: AllocateIDRange start and end must both be greater than 0")
361 }
362
363 if start > end {
364 return errors.New("datastore: AllocateIDRange start must be before end")
365 }
366
367 req := &pb.AllocateIdsRequest{
368 ModelKey: keyToProto("", NewIncompleteKey(c, kind, parent)),
369 Max: proto.Int64(end),
370 }
371 res := &pb.AllocateIdsResponse{}
372 if err := internal.Call(c, "datastore_v3", "AllocateIds", req, res); err != nil {
373 return err
374 }
375
376 // Check for collisions, i.e. existing entities with IDs in this range.
377 // We could do this before the allocation, but we'd still have to do it
378 // afterward as well to catch the race condition where an entity is inserted
379 // after that initial check but before the allocation. Skip the up-front check
380 // and just do it once.
381 q := NewQuery(kind).Filter("__key__ >=", NewKey(c, kind, "", start, parent)).
382 Filter("__key__ <=", NewKey(c, kind, "", end, parent)).KeysOnly().Limit(1)
383
384 keys, err := q.GetAll(c, nil)
385 if err != nil {
386 return err
387 }
388 if len(keys) != 0 {
389 return &KeyRangeCollisionError{start: start, end: end}
390 }
391
392 // Check for a race condition, i.e. cases where the datastore may have
393 // cached ID batches that contain IDs in this range.
394 if start < res.GetStart() {
395 return &KeyRangeContentionError{start: start, end: end}
396 }
397
398 return nil
399 }
0 // Copyright 2011 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "bytes"
8 "context"
9 "encoding/gob"
10 "encoding/json"
11 "testing"
12
13 "google.golang.org/appengine/v2/internal"
14 )
15
16 func TestKeyEncoding(t *testing.T) {
17 testCases := []struct {
18 desc string
19 key *Key
20 exp string
21 }{
22 {
23 desc: "A simple key with an int ID",
24 key: &Key{
25 kind: "Person",
26 intID: 1,
27 appID: "glibrary",
28 },
29 exp: "aghnbGlicmFyeXIMCxIGUGVyc29uGAEM",
30 },
31 {
32 desc: "A simple key with a string ID",
33 key: &Key{
34 kind: "Graph",
35 stringID: "graph:7-day-active",
36 appID: "glibrary",
37 },
38 exp: "aghnbGlicmFyeXIdCxIFR3JhcGgiEmdyYXBoOjctZGF5LWFjdGl2ZQw",
39 },
40 {
41 desc: "A key with a parent",
42 key: &Key{
43 kind: "WordIndex",
44 intID: 1033,
45 parent: &Key{
46 kind: "WordIndex",
47 intID: 1020032,
48 appID: "glibrary",
49 },
50 appID: "glibrary",
51 },
52 exp: "aghnbGlicmFyeXIhCxIJV29yZEluZGV4GIChPgwLEglXb3JkSW5kZXgYiQgM",
53 },
54 }
55 for _, tc := range testCases {
56 enc := tc.key.Encode()
57 if enc != tc.exp {
58 t.Errorf("%s: got %q, want %q", tc.desc, enc, tc.exp)
59 }
60
61 key, err := DecodeKey(tc.exp)
62 if err != nil {
63 t.Errorf("%s: failed decoding key: %v", tc.desc, err)
64 continue
65 }
66 if !key.Equal(tc.key) {
67 t.Errorf("%s: decoded key %v, want %v", tc.desc, key, tc.key)
68 }
69 }
70 }
71
72 func TestKeyGob(t *testing.T) {
73 k := &Key{
74 kind: "Gopher",
75 intID: 3,
76 parent: &Key{
77 kind: "Mom",
78 stringID: "narwhal",
79 appID: "gopher-con",
80 },
81 appID: "gopher-con",
82 }
83
84 buf := new(bytes.Buffer)
85 if err := gob.NewEncoder(buf).Encode(k); err != nil {
86 t.Fatalf("gob encode failed: %v", err)
87 }
88
89 k2 := new(Key)
90 if err := gob.NewDecoder(buf).Decode(k2); err != nil {
91 t.Fatalf("gob decode failed: %v", err)
92 }
93 if !k2.Equal(k) {
94 t.Errorf("gob round trip of %v produced %v", k, k2)
95 }
96 }
97
98 func TestNilKeyGob(t *testing.T) {
99 type S struct {
100 Key *Key
101 }
102 s1 := new(S)
103
104 buf := new(bytes.Buffer)
105 if err := gob.NewEncoder(buf).Encode(s1); err != nil {
106 t.Fatalf("gob encode failed: %v", err)
107 }
108
109 s2 := new(S)
110 if err := gob.NewDecoder(buf).Decode(s2); err != nil {
111 t.Fatalf("gob decode failed: %v", err)
112 }
113 if s2.Key != nil {
114 t.Errorf("gob round trip of nil key produced %v", s2.Key)
115 }
116 }
117
118 func TestKeyJSON(t *testing.T) {
119 k := &Key{
120 kind: "Gopher",
121 intID: 2,
122 parent: &Key{
123 kind: "Mom",
124 stringID: "narwhal",
125 appID: "gopher-con",
126 },
127 appID: "gopher-con",
128 }
129 exp := `"` + k.Encode() + `"`
130
131 buf, err := json.Marshal(k)
132 if err != nil {
133 t.Fatalf("json.Marshal failed: %v", err)
134 }
135 if s := string(buf); s != exp {
136 t.Errorf("JSON encoding of key %v: got %q, want %q", k, s, exp)
137 }
138
139 k2 := new(Key)
140 if err := json.Unmarshal(buf, k2); err != nil {
141 t.Fatalf("json.Unmarshal failed: %v", err)
142 }
143 if !k2.Equal(k) {
144 t.Errorf("JSON round trip of %v produced %v", k, k2)
145 }
146 }
147
148 func TestNilKeyJSON(t *testing.T) {
149 type S struct {
150 Key *Key
151 }
152 s1 := new(S)
153
154 buf, err := json.Marshal(s1)
155 if err != nil {
156 t.Fatalf("json.Marshal failed: %v", err)
157 }
158
159 s2 := new(S)
160 if err := json.Unmarshal(buf, s2); err != nil {
161 t.Fatalf("json.Unmarshal failed: %v", err)
162 }
163 if s2.Key != nil {
164 t.Errorf("JSON round trip of nil key produced %v", s2.Key)
165 }
166 }
167
168 func TestIncompleteKeyWithParent(t *testing.T) {
169 c := internal.WithAppIDOverride(context.Background(), "s~some-app")
170
171 // fadduh is a complete key.
172 fadduh := NewKey(c, "Person", "", 1, nil)
173 if fadduh.Incomplete() {
174 t.Fatalf("fadduh is incomplete")
175 }
176
177 // robert is an incomplete key with fadduh as a parent.
178 robert := NewIncompleteKey(c, "Person", fadduh)
179 if !robert.Incomplete() {
180 t.Fatalf("robert is complete")
181 }
182
183 // Both should be valid keys.
184 if !fadduh.valid() {
185 t.Errorf("fadduh is invalid: %v", fadduh)
186 }
187 if !robert.valid() {
188 t.Errorf("robert is invalid: %v", robert)
189 }
190 }
191
192 func TestNamespace(t *testing.T) {
193 key := &Key{
194 kind: "Person",
195 intID: 1,
196 appID: "s~some-app",
197 namespace: "mynamespace",
198 }
199 if g, w := key.Namespace(), "mynamespace"; g != w {
200 t.Errorf("key.Namespace() = %q, want %q", g, w)
201 }
202 }
0 // Copyright 2019 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "context"
8 "sync"
9
10 "google.golang.org/appengine/v2/datastore/internal/cloudkey"
11 "google.golang.org/appengine/v2/internal"
12 )
13
14 var keyConversion struct {
15 mu sync.RWMutex
16 appID string // read using getKeyConversionAppID
17 }
18
19 // EnableKeyConversion enables encoded key compatibility with the Cloud
20 // Datastore client library (cloud.google.com/go/datastore). Encoded keys
21 // generated by the Cloud Datastore client library will be decoded into App
22 // Engine datastore keys.
23 //
24 // The context provided must be an App Engine context if running in App Engine
25 // first generation runtime. This can be called in the /_ah/start handler. It is
26 // safe to call multiple times, and is cheap to call, so can also be inserted as
27 // middleware.
28 //
29 // Enabling key compatibility does not affect the encoding format used by
30 // Key.Encode, it only expands the type of keys that are able to be decoded with
31 // DecodeKey.
32 func EnableKeyConversion(ctx context.Context) {
33 // Only attempt to set appID if it's unset.
34 // If already set, ignore.
35 if getKeyConversionAppID() != "" {
36 return
37 }
38
39 keyConversion.mu.Lock()
40 // Check again to avoid race where another goroutine set appID between the call
41 // to getKeyConversionAppID above and taking the write lock.
42 if keyConversion.appID == "" {
43 keyConversion.appID = internal.FullyQualifiedAppID(ctx)
44 }
45 keyConversion.mu.Unlock()
46 }
47
48 func getKeyConversionAppID() string {
49 keyConversion.mu.RLock()
50 appID := keyConversion.appID
51 keyConversion.mu.RUnlock()
52 return appID
53 }
54
55 // decodeCloudKey attempts to decode the given encoded key generated by the
56 // Cloud Datastore client library (cloud.google.com/go/datastore), returning nil
57 // if the key couldn't be decoded.
58 func decodeCloudKey(encoded string) *Key {
59 appID := getKeyConversionAppID()
60 if appID == "" {
61 return nil
62 }
63
64 k, err := cloudkey.DecodeKey(encoded)
65 if err != nil {
66 return nil
67 }
68 return convertCloudKey(k, appID)
69 }
70
71 // convertCloudKey converts a Cloud Datastore key and converts it to an App
72 // Engine Datastore key. Cloud Datastore keys don't include the project/app ID,
73 // so we must add it back in.
74 func convertCloudKey(key *cloudkey.Key, appID string) *Key {
75 if key == nil {
76 return nil
77 }
78 k := &Key{
79 intID: key.ID,
80 kind: key.Kind,
81 namespace: key.Namespace,
82 parent: convertCloudKey(key.Parent, appID),
83 stringID: key.Name,
84 appID: appID,
85 }
86 return k
87 }
0 // Copyright 2019 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "reflect"
8 "testing"
9 )
10
11 func TestKeyConversion(t *testing.T) {
12 var tests = []struct {
13 desc string
14 key *Key
15 encodedKey string
16 }{
17 {
18 desc: "A control test for legacy to legacy key conversion int as the key",
19 key: &Key{
20 kind: "Person",
21 intID: 1,
22 appID: "glibrary",
23 },
24 encodedKey: "aghnbGlicmFyeXIMCxIGUGVyc29uGAEM",
25 },
26 {
27 desc: "A control test for legacy to legacy key conversion string as the key",
28 key: &Key{
29 kind: "Graph",
30 stringID: "graph:7-day-active",
31 appID: "glibrary",
32 },
33 encodedKey: "aghnbGlicmFyeXIdCxIFR3JhcGgiEmdyYXBoOjctZGF5LWFjdGl2ZQw",
34 },
35
36 // These are keys encoded with cloud.google.com/go/datastore
37 // Standard int as the key
38 {
39 desc: "Convert new key format to old key with int id",
40 key: &Key{
41 kind: "WordIndex",
42 intID: 1033,
43 appID: "glibrary",
44 },
45 encodedKey: "Eg4KCVdvcmRJbmRleBCJCA",
46 },
47 // These are keys encoded with cloud.google.com/go/datastore
48 // Standard string
49 {
50 desc: "Convert new key format to old key with string id",
51 key: &Key{
52 kind: "WordIndex",
53 stringID: "IAmAnID",
54 appID: "glibrary",
55 },
56 encodedKey: "EhQKCVdvcmRJbmRleBoHSUFtQW5JRA",
57 },
58
59 // These are keys encoded with cloud.google.com/go/datastore
60 // ID String with parent as string
61 {
62 desc: "Convert new key format to old key with string id with a parent",
63 key: &Key{
64 kind: "WordIndex",
65 stringID: "IAmAnID",
66 appID: "glibrary",
67 parent: &Key{
68 kind: "LetterIndex",
69 stringID: "IAmAnotherID",
70 appID: "glibrary",
71 },
72 },
73 encodedKey: "EhsKC0xldHRlckluZGV4GgxJQW1Bbm90aGVySUQSFAoJV29yZEluZGV4GgdJQW1BbklE",
74 },
75 }
76
77 // Simulate the key converter enablement
78 keyConversion.appID = "glibrary"
79 for _, tc := range tests {
80 dk, err := DecodeKey(tc.encodedKey)
81 if err != nil {
82 t.Fatalf("DecodeKey: %v", err)
83 }
84 if !reflect.DeepEqual(dk, tc.key) {
85 t.Errorf("%s: got %+v, want %+v", tc.desc, dk, tc.key)
86 }
87 }
88 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "fmt"
8 "reflect"
9 "strings"
10 "time"
11
12 "github.com/golang/protobuf/proto"
13 "google.golang.org/appengine/v2"
14 pb "google.golang.org/appengine/v2/internal/datastore"
15 )
16
17 var (
18 typeOfBlobKey = reflect.TypeOf(appengine.BlobKey(""))
19 typeOfByteSlice = reflect.TypeOf([]byte(nil))
20 typeOfByteString = reflect.TypeOf(ByteString(nil))
21 typeOfGeoPoint = reflect.TypeOf(appengine.GeoPoint{})
22 typeOfTime = reflect.TypeOf(time.Time{})
23 typeOfKeyPtr = reflect.TypeOf(&Key{})
24 typeOfEntityPtr = reflect.TypeOf(&Entity{})
25 )
26
27 // typeMismatchReason returns a string explaining why the property p could not
28 // be stored in an entity field of type v.Type().
29 func typeMismatchReason(pValue interface{}, v reflect.Value) string {
30 entityType := "empty"
31 switch pValue.(type) {
32 case int64:
33 entityType = "int"
34 case bool:
35 entityType = "bool"
36 case string:
37 entityType = "string"
38 case float64:
39 entityType = "float"
40 case *Key:
41 entityType = "*datastore.Key"
42 case time.Time:
43 entityType = "time.Time"
44 case appengine.BlobKey:
45 entityType = "appengine.BlobKey"
46 case appengine.GeoPoint:
47 entityType = "appengine.GeoPoint"
48 case ByteString:
49 entityType = "datastore.ByteString"
50 case []byte:
51 entityType = "[]byte"
52 }
53 return fmt.Sprintf("type mismatch: %s versus %v", entityType, v.Type())
54 }
55
56 type propertyLoader struct {
57 // m holds the number of times a substruct field like "Foo.Bar.Baz" has
58 // been seen so far. The map is constructed lazily.
59 m map[string]int
60 }
61
62 func (l *propertyLoader) load(codec *structCodec, structValue reflect.Value, p Property, requireSlice bool) string {
63 var v reflect.Value
64 var sliceIndex int
65
66 name := p.Name
67
68 // If name ends with a '.', the last field is anonymous.
69 // In this case, strings.Split will give us "" as the
70 // last element of our fields slice, which will match the ""
71 // field name in the substruct codec.
72 fields := strings.Split(name, ".")
73
74 for len(fields) > 0 {
75 var decoder fieldCodec
76 var ok bool
77
78 // Cut off the last field (delimited by ".") and find its parent
79 // in the codec.
80 // eg. for name "A.B.C.D", split off "A.B.C" and try to
81 // find a field in the codec with this name.
82 // Loop again with "A.B", etc.
83 for i := len(fields); i > 0; i-- {
84 parent := strings.Join(fields[:i], ".")
85 decoder, ok = codec.fields[parent]
86 if ok {
87 fields = fields[i:]
88 break
89 }
90 }
91
92 // If we never found a matching field in the codec, return
93 // error message.
94 if !ok {
95 return "no such struct field"
96 }
97
98 v = initField(structValue, decoder.path)
99 if !v.IsValid() {
100 return "no such struct field"
101 }
102 if !v.CanSet() {
103 return "cannot set struct field"
104 }
105
106 if decoder.structCodec != nil {
107 codec = decoder.structCodec
108 structValue = v
109 }
110
111 if v.Kind() == reflect.Slice && v.Type() != typeOfByteSlice {
112 if l.m == nil {
113 l.m = make(map[string]int)
114 }
115 sliceIndex = l.m[p.Name]
116 l.m[p.Name] = sliceIndex + 1
117 for v.Len() <= sliceIndex {
118 v.Set(reflect.Append(v, reflect.New(v.Type().Elem()).Elem()))
119 }
120 structValue = v.Index(sliceIndex)
121 requireSlice = false
122 }
123 }
124
125 var slice reflect.Value
126 if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
127 slice = v
128 v = reflect.New(v.Type().Elem()).Elem()
129 } else if requireSlice {
130 return "multiple-valued property requires a slice field type"
131 }
132
133 // Convert indexValues to a Go value with a meaning derived from the
134 // destination type.
135 pValue := p.Value
136 if iv, ok := pValue.(indexValue); ok {
137 meaning := pb.Property_NO_MEANING
138 switch v.Type() {
139 case typeOfBlobKey:
140 meaning = pb.Property_BLOBKEY
141 case typeOfByteSlice:
142 meaning = pb.Property_BLOB
143 case typeOfByteString:
144 meaning = pb.Property_BYTESTRING
145 case typeOfGeoPoint:
146 meaning = pb.Property_GEORSS_POINT
147 case typeOfTime:
148 meaning = pb.Property_GD_WHEN
149 case typeOfEntityPtr:
150 meaning = pb.Property_ENTITY_PROTO
151 }
152 var err error
153 pValue, err = propValue(iv.value, meaning)
154 if err != nil {
155 return err.Error()
156 }
157 }
158
159 if errReason := setVal(v, pValue); errReason != "" {
160 // Set the slice back to its zero value.
161 if slice.IsValid() {
162 slice.Set(reflect.Zero(slice.Type()))
163 }
164 return errReason
165 }
166
167 if slice.IsValid() {
168 slice.Index(sliceIndex).Set(v)
169 }
170
171 return ""
172 }
173
174 // setVal sets v to the value pValue.
175 func setVal(v reflect.Value, pValue interface{}) string {
176 switch v.Kind() {
177 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
178 x, ok := pValue.(int64)
179 if !ok && pValue != nil {
180 return typeMismatchReason(pValue, v)
181 }
182 if v.OverflowInt(x) {
183 return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
184 }
185 v.SetInt(x)
186 case reflect.Bool:
187 x, ok := pValue.(bool)
188 if !ok && pValue != nil {
189 return typeMismatchReason(pValue, v)
190 }
191 v.SetBool(x)
192 case reflect.String:
193 switch x := pValue.(type) {
194 case appengine.BlobKey:
195 v.SetString(string(x))
196 case ByteString:
197 v.SetString(string(x))
198 case string:
199 v.SetString(x)
200 default:
201 if pValue != nil {
202 return typeMismatchReason(pValue, v)
203 }
204 }
205 case reflect.Float32, reflect.Float64:
206 x, ok := pValue.(float64)
207 if !ok && pValue != nil {
208 return typeMismatchReason(pValue, v)
209 }
210 if v.OverflowFloat(x) {
211 return fmt.Sprintf("value %v overflows struct field of type %v", x, v.Type())
212 }
213 v.SetFloat(x)
214 case reflect.Ptr:
215 x, ok := pValue.(*Key)
216 if !ok && pValue != nil {
217 return typeMismatchReason(pValue, v)
218 }
219 if _, ok := v.Interface().(*Key); !ok {
220 return typeMismatchReason(pValue, v)
221 }
222 v.Set(reflect.ValueOf(x))
223 case reflect.Struct:
224 switch v.Type() {
225 case typeOfTime:
226 x, ok := pValue.(time.Time)
227 if !ok && pValue != nil {
228 return typeMismatchReason(pValue, v)
229 }
230 v.Set(reflect.ValueOf(x))
231 case typeOfGeoPoint:
232 x, ok := pValue.(appengine.GeoPoint)
233 if !ok && pValue != nil {
234 return typeMismatchReason(pValue, v)
235 }
236 v.Set(reflect.ValueOf(x))
237 default:
238 ent, ok := pValue.(*Entity)
239 if !ok {
240 return typeMismatchReason(pValue, v)
241 }
242
243 // Recursively load nested struct
244 pls, err := newStructPLS(v.Addr().Interface())
245 if err != nil {
246 return err.Error()
247 }
248
249 // if ent has a Key value and our struct has a Key field,
250 // load the Entity's Key value into the Key field on the struct.
251 if ent.Key != nil && pls.codec.keyField != -1 {
252
253 pls.v.Field(pls.codec.keyField).Set(reflect.ValueOf(ent.Key))
254 }
255
256 err = pls.Load(ent.Properties)
257 if err != nil {
258 return err.Error()
259 }
260 }
261 case reflect.Slice:
262 x, ok := pValue.([]byte)
263 if !ok {
264 if y, yok := pValue.(ByteString); yok {
265 x, ok = []byte(y), true
266 }
267 }
268 if !ok && pValue != nil {
269 return typeMismatchReason(pValue, v)
270 }
271 if v.Type().Elem().Kind() != reflect.Uint8 {
272 return typeMismatchReason(pValue, v)
273 }
274 v.SetBytes(x)
275 default:
276 return typeMismatchReason(pValue, v)
277 }
278 return ""
279 }
280
281 // initField is similar to reflect's Value.FieldByIndex, in that it
282 // returns the nested struct field corresponding to index, but it
283 // initialises any nil pointers encountered when traversing the structure.
284 func initField(val reflect.Value, index []int) reflect.Value {
285 for _, i := range index[:len(index)-1] {
286 val = val.Field(i)
287 if val.Kind() == reflect.Ptr {
288 if val.IsNil() {
289 val.Set(reflect.New(val.Type().Elem()))
290 }
291 val = val.Elem()
292 }
293 }
294 return val.Field(index[len(index)-1])
295 }
296
297 // loadEntity loads an EntityProto into PropertyLoadSaver or struct pointer.
298 func loadEntity(dst interface{}, src *pb.EntityProto) (err error) {
299 ent, err := protoToEntity(src)
300 if err != nil {
301 return err
302 }
303 if e, ok := dst.(PropertyLoadSaver); ok {
304 return e.Load(ent.Properties)
305 }
306 return LoadStruct(dst, ent.Properties)
307 }
308
309 func (s structPLS) Load(props []Property) error {
310 var fieldName, reason string
311 var l propertyLoader
312 for _, p := range props {
313 if errStr := l.load(s.codec, s.v, p, p.Multiple); errStr != "" {
314 // We don't return early, as we try to load as many properties as possible.
315 // It is valid to load an entity into a struct that cannot fully represent it.
316 // That case returns an error, but the caller is free to ignore it.
317 fieldName, reason = p.Name, errStr
318 }
319 }
320 if reason != "" {
321 return &ErrFieldMismatch{
322 StructType: s.v.Type(),
323 FieldName: fieldName,
324 Reason: reason,
325 }
326 }
327 return nil
328 }
329
330 func protoToEntity(src *pb.EntityProto) (*Entity, error) {
331 props, rawProps := src.Property, src.RawProperty
332 outProps := make([]Property, 0, len(props)+len(rawProps))
333 for {
334 var (
335 x *pb.Property
336 noIndex bool
337 )
338 if len(props) > 0 {
339 x, props = props[0], props[1:]
340 } else if len(rawProps) > 0 {
341 x, rawProps = rawProps[0], rawProps[1:]
342 noIndex = true
343 } else {
344 break
345 }
346
347 var value interface{}
348 if x.Meaning != nil && *x.Meaning == pb.Property_INDEX_VALUE {
349 value = indexValue{x.Value}
350 } else {
351 var err error
352 value, err = propValue(x.Value, x.GetMeaning())
353 if err != nil {
354 return nil, err
355 }
356 }
357 outProps = append(outProps, Property{
358 Name: x.GetName(),
359 Value: value,
360 NoIndex: noIndex,
361 Multiple: x.GetMultiple(),
362 })
363 }
364
365 var key *Key
366 if src.Key != nil {
367 // Ignore any error, since nested entity values
368 // are allowed to have an invalid key.
369 key, _ = protoToKey(src.Key)
370 }
371 return &Entity{key, outProps}, nil
372 }
373
374 // propValue returns a Go value that combines the raw PropertyValue with a
375 // meaning. For example, an Int64Value with GD_WHEN becomes a time.Time.
376 func propValue(v *pb.PropertyValue, m pb.Property_Meaning) (interface{}, error) {
377 switch {
378 case v.Int64Value != nil:
379 if m == pb.Property_GD_WHEN {
380 return fromUnixMicro(*v.Int64Value), nil
381 } else {
382 return *v.Int64Value, nil
383 }
384 case v.BooleanValue != nil:
385 return *v.BooleanValue, nil
386 case v.StringValue != nil:
387 if m == pb.Property_BLOB {
388 return []byte(*v.StringValue), nil
389 } else if m == pb.Property_BLOBKEY {
390 return appengine.BlobKey(*v.StringValue), nil
391 } else if m == pb.Property_BYTESTRING {
392 return ByteString(*v.StringValue), nil
393 } else if m == pb.Property_ENTITY_PROTO {
394 var ent pb.EntityProto
395 err := proto.Unmarshal([]byte(*v.StringValue), &ent)
396 if err != nil {
397 return nil, err
398 }
399 return protoToEntity(&ent)
400 } else {
401 return *v.StringValue, nil
402 }
403 case v.DoubleValue != nil:
404 return *v.DoubleValue, nil
405 case v.Referencevalue != nil:
406 key, err := referenceValueToKey(v.Referencevalue)
407 if err != nil {
408 return nil, err
409 }
410 return key, nil
411 case v.Pointvalue != nil:
412 // NOTE: Strangely, latitude maps to X, longitude to Y.
413 return appengine.GeoPoint{Lat: v.Pointvalue.GetX(), Lng: v.Pointvalue.GetY()}, nil
414 }
415 return nil, nil
416 }
417
418 // indexValue is a Property value that is created when entities are loaded from
419 // an index, such as from a projection query.
420 //
421 // Such Property values do not contain all of the metadata required to be
422 // faithfully represented as a Go value, and are instead represented as an
423 // opaque indexValue. Load the properties into a concrete struct type (e.g. by
424 // passing a struct pointer to Iterator.Next) to reconstruct actual Go values
425 // of type int, string, time.Time, etc.
426 type indexValue struct {
427 value *pb.PropertyValue
428 }
0 // Copyright 2016 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "reflect"
8 "testing"
9
10 proto "github.com/golang/protobuf/proto"
11 pb "google.golang.org/appengine/v2/internal/datastore"
12 )
13
14 type Simple struct {
15 I int64
16 }
17
18 type SimpleWithTag struct {
19 I int64 `datastore:"II"`
20 }
21
22 type NestedSimpleWithTag struct {
23 A SimpleWithTag `datastore:"AA"`
24 }
25
26 type NestedSliceOfSimple struct {
27 A []Simple
28 }
29
30 type SimpleTwoFields struct {
31 S string
32 SS string
33 }
34
35 type NestedSimpleAnonymous struct {
36 Simple
37 X string
38 }
39
40 type NestedSimple struct {
41 A Simple
42 I int64
43 }
44
45 type NestedSimple1 struct {
46 A Simple
47 X string
48 }
49
50 type NestedSimple2X struct {
51 AA NestedSimple
52 A SimpleTwoFields
53 S string
54 }
55
56 type BDotB struct {
57 B string `datastore:"B.B"`
58 }
59
60 type ABDotB struct {
61 A BDotB
62 }
63
64 type MultiAnonymous struct {
65 Simple
66 SimpleTwoFields
67 X string
68 }
69
70 var (
71 // these values need to be addressable
72 testString2 = "two"
73 testString3 = "three"
74 testInt64 = int64(2)
75
76 fieldNameI = "I"
77 fieldNameX = "X"
78 fieldNameS = "S"
79 fieldNameSS = "SS"
80 fieldNameADotI = "A.I"
81 fieldNameAADotII = "AA.II"
82 fieldNameADotBDotB = "A.B.B"
83 )
84
85 func TestLoadEntityNestedLegacy(t *testing.T) {
86 testCases := []struct {
87 desc string
88 src *pb.EntityProto
89 want interface{}
90 }{
91 {
92 "nested",
93 &pb.EntityProto{
94 Key: keyToProto("some-app-id", testKey0),
95 Property: []*pb.Property{
96 &pb.Property{
97 Name: &fieldNameX,
98 Value: &pb.PropertyValue{
99 StringValue: &testString2,
100 },
101 },
102 &pb.Property{
103 Name: &fieldNameADotI,
104 Value: &pb.PropertyValue{
105 Int64Value: &testInt64,
106 },
107 },
108 },
109 },
110 &NestedSimple1{
111 A: Simple{I: testInt64},
112 X: testString2,
113 },
114 },
115 {
116 "nested with tag",
117 &pb.EntityProto{
118 Key: keyToProto("some-app-id", testKey0),
119 Property: []*pb.Property{
120 &pb.Property{
121 Name: &fieldNameAADotII,
122 Value: &pb.PropertyValue{
123 Int64Value: &testInt64,
124 },
125 },
126 },
127 },
128 &NestedSimpleWithTag{
129 A: SimpleWithTag{I: testInt64},
130 },
131 },
132 {
133 "nested with anonymous struct field",
134 &pb.EntityProto{
135 Key: keyToProto("some-app-id", testKey0),
136 Property: []*pb.Property{
137 &pb.Property{
138 Name: &fieldNameX,
139 Value: &pb.PropertyValue{
140 StringValue: &testString2,
141 },
142 },
143 &pb.Property{
144 Name: &fieldNameI,
145 Value: &pb.PropertyValue{
146 Int64Value: &testInt64,
147 },
148 },
149 },
150 },
151 &NestedSimpleAnonymous{
152 Simple: Simple{I: testInt64},
153 X: testString2,
154 },
155 },
156 {
157 "nested with dotted field tag",
158 &pb.EntityProto{
159 Key: keyToProto("some-app-id", testKey0),
160 Property: []*pb.Property{
161 &pb.Property{
162 Name: &fieldNameADotBDotB,
163 Value: &pb.PropertyValue{
164 StringValue: &testString2,
165 },
166 },
167 },
168 },
169 &ABDotB{
170 A: BDotB{
171 B: testString2,
172 },
173 },
174 },
175 {
176 "nested with dotted field tag",
177 &pb.EntityProto{
178 Key: keyToProto("some-app-id", testKey0),
179 Property: []*pb.Property{
180 &pb.Property{
181 Name: &fieldNameI,
182 Value: &pb.PropertyValue{
183 Int64Value: &testInt64,
184 },
185 },
186 &pb.Property{
187 Name: &fieldNameS,
188 Value: &pb.PropertyValue{
189 StringValue: &testString2,
190 },
191 },
192 &pb.Property{
193 Name: &fieldNameSS,
194 Value: &pb.PropertyValue{
195 StringValue: &testString3,
196 },
197 },
198 &pb.Property{
199 Name: &fieldNameX,
200 Value: &pb.PropertyValue{
201 StringValue: &testString3,
202 },
203 },
204 },
205 },
206 &MultiAnonymous{
207 Simple: Simple{I: testInt64},
208 SimpleTwoFields: SimpleTwoFields{S: "two", SS: "three"},
209 X: "three",
210 },
211 },
212 }
213
214 for _, tc := range testCases {
215 dst := reflect.New(reflect.TypeOf(tc.want).Elem()).Interface()
216 err := loadEntity(dst, tc.src)
217 if err != nil {
218 t.Errorf("loadEntity: %s: %v", tc.desc, err)
219 continue
220 }
221
222 if !reflect.DeepEqual(tc.want, dst) {
223 t.Errorf("%s: compare:\ngot: %#v\nwant: %#v", tc.desc, dst, tc.want)
224 }
225 }
226 }
227
228 type WithKey struct {
229 X string
230 I int64
231 K *Key `datastore:"__key__"`
232 }
233
234 type NestedWithKey struct {
235 N WithKey
236 Y string
237 }
238
239 var (
240 incompleteKey = newKey("", nil)
241 invalidKey = newKey("s", incompleteKey)
242
243 // these values need to be addressable
244 fieldNameA = "A"
245 fieldNameK = "K"
246 fieldNameN = "N"
247 fieldNameY = "Y"
248 fieldNameAA = "AA"
249 fieldNameII = "II"
250 fieldNameBDotB = "B.B"
251
252 entityProtoMeaning = pb.Property_ENTITY_PROTO
253
254 TRUE = true
255 FALSE = false
256 )
257
258 var (
259 simpleEntityProto, nestedSimpleEntityProto,
260 simpleTwoFieldsEntityProto, simpleWithTagEntityProto,
261 bDotBEntityProto, withKeyEntityProto string
262 )
263
264 func init() {
265 // simpleEntityProto corresponds to:
266 // Simple{I: testInt64}
267 simpleEntityProtob, err := proto.Marshal(&pb.EntityProto{
268 Key: keyToProto("", incompleteKey),
269 Property: []*pb.Property{
270 &pb.Property{
271 Name: &fieldNameI,
272 Value: &pb.PropertyValue{
273 Int64Value: &testInt64,
274 },
275 Multiple: &FALSE,
276 },
277 },
278 EntityGroup: &pb.Path{},
279 })
280 if err != nil {
281 panic(err)
282 }
283 simpleEntityProto = string(simpleEntityProtob)
284
285 // nestedSimpleEntityProto corresponds to:
286 // NestedSimple{
287 // A: Simple{I: testInt64},
288 // I: testInt64,
289 // }
290 nestedSimpleEntityProtob, err := proto.Marshal(&pb.EntityProto{
291 Key: keyToProto("", incompleteKey),
292 Property: []*pb.Property{
293 &pb.Property{
294 Name: &fieldNameA,
295 Meaning: &entityProtoMeaning,
296 Value: &pb.PropertyValue{
297 StringValue: &simpleEntityProto,
298 },
299 Multiple: &FALSE,
300 },
301 &pb.Property{
302 Name: &fieldNameI,
303 Meaning: &entityProtoMeaning,
304 Value: &pb.PropertyValue{
305 Int64Value: &testInt64,
306 },
307 Multiple: &FALSE,
308 },
309 },
310 EntityGroup: &pb.Path{},
311 })
312 if err != nil {
313 panic(err)
314 }
315 nestedSimpleEntityProto = string(nestedSimpleEntityProtob)
316
317 // simpleTwoFieldsEntityProto corresponds to:
318 // SimpleTwoFields{S: testString2, SS: testString3}
319 simpleTwoFieldsEntityProtob, err := proto.Marshal(&pb.EntityProto{
320 Key: keyToProto("", incompleteKey),
321 Property: []*pb.Property{
322 &pb.Property{
323 Name: &fieldNameS,
324 Value: &pb.PropertyValue{
325 StringValue: &testString2,
326 },
327 Multiple: &FALSE,
328 },
329 &pb.Property{
330 Name: &fieldNameSS,
331 Value: &pb.PropertyValue{
332 StringValue: &testString3,
333 },
334 Multiple: &FALSE,
335 },
336 },
337 EntityGroup: &pb.Path{},
338 })
339 if err != nil {
340 panic(err)
341 }
342 simpleTwoFieldsEntityProto = string(simpleTwoFieldsEntityProtob)
343
344 // simpleWithTagEntityProto corresponds to:
345 // SimpleWithTag{I: testInt64}
346 simpleWithTagEntityProtob, err := proto.Marshal(&pb.EntityProto{
347 Key: keyToProto("", incompleteKey),
348 Property: []*pb.Property{
349 &pb.Property{
350 Name: &fieldNameII,
351 Value: &pb.PropertyValue{
352 Int64Value: &testInt64,
353 },
354 Multiple: &FALSE,
355 },
356 },
357 EntityGroup: &pb.Path{},
358 })
359 if err != nil {
360 panic(err)
361 }
362 simpleWithTagEntityProto = string(simpleWithTagEntityProtob)
363
364 // bDotBEntityProto corresponds to:
365 // BDotB{
366 // B: testString2,
367 // }
368 bDotBEntityProtob, err := proto.Marshal(&pb.EntityProto{
369 Key: keyToProto("", incompleteKey),
370 Property: []*pb.Property{
371 &pb.Property{
372 Name: &fieldNameBDotB,
373 Value: &pb.PropertyValue{
374 StringValue: &testString2,
375 },
376 Multiple: &FALSE,
377 },
378 },
379 EntityGroup: &pb.Path{},
380 })
381 if err != nil {
382 panic(err)
383 }
384 bDotBEntityProto = string(bDotBEntityProtob)
385
386 // withKeyEntityProto corresponds to:
387 // WithKey{
388 // X: testString3,
389 // I: testInt64,
390 // K: testKey1a,
391 // }
392 withKeyEntityProtob, err := proto.Marshal(&pb.EntityProto{
393 Key: keyToProto("", testKey1a),
394 Property: []*pb.Property{
395 &pb.Property{
396 Name: &fieldNameX,
397 Value: &pb.PropertyValue{
398 StringValue: &testString3,
399 },
400 Multiple: &FALSE,
401 },
402 &pb.Property{
403 Name: &fieldNameI,
404 Value: &pb.PropertyValue{
405 Int64Value: &testInt64,
406 },
407 Multiple: &FALSE,
408 },
409 },
410 EntityGroup: &pb.Path{},
411 })
412 if err != nil {
413 panic(err)
414 }
415 withKeyEntityProto = string(withKeyEntityProtob)
416
417 }
418
419 func TestLoadEntityNested(t *testing.T) {
420 testCases := []struct {
421 desc string
422 src *pb.EntityProto
423 want interface{}
424 }{
425 {
426 "nested basic",
427 &pb.EntityProto{
428 Key: keyToProto("some-app-id", testKey0),
429 Property: []*pb.Property{
430 &pb.Property{
431 Name: &fieldNameA,
432 Meaning: &entityProtoMeaning,
433 Value: &pb.PropertyValue{
434 StringValue: &simpleEntityProto,
435 },
436 },
437 &pb.Property{
438 Name: &fieldNameI,
439 Value: &pb.PropertyValue{
440 Int64Value: &testInt64,
441 },
442 },
443 },
444 },
445 &NestedSimple{
446 A: Simple{I: 2},
447 I: 2,
448 },
449 },
450 {
451 "nested with struct tags",
452 &pb.EntityProto{
453 Key: keyToProto("some-app-id", testKey0),
454 Property: []*pb.Property{
455 &pb.Property{
456 Name: &fieldNameAA,
457 Meaning: &entityProtoMeaning,
458 Value: &pb.PropertyValue{
459 StringValue: &simpleWithTagEntityProto,
460 },
461 },
462 },
463 },
464 &NestedSimpleWithTag{
465 A: SimpleWithTag{I: testInt64},
466 },
467 },
468 {
469 "nested 2x",
470 &pb.EntityProto{
471 Key: keyToProto("some-app-id", testKey0),
472 Property: []*pb.Property{
473 &pb.Property{
474 Name: &fieldNameAA,
475 Meaning: &entityProtoMeaning,
476 Value: &pb.PropertyValue{
477 StringValue: &nestedSimpleEntityProto,
478 },
479 },
480 &pb.Property{
481 Name: &fieldNameA,
482 Meaning: &entityProtoMeaning,
483 Value: &pb.PropertyValue{
484 StringValue: &simpleTwoFieldsEntityProto,
485 },
486 },
487 &pb.Property{
488 Name: &fieldNameS,
489 Value: &pb.PropertyValue{
490 StringValue: &testString3,
491 },
492 },
493 },
494 },
495 &NestedSimple2X{
496 AA: NestedSimple{
497 A: Simple{I: testInt64},
498 I: testInt64,
499 },
500 A: SimpleTwoFields{S: testString2, SS: testString3},
501 S: testString3,
502 },
503 },
504 {
505 "nested anonymous",
506 &pb.EntityProto{
507 Key: keyToProto("some-app-id", testKey0),
508 Property: []*pb.Property{
509 &pb.Property{
510 Name: &fieldNameI,
511 Value: &pb.PropertyValue{
512 Int64Value: &testInt64,
513 },
514 },
515 &pb.Property{
516 Name: &fieldNameX,
517 Value: &pb.PropertyValue{
518 StringValue: &testString2,
519 },
520 },
521 },
522 },
523 &NestedSimpleAnonymous{
524 Simple: Simple{I: testInt64},
525 X: testString2,
526 },
527 },
528 {
529 "nested simple with slice",
530 &pb.EntityProto{
531 Key: keyToProto("some-app-id", testKey0),
532 Property: []*pb.Property{
533 &pb.Property{
534 Name: &fieldNameA,
535 Meaning: &entityProtoMeaning,
536 Multiple: &TRUE,
537 Value: &pb.PropertyValue{
538 StringValue: &simpleEntityProto,
539 },
540 },
541 &pb.Property{
542 Name: &fieldNameA,
543 Meaning: &entityProtoMeaning,
544 Multiple: &TRUE,
545 Value: &pb.PropertyValue{
546 StringValue: &simpleEntityProto,
547 },
548 },
549 },
550 },
551 &NestedSliceOfSimple{
552 A: []Simple{Simple{I: testInt64}, Simple{I: testInt64}},
553 },
554 },
555 {
556 "nested with multiple anonymous fields",
557 &pb.EntityProto{
558 Key: keyToProto("some-app-id", testKey0),
559 Property: []*pb.Property{
560 &pb.Property{
561 Name: &fieldNameI,
562 Value: &pb.PropertyValue{
563 Int64Value: &testInt64,
564 },
565 },
566 &pb.Property{
567 Name: &fieldNameS,
568 Value: &pb.PropertyValue{
569 StringValue: &testString2,
570 },
571 },
572 &pb.Property{
573 Name: &fieldNameSS,
574 Value: &pb.PropertyValue{
575 StringValue: &testString3,
576 },
577 },
578 &pb.Property{
579 Name: &fieldNameX,
580 Value: &pb.PropertyValue{
581 StringValue: &testString2,
582 },
583 },
584 },
585 },
586 &MultiAnonymous{
587 Simple: Simple{I: testInt64},
588 SimpleTwoFields: SimpleTwoFields{S: testString2, SS: testString3},
589 X: testString2,
590 },
591 },
592 {
593 "nested with dotted field tag",
594 &pb.EntityProto{
595 Key: keyToProto("some-app-id", testKey0),
596 Property: []*pb.Property{
597 &pb.Property{
598 Name: &fieldNameA,
599 Meaning: &entityProtoMeaning,
600 Value: &pb.PropertyValue{
601 StringValue: &bDotBEntityProto,
602 },
603 },
604 },
605 },
606 &ABDotB{
607 A: BDotB{
608 B: testString2,
609 },
610 },
611 },
612 {
613 "nested entity with key",
614 &pb.EntityProto{
615 Key: keyToProto("some-app-id", testKey0),
616 Property: []*pb.Property{
617 &pb.Property{
618 Name: &fieldNameY,
619 Value: &pb.PropertyValue{
620 StringValue: &testString2,
621 },
622 },
623 &pb.Property{
624 Name: &fieldNameN,
625 Meaning: &entityProtoMeaning,
626 Value: &pb.PropertyValue{
627 StringValue: &withKeyEntityProto,
628 },
629 },
630 },
631 },
632 &NestedWithKey{
633 Y: testString2,
634 N: WithKey{
635 X: testString3,
636 I: testInt64,
637 K: testKey1a,
638 },
639 },
640 },
641 }
642
643 for _, tc := range testCases {
644 dst := reflect.New(reflect.TypeOf(tc.want).Elem()).Interface()
645 err := loadEntity(dst, tc.src)
646 if err != nil {
647 t.Errorf("loadEntity: %s: %v", tc.desc, err)
648 continue
649 }
650
651 if !reflect.DeepEqual(tc.want, dst) {
652 t.Errorf("%s: compare:\ngot: %#v\nwant: %#v", tc.desc, dst, tc.want)
653 }
654 }
655 }
0 // Copyright 2016 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import "context"
7
8 // Datastore kinds for the metadata entities.
9 const (
10 namespaceKind = "__namespace__"
11 kindKind = "__kind__"
12 propertyKind = "__property__"
13 )
14
15 // Namespaces returns all the datastore namespaces.
16 func Namespaces(ctx context.Context) ([]string, error) {
17 // TODO(djd): Support range queries.
18 q := NewQuery(namespaceKind).KeysOnly()
19 keys, err := q.GetAll(ctx, nil)
20 if err != nil {
21 return nil, err
22 }
23 // The empty namespace key uses a numeric ID (==1), but luckily
24 // the string ID defaults to "" for numeric IDs anyway.
25 return keyNames(keys), nil
26 }
27
28 // Kinds returns the names of all the kinds in the current namespace.
29 func Kinds(ctx context.Context) ([]string, error) {
30 // TODO(djd): Support range queries.
31 q := NewQuery(kindKind).KeysOnly()
32 keys, err := q.GetAll(ctx, nil)
33 if err != nil {
34 return nil, err
35 }
36 return keyNames(keys), nil
37 }
38
39 // keyNames returns a slice of the provided keys' names (string IDs).
40 func keyNames(keys []*Key) []string {
41 n := make([]string, 0, len(keys))
42 for _, k := range keys {
43 n = append(n, k.StringID())
44 }
45 return n
46 }
47
48 // KindProperties returns all the indexed properties for the given kind.
49 // The properties are returned as a map of property names to a slice of the
50 // representation types. The representation types for the supported Go property
51 // types are:
52 //
53 // "INT64": signed integers and time.Time
54 // "DOUBLE": float32 and float64
55 // "BOOLEAN": bool
56 // "STRING": string, []byte and ByteString
57 // "POINT": appengine.GeoPoint
58 // "REFERENCE": *Key
59 // "USER": (not used in the Go runtime)
60 func KindProperties(ctx context.Context, kind string) (map[string][]string, error) {
61 // TODO(djd): Support range queries.
62 kindKey := NewKey(ctx, kindKind, kind, 0, nil)
63 q := NewQuery(propertyKind).Ancestor(kindKey)
64
65 propMap := map[string][]string{}
66 props := []struct {
67 Repr []string `datastore:"property_representation"`
68 }{}
69
70 keys, err := q.GetAll(ctx, &props)
71 if err != nil {
72 return nil, err
73 }
74 for i, p := range props {
75 propMap[keys[i].StringID()] = p.Repr
76 }
77 return propMap, nil
78 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "fmt"
8 "reflect"
9 "strings"
10 "sync"
11 "unicode"
12 )
13
14 // Entities with more than this many indexed properties will not be saved.
15 const maxIndexedProperties = 20000
16
17 // []byte fields more than 1 megabyte long will not be loaded or saved.
18 const maxBlobLen = 1 << 20
19
20 // Property is a name/value pair plus some metadata. A datastore entity's
21 // contents are loaded and saved as a sequence of Properties. An entity can
22 // have multiple Properties with the same name, provided that p.Multiple is
23 // true on all of that entity's Properties with that name.
24 type Property struct {
25 // Name is the property name.
26 Name string
27 // Value is the property value. The valid types are:
28 // - int64
29 // - bool
30 // - string
31 // - float64
32 // - ByteString
33 // - *Key
34 // - time.Time
35 // - appengine.BlobKey
36 // - appengine.GeoPoint
37 // - []byte (up to 1 megabyte in length)
38 // - *Entity (representing a nested struct)
39 // This set is smaller than the set of valid struct field types that the
40 // datastore can load and save. A Property Value cannot be a slice (apart
41 // from []byte); use multiple Properties instead. Also, a Value's type
42 // must be explicitly on the list above; it is not sufficient for the
43 // underlying type to be on that list. For example, a Value of "type
44 // myInt64 int64" is invalid. Smaller-width integers and floats are also
45 // invalid. Again, this is more restrictive than the set of valid struct
46 // field types.
47 //
48 // A Value will have an opaque type when loading entities from an index,
49 // such as via a projection query. Load entities into a struct instead
50 // of a PropertyLoadSaver when using a projection query.
51 //
52 // A Value may also be the nil interface value; this is equivalent to
53 // Python's None but not directly representable by a Go struct. Loading
54 // a nil-valued property into a struct will set that field to the zero
55 // value.
56 Value interface{}
57 // NoIndex is whether the datastore cannot index this property.
58 NoIndex bool
59 // Multiple is whether the entity can have multiple properties with
60 // the same name. Even if a particular instance only has one property with
61 // a certain name, Multiple should be true if a struct would best represent
62 // it as a field of type []T instead of type T.
63 Multiple bool
64 }
65
66 // An Entity is the value type for a nested struct.
67 // This type is only used for a Property's Value.
68 type Entity struct {
69 Key *Key
70 Properties []Property
71 }
72
73 // ByteString is a short byte slice (up to 1500 bytes) that can be indexed.
74 type ByteString []byte
75
76 // PropertyLoadSaver can be converted from and to a slice of Properties.
77 type PropertyLoadSaver interface {
78 Load([]Property) error
79 Save() ([]Property, error)
80 }
81
82 // PropertyList converts a []Property to implement PropertyLoadSaver.
83 type PropertyList []Property
84
85 var (
86 typeOfPropertyLoadSaver = reflect.TypeOf((*PropertyLoadSaver)(nil)).Elem()
87 typeOfPropertyList = reflect.TypeOf(PropertyList(nil))
88 )
89
90 // Load loads all of the provided properties into l.
91 // It does not first reset *l to an empty slice.
92 func (l *PropertyList) Load(p []Property) error {
93 *l = append(*l, p...)
94 return nil
95 }
96
97 // Save saves all of l's properties as a slice or Properties.
98 func (l *PropertyList) Save() ([]Property, error) {
99 return *l, nil
100 }
101
102 // validPropertyName returns whether name consists of one or more valid Go
103 // identifiers joined by ".".
104 func validPropertyName(name string) bool {
105 if name == "" {
106 return false
107 }
108 for _, s := range strings.Split(name, ".") {
109 if s == "" {
110 return false
111 }
112 first := true
113 for _, c := range s {
114 if first {
115 first = false
116 if c != '_' && !unicode.IsLetter(c) {
117 return false
118 }
119 } else {
120 if c != '_' && !unicode.IsLetter(c) && !unicode.IsDigit(c) {
121 return false
122 }
123 }
124 }
125 }
126 return true
127 }
128
129 // structCodec describes how to convert a struct to and from a sequence of
130 // properties.
131 type structCodec struct {
132 // fields gives the field codec for the structTag with the given name.
133 fields map[string]fieldCodec
134 // hasSlice is whether a struct or any of its nested or embedded structs
135 // has a slice-typed field (other than []byte).
136 hasSlice bool
137 // keyField is the index of a *Key field with structTag __key__.
138 // This field is not relevant for the top level struct, only for
139 // nested structs.
140 keyField int
141 // complete is whether the structCodec is complete. An incomplete
142 // structCodec may be encountered when walking a recursive struct.
143 complete bool
144 }
145
146 // fieldCodec is a struct field's index and, if that struct field's type is
147 // itself a struct, that substruct's structCodec.
148 type fieldCodec struct {
149 // path is the index path to the field
150 path []int
151 noIndex bool
152 // omitEmpty indicates that the field should be omitted on save
153 // if empty.
154 omitEmpty bool
155 // structCodec is the codec fot the struct field at index 'path',
156 // or nil if the field is not a struct.
157 structCodec *structCodec
158 }
159
160 // structCodecs collects the structCodecs that have already been calculated.
161 var (
162 structCodecsMutex sync.Mutex
163 structCodecs = make(map[reflect.Type]*structCodec)
164 )
165
166 // getStructCodec returns the structCodec for the given struct type.
167 func getStructCodec(t reflect.Type) (*structCodec, error) {
168 structCodecsMutex.Lock()
169 defer structCodecsMutex.Unlock()
170 return getStructCodecLocked(t)
171 }
172
173 // getStructCodecLocked implements getStructCodec. The structCodecsMutex must
174 // be held when calling this function.
175 func getStructCodecLocked(t reflect.Type) (ret *structCodec, retErr error) {
176 c, ok := structCodecs[t]
177 if ok {
178 return c, nil
179 }
180 c = &structCodec{
181 fields: make(map[string]fieldCodec),
182 // We initialize keyField to -1 so that the zero-value is not
183 // misinterpreted as index 0.
184 keyField: -1,
185 }
186
187 // Add c to the structCodecs map before we are sure it is good. If t is
188 // a recursive type, it needs to find the incomplete entry for itself in
189 // the map.
190 structCodecs[t] = c
191 defer func() {
192 if retErr != nil {
193 delete(structCodecs, t)
194 }
195 }()
196
197 for i := 0; i < t.NumField(); i++ {
198 f := t.Field(i)
199 // Skip unexported fields.
200 // Note that if f is an anonymous, unexported struct field,
201 // we will promote its fields.
202 if f.PkgPath != "" && !f.Anonymous {
203 continue
204 }
205
206 tags := strings.Split(f.Tag.Get("datastore"), ",")
207 name := tags[0]
208 opts := make(map[string]bool)
209 for _, t := range tags[1:] {
210 opts[t] = true
211 }
212 switch {
213 case name == "":
214 if !f.Anonymous {
215 name = f.Name
216 }
217 case name == "-":
218 continue
219 case name == "__key__":
220 if f.Type != typeOfKeyPtr {
221 return nil, fmt.Errorf("datastore: __key__ field on struct %v is not a *datastore.Key", t)
222 }
223 c.keyField = i
224 case !validPropertyName(name):
225 return nil, fmt.Errorf("datastore: struct tag has invalid property name: %q", name)
226 }
227
228 substructType, fIsSlice := reflect.Type(nil), false
229 switch f.Type.Kind() {
230 case reflect.Struct:
231 substructType = f.Type
232 case reflect.Slice:
233 if f.Type.Elem().Kind() == reflect.Struct {
234 substructType = f.Type.Elem()
235 }
236 fIsSlice = f.Type != typeOfByteSlice
237 c.hasSlice = c.hasSlice || fIsSlice
238 }
239
240 var sub *structCodec
241 if substructType != nil && substructType != typeOfTime && substructType != typeOfGeoPoint {
242 var err error
243 sub, err = getStructCodecLocked(substructType)
244 if err != nil {
245 return nil, err
246 }
247 if !sub.complete {
248 return nil, fmt.Errorf("datastore: recursive struct: field %q", f.Name)
249 }
250 if fIsSlice && sub.hasSlice {
251 return nil, fmt.Errorf(
252 "datastore: flattening nested structs leads to a slice of slices: field %q", f.Name)
253 }
254 c.hasSlice = c.hasSlice || sub.hasSlice
255 // If f is an anonymous struct field, we promote the substruct's fields up to this level
256 // in the linked list of struct codecs.
257 if f.Anonymous {
258 for subname, subfield := range sub.fields {
259 if name != "" {
260 subname = name + "." + subname
261 }
262 if _, ok := c.fields[subname]; ok {
263 return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", subname)
264 }
265 c.fields[subname] = fieldCodec{
266 path: append([]int{i}, subfield.path...),
267 noIndex: subfield.noIndex || opts["noindex"],
268 omitEmpty: subfield.omitEmpty,
269 structCodec: subfield.structCodec,
270 }
271 }
272 continue
273 }
274 }
275
276 if _, ok := c.fields[name]; ok {
277 return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", name)
278 }
279 c.fields[name] = fieldCodec{
280 path: []int{i},
281 noIndex: opts["noindex"],
282 omitEmpty: opts["omitempty"],
283 structCodec: sub,
284 }
285 }
286 c.complete = true
287 return c, nil
288 }
289
290 // structPLS adapts a struct to be a PropertyLoadSaver.
291 type structPLS struct {
292 v reflect.Value
293 codec *structCodec
294 }
295
296 // newStructPLS returns a structPLS, which implements the
297 // PropertyLoadSaver interface, for the struct pointer p.
298 func newStructPLS(p interface{}) (*structPLS, error) {
299 v := reflect.ValueOf(p)
300 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
301 return nil, ErrInvalidEntityType
302 }
303 v = v.Elem()
304 codec, err := getStructCodec(v.Type())
305 if err != nil {
306 return nil, err
307 }
308 return &structPLS{v, codec}, nil
309 }
310
311 // LoadStruct loads the properties from p to dst.
312 // dst must be a struct pointer.
313 func LoadStruct(dst interface{}, p []Property) error {
314 x, err := newStructPLS(dst)
315 if err != nil {
316 return err
317 }
318 return x.Load(p)
319 }
320
321 // SaveStruct returns the properties from src as a slice of Properties.
322 // src must be a struct pointer.
323 func SaveStruct(src interface{}) ([]Property, error) {
324 x, err := newStructPLS(src)
325 if err != nil {
326 return nil, err
327 }
328 return x.Save()
329 }
0 // Copyright 2011 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "reflect"
8 "sort"
9 "testing"
10 "time"
11
12 "google.golang.org/appengine/v2"
13 )
14
15 func TestValidPropertyName(t *testing.T) {
16 testCases := []struct {
17 name string
18 want bool
19 }{
20 // Invalid names.
21 {"", false},
22 {"'", false},
23 {".", false},
24 {"..", false},
25 {".foo", false},
26 {"0", false},
27 {"00", false},
28 {"X.X.4.X.X", false},
29 {"\n", false},
30 {"\x00", false},
31 {"abc\xffz", false},
32 {"foo.", false},
33 {"foo..", false},
34 {"foo..bar", false},
35 {"☃", false},
36 {`"`, false},
37 // Valid names.
38 {"AB", true},
39 {"Abc", true},
40 {"X.X.X.X.X", true},
41 {"_", true},
42 {"_0", true},
43 {"a", true},
44 {"a_B", true},
45 {"f00", true},
46 {"f0o", true},
47 {"fo0", true},
48 {"foo", true},
49 {"foo.bar", true},
50 {"foo.bar.baz", true},
51 {"世界", true},
52 }
53 for _, tc := range testCases {
54 got := validPropertyName(tc.name)
55 if got != tc.want {
56 t.Errorf("%q: got %v, want %v", tc.name, got, tc.want)
57 }
58 }
59 }
60
61 func TestStructCodec(t *testing.T) {
62 type oStruct struct {
63 O int
64 }
65 type pStruct struct {
66 P int
67 Q int
68 }
69 type rStruct struct {
70 R int
71 S pStruct
72 T oStruct
73 oStruct
74 }
75 type uStruct struct {
76 U int
77 v int
78 }
79 type vStruct struct {
80 V string `datastore:",noindex"`
81 }
82 oStructCodec := &structCodec{
83 fields: map[string]fieldCodec{
84 "O": {path: []int{0}},
85 },
86 complete: true,
87 }
88 pStructCodec := &structCodec{
89 fields: map[string]fieldCodec{
90 "P": {path: []int{0}},
91 "Q": {path: []int{1}},
92 },
93 complete: true,
94 }
95 rStructCodec := &structCodec{
96 fields: map[string]fieldCodec{
97 "R": {path: []int{0}},
98 "S": {path: []int{1}, structCodec: pStructCodec},
99 "T": {path: []int{2}, structCodec: oStructCodec},
100 "O": {path: []int{3, 0}},
101 },
102 complete: true,
103 }
104 uStructCodec := &structCodec{
105 fields: map[string]fieldCodec{
106 "U": {path: []int{0}},
107 },
108 complete: true,
109 }
110 vStructCodec := &structCodec{
111 fields: map[string]fieldCodec{
112 "V": {path: []int{0}, noIndex: true},
113 },
114 complete: true,
115 }
116
117 testCases := []struct {
118 desc string
119 structValue interface{}
120 want *structCodec
121 }{
122 {
123 "oStruct",
124 oStruct{},
125 oStructCodec,
126 },
127 {
128 "pStruct",
129 pStruct{},
130 pStructCodec,
131 },
132 {
133 "rStruct",
134 rStruct{},
135 rStructCodec,
136 },
137 {
138 "uStruct",
139 uStruct{},
140 uStructCodec,
141 },
142 {
143 "non-basic fields",
144 struct {
145 B appengine.BlobKey
146 K *Key
147 T time.Time
148 }{},
149 &structCodec{
150 fields: map[string]fieldCodec{
151 "B": {path: []int{0}},
152 "K": {path: []int{1}},
153 "T": {path: []int{2}},
154 },
155 complete: true,
156 },
157 },
158 {
159 "struct tags with ignored embed",
160 struct {
161 A int `datastore:"a,noindex"`
162 B int `datastore:"b"`
163 C int `datastore:",noindex"`
164 D int `datastore:""`
165 E int
166 I int `datastore:"-"`
167 J int `datastore:",noindex" json:"j"`
168 oStruct `datastore:"-"`
169 }{},
170 &structCodec{
171 fields: map[string]fieldCodec{
172 "a": {path: []int{0}, noIndex: true},
173 "b": {path: []int{1}},
174 "C": {path: []int{2}, noIndex: true},
175 "D": {path: []int{3}},
176 "E": {path: []int{4}},
177 "J": {path: []int{6}, noIndex: true},
178 },
179 complete: true,
180 },
181 },
182 {
183 "unexported fields",
184 struct {
185 A int
186 b int
187 C int `datastore:"x"`
188 d int `datastore:"Y"`
189 }{},
190 &structCodec{
191 fields: map[string]fieldCodec{
192 "A": {path: []int{0}},
193 "x": {path: []int{2}},
194 },
195 complete: true,
196 },
197 },
198 {
199 "nested and embedded structs",
200 struct {
201 A int
202 B int
203 CC oStruct
204 DDD rStruct
205 oStruct
206 }{},
207 &structCodec{
208 fields: map[string]fieldCodec{
209 "A": {path: []int{0}},
210 "B": {path: []int{1}},
211 "CC": {path: []int{2}, structCodec: oStructCodec},
212 "DDD": {path: []int{3}, structCodec: rStructCodec},
213 "O": {path: []int{4, 0}},
214 },
215 complete: true,
216 },
217 },
218 {
219 "struct tags with nested and embedded structs",
220 struct {
221 A int `datastore:"-"`
222 B int `datastore:"w"`
223 C oStruct `datastore:"xx"`
224 D rStruct `datastore:"y"`
225 oStruct `datastore:"z"`
226 }{},
227 &structCodec{
228 fields: map[string]fieldCodec{
229 "w": {path: []int{1}},
230 "xx": {path: []int{2}, structCodec: oStructCodec},
231 "y": {path: []int{3}, structCodec: rStructCodec},
232 "z.O": {path: []int{4, 0}},
233 },
234 complete: true,
235 },
236 },
237 {
238 "unexported nested and embedded structs",
239 struct {
240 a int
241 B int
242 c uStruct
243 D uStruct
244 uStruct
245 }{},
246 &structCodec{
247 fields: map[string]fieldCodec{
248 "B": {path: []int{1}},
249 "D": {path: []int{3}, structCodec: uStructCodec},
250 "U": {path: []int{4, 0}},
251 },
252 complete: true,
253 },
254 },
255 {
256 "noindex nested struct",
257 struct {
258 A oStruct `datastore:",noindex"`
259 }{},
260 &structCodec{
261 fields: map[string]fieldCodec{
262 "A": {path: []int{0}, structCodec: oStructCodec, noIndex: true},
263 },
264 complete: true,
265 },
266 },
267 {
268 "noindex slice",
269 struct {
270 A []string `datastore:",noindex"`
271 }{},
272 &structCodec{
273 fields: map[string]fieldCodec{
274 "A": {path: []int{0}, noIndex: true},
275 },
276 hasSlice: true,
277 complete: true,
278 },
279 },
280 {
281 "noindex embedded struct slice",
282 struct {
283 // vStruct has a single field, V, also with noindex.
284 A []vStruct `datastore:",noindex"`
285 }{},
286 &structCodec{
287 fields: map[string]fieldCodec{
288 "A": {path: []int{0}, structCodec: vStructCodec, noIndex: true},
289 },
290 hasSlice: true,
291 complete: true,
292 },
293 },
294 }
295
296 for _, tc := range testCases {
297 got, err := getStructCodec(reflect.TypeOf(tc.structValue))
298 if err != nil {
299 t.Errorf("%s: getStructCodec: %v", tc.desc, err)
300 continue
301 }
302 // can't reflect.DeepEqual b/c element order in fields map may differ
303 if !isEqualStructCodec(got, tc.want) {
304 t.Errorf("%s\ngot %+v\nwant %+v\n", tc.desc, got, tc.want)
305 }
306 }
307 }
308
309 func isEqualStructCodec(got, want *structCodec) bool {
310 if got.complete != want.complete {
311 return false
312 }
313 if got.hasSlice != want.hasSlice {
314 return false
315 }
316 if len(got.fields) != len(want.fields) {
317 return false
318 }
319 for name, wantF := range want.fields {
320 gotF := got.fields[name]
321 if !reflect.DeepEqual(wantF.path, gotF.path) {
322 return false
323 }
324 if wantF.noIndex != gotF.noIndex {
325 return false
326 }
327 if wantF.structCodec != nil {
328 if gotF.structCodec == nil {
329 return false
330 }
331 if !isEqualStructCodec(gotF.structCodec, wantF.structCodec) {
332 return false
333 }
334 }
335 }
336
337 return true
338 }
339
340 func TestRepeatedPropertyName(t *testing.T) {
341 good := []interface{}{
342 struct {
343 A int `datastore:"-"`
344 }{},
345 struct {
346 A int `datastore:"b"`
347 B int
348 }{},
349 struct {
350 A int
351 B int `datastore:"B"`
352 }{},
353 struct {
354 A int `datastore:"B"`
355 B int `datastore:"-"`
356 }{},
357 struct {
358 A int `datastore:"-"`
359 B int `datastore:"A"`
360 }{},
361 struct {
362 A int `datastore:"B"`
363 B int `datastore:"A"`
364 }{},
365 struct {
366 A int `datastore:"B"`
367 B int `datastore:"C"`
368 C int `datastore:"A"`
369 }{},
370 struct {
371 A int `datastore:"B"`
372 B int `datastore:"C"`
373 C int `datastore:"D"`
374 }{},
375 }
376 bad := []interface{}{
377 struct {
378 A int `datastore:"B"`
379 B int
380 }{},
381 struct {
382 A int
383 B int `datastore:"A"`
384 }{},
385 struct {
386 A int `datastore:"C"`
387 B int `datastore:"C"`
388 }{},
389 struct {
390 A int `datastore:"B"`
391 B int `datastore:"C"`
392 C int `datastore:"B"`
393 }{},
394 }
395 testGetStructCodec(t, good, bad)
396 }
397
398 func TestFlatteningNestedStructs(t *testing.T) {
399 type DeepGood struct {
400 A struct {
401 B []struct {
402 C struct {
403 D int
404 }
405 }
406 }
407 }
408 type DeepBad struct {
409 A struct {
410 B []struct {
411 C struct {
412 D []int
413 }
414 }
415 }
416 }
417 type ISay struct {
418 Tomato int
419 }
420 type YouSay struct {
421 Tomato int
422 }
423 type Tweedledee struct {
424 Dee int `datastore:"D"`
425 }
426 type Tweedledum struct {
427 Dum int `datastore:"D"`
428 }
429
430 good := []interface{}{
431 struct {
432 X []struct {
433 Y string
434 }
435 }{},
436 struct {
437 X []struct {
438 Y []byte
439 }
440 }{},
441 struct {
442 P []int
443 X struct {
444 Y []int
445 }
446 }{},
447 struct {
448 X struct {
449 Y []int
450 }
451 Q []int
452 }{},
453 struct {
454 P []int
455 X struct {
456 Y []int
457 }
458 Q []int
459 }{},
460 struct {
461 DeepGood
462 }{},
463 struct {
464 DG DeepGood
465 }{},
466 struct {
467 Foo struct {
468 Z int
469 } `datastore:"A"`
470 Bar struct {
471 Z int
472 } `datastore:"B"`
473 }{},
474 }
475 bad := []interface{}{
476 struct {
477 X []struct {
478 Y []string
479 }
480 }{},
481 struct {
482 X []struct {
483 Y []int
484 }
485 }{},
486 struct {
487 DeepBad
488 }{},
489 struct {
490 DB DeepBad
491 }{},
492 struct {
493 ISay
494 YouSay
495 }{},
496 struct {
497 Tweedledee
498 Tweedledum
499 }{},
500 struct {
501 Foo struct {
502 Z int
503 } `datastore:"A"`
504 Bar struct {
505 Z int
506 } `datastore:"A"`
507 }{},
508 }
509 testGetStructCodec(t, good, bad)
510 }
511
512 func testGetStructCodec(t *testing.T, good []interface{}, bad []interface{}) {
513 for _, x := range good {
514 if _, err := getStructCodec(reflect.TypeOf(x)); err != nil {
515 t.Errorf("type %T: got non-nil error (%s), want nil", x, err)
516 }
517 }
518 for _, x := range bad {
519 if _, err := getStructCodec(reflect.TypeOf(x)); err == nil {
520 t.Errorf("type %T: got nil error, want non-nil", x)
521 }
522 }
523 }
524
525 func TestNilKeyIsStored(t *testing.T) {
526 x := struct {
527 K *Key
528 I int
529 }{}
530 p := PropertyList{}
531 // Save x as properties.
532 p1, _ := SaveStruct(&x)
533 p.Load(p1)
534 // Set x's fields to non-zero.
535 x.K = &Key{}
536 x.I = 2
537 // Load x from properties.
538 p2, _ := p.Save()
539 LoadStruct(&x, p2)
540 // Check that x's fields were set to zero.
541 if x.K != nil {
542 t.Errorf("K field was not zero")
543 }
544 if x.I != 0 {
545 t.Errorf("I field was not zero")
546 }
547 }
548
549 func TestSaveStructOmitEmpty(t *testing.T) {
550 // Expected props names are sorted alphabetically
551 expectedPropNamesForSingles := []string{"EmptyValue", "NonEmptyValue", "OmitEmptyWithValue"}
552 expectedPropNamesForSlices := []string{"NonEmptyValue", "NonEmptyValue", "OmitEmptyWithValue", "OmitEmptyWithValue"}
553
554 testOmitted := func(expectedPropNames []string, src interface{}) {
555 // t.Helper() - this is available from Go version 1.9, but we also support Go versions 1.6, 1.7, 1.8
556 if props, err := SaveStruct(src); err != nil {
557 t.Fatal(err)
558 } else {
559 // Collect names for reporting if diffs from expected and for easier sorting
560 actualPropNames := make([]string, len(props))
561 for i := range props {
562 actualPropNames[i] = props[i].Name
563 }
564 // Sort actuals for comparing with already sorted expected names
565 sort.Sort(sort.StringSlice(actualPropNames))
566 if !reflect.DeepEqual(actualPropNames, expectedPropNames) {
567 t.Errorf("Expected this properties: %v, got: %v", expectedPropNames, actualPropNames)
568 }
569 }
570 }
571
572 testOmitted(expectedPropNamesForSingles, &struct {
573 EmptyValue int
574 NonEmptyValue int
575 OmitEmptyNoValue int `datastore:",omitempty"`
576 OmitEmptyWithValue int `datastore:",omitempty"`
577 }{
578 NonEmptyValue: 1,
579 OmitEmptyWithValue: 2,
580 })
581
582 testOmitted(expectedPropNamesForSlices, &struct {
583 EmptyValue []int
584 NonEmptyValue []int
585 OmitEmptyNoValue []int `datastore:",omitempty"`
586 OmitEmptyWithValue []int `datastore:",omitempty"`
587 }{
588 NonEmptyValue: []int{1, 2},
589 OmitEmptyWithValue: []int{3, 4},
590 })
591
592 testOmitted(expectedPropNamesForSingles, &struct {
593 EmptyValue bool
594 NonEmptyValue bool
595 OmitEmptyNoValue bool `datastore:",omitempty"`
596 OmitEmptyWithValue bool `datastore:",omitempty"`
597 }{
598 NonEmptyValue: true,
599 OmitEmptyWithValue: true,
600 })
601
602 testOmitted(expectedPropNamesForSlices, &struct {
603 EmptyValue []bool
604 NonEmptyValue []bool
605 OmitEmptyNoValue []bool `datastore:",omitempty"`
606 OmitEmptyWithValue []bool `datastore:",omitempty"`
607 }{
608 NonEmptyValue: []bool{true, true},
609 OmitEmptyWithValue: []bool{true, true},
610 })
611
612 testOmitted(expectedPropNamesForSingles, &struct {
613 EmptyValue string
614 NonEmptyValue string
615 OmitEmptyNoValue string `datastore:",omitempty"`
616 OmitEmptyWithValue string `datastore:",omitempty"`
617 }{
618 NonEmptyValue: "s",
619 OmitEmptyWithValue: "s",
620 })
621
622 testOmitted(expectedPropNamesForSlices, &struct {
623 EmptyValue []string
624 NonEmptyValue []string
625 OmitEmptyNoValue []string `datastore:",omitempty"`
626 OmitEmptyWithValue []string `datastore:",omitempty"`
627 }{
628 NonEmptyValue: []string{"s1", "s2"},
629 OmitEmptyWithValue: []string{"s3", "s4"},
630 })
631
632 testOmitted(expectedPropNamesForSingles, &struct {
633 EmptyValue float32
634 NonEmptyValue float32
635 OmitEmptyNoValue float32 `datastore:",omitempty"`
636 OmitEmptyWithValue float32 `datastore:",omitempty"`
637 }{
638 NonEmptyValue: 1.1,
639 OmitEmptyWithValue: 1.2,
640 })
641
642 testOmitted(expectedPropNamesForSlices, &struct {
643 EmptyValue []float32
644 NonEmptyValue []float32
645 OmitEmptyNoValue []float32 `datastore:",omitempty"`
646 OmitEmptyWithValue []float32 `datastore:",omitempty"`
647 }{
648 NonEmptyValue: []float32{1.1, 2.2},
649 OmitEmptyWithValue: []float32{3.3, 4.4},
650 })
651
652 testOmitted(expectedPropNamesForSingles, &struct {
653 EmptyValue time.Time
654 NonEmptyValue time.Time
655 OmitEmptyNoValue time.Time `datastore:",omitempty"`
656 OmitEmptyWithValue time.Time `datastore:",omitempty"`
657 }{
658 NonEmptyValue: now,
659 OmitEmptyWithValue: now,
660 })
661
662 testOmitted(expectedPropNamesForSlices, &struct {
663 EmptyValue []time.Time
664 NonEmptyValue []time.Time
665 OmitEmptyNoValue []time.Time `datastore:",omitempty"`
666 OmitEmptyWithValue []time.Time `datastore:",omitempty"`
667 }{
668 NonEmptyValue: []time.Time{now, now},
669 OmitEmptyWithValue: []time.Time{now, now},
670 })
671 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "context"
8 "encoding/base64"
9 "errors"
10 "fmt"
11 "math"
12 "reflect"
13 "strings"
14
15 "github.com/golang/protobuf/proto"
16
17 "google.golang.org/appengine/v2/internal"
18 pb "google.golang.org/appengine/v2/internal/datastore"
19 )
20
21 type operator int
22
23 const (
24 lessThan operator = iota
25 lessEq
26 equal
27 greaterEq
28 greaterThan
29 )
30
31 var operatorToProto = map[operator]*pb.Query_Filter_Operator{
32 lessThan: pb.Query_Filter_LESS_THAN.Enum(),
33 lessEq: pb.Query_Filter_LESS_THAN_OR_EQUAL.Enum(),
34 equal: pb.Query_Filter_EQUAL.Enum(),
35 greaterEq: pb.Query_Filter_GREATER_THAN_OR_EQUAL.Enum(),
36 greaterThan: pb.Query_Filter_GREATER_THAN.Enum(),
37 }
38
39 // filter is a conditional filter on query results.
40 type filter struct {
41 FieldName string
42 Op operator
43 Value interface{}
44 }
45
46 type sortDirection int
47
48 const (
49 ascending sortDirection = iota
50 descending
51 )
52
53 var sortDirectionToProto = map[sortDirection]*pb.Query_Order_Direction{
54 ascending: pb.Query_Order_ASCENDING.Enum(),
55 descending: pb.Query_Order_DESCENDING.Enum(),
56 }
57
58 // order is a sort order on query results.
59 type order struct {
60 FieldName string
61 Direction sortDirection
62 }
63
64 // NewQuery creates a new Query for a specific entity kind.
65 //
66 // An empty kind means to return all entities, including entities created and
67 // managed by other App Engine features, and is called a kindless query.
68 // Kindless queries cannot include filters or sort orders on property values.
69 func NewQuery(kind string) *Query {
70 return &Query{
71 kind: kind,
72 limit: -1,
73 }
74 }
75
76 // Query represents a datastore query.
77 type Query struct {
78 kind string
79 ancestor *Key
80 filter []filter
81 order []order
82 projection []string
83
84 distinct bool
85 distinctOn []string
86 keysOnly bool
87 eventual bool
88 limit int32
89 offset int32
90 count int32
91 start *pb.CompiledCursor
92 end *pb.CompiledCursor
93
94 err error
95 }
96
97 func (q *Query) clone() *Query {
98 x := *q
99 // Copy the contents of the slice-typed fields to a new backing store.
100 if len(q.filter) > 0 {
101 x.filter = make([]filter, len(q.filter))
102 copy(x.filter, q.filter)
103 }
104 if len(q.order) > 0 {
105 x.order = make([]order, len(q.order))
106 copy(x.order, q.order)
107 }
108 return &x
109 }
110
111 // Ancestor returns a derivative query with an ancestor filter.
112 // The ancestor should not be nil.
113 func (q *Query) Ancestor(ancestor *Key) *Query {
114 q = q.clone()
115 if ancestor == nil {
116 q.err = errors.New("datastore: nil query ancestor")
117 return q
118 }
119 q.ancestor = ancestor
120 return q
121 }
122
123 // EventualConsistency returns a derivative query that returns eventually
124 // consistent results.
125 // It only has an effect on ancestor queries.
126 func (q *Query) EventualConsistency() *Query {
127 q = q.clone()
128 q.eventual = true
129 return q
130 }
131
132 // Filter returns a derivative query with a field-based filter.
133 // The filterStr argument must be a field name followed by optional space,
134 // followed by an operator, one of ">", "<", ">=", "<=", or "=".
135 // Fields are compared against the provided value using the operator.
136 // Multiple filters are AND'ed together.
137 func (q *Query) Filter(filterStr string, value interface{}) *Query {
138 q = q.clone()
139 filterStr = strings.TrimSpace(filterStr)
140 if len(filterStr) < 1 {
141 q.err = errors.New("datastore: invalid filter: " + filterStr)
142 return q
143 }
144 f := filter{
145 FieldName: strings.TrimRight(filterStr, " ><=!"),
146 Value: value,
147 }
148 switch op := strings.TrimSpace(filterStr[len(f.FieldName):]); op {
149 case "<=":
150 f.Op = lessEq
151 case ">=":
152 f.Op = greaterEq
153 case "<":
154 f.Op = lessThan
155 case ">":
156 f.Op = greaterThan
157 case "=":
158 f.Op = equal
159 default:
160 q.err = fmt.Errorf("datastore: invalid operator %q in filter %q", op, filterStr)
161 return q
162 }
163 q.filter = append(q.filter, f)
164 return q
165 }
166
167 // Order returns a derivative query with a field-based sort order. Orders are
168 // applied in the order they are added. The default order is ascending; to sort
169 // in descending order prefix the fieldName with a minus sign (-).
170 func (q *Query) Order(fieldName string) *Query {
171 q = q.clone()
172 fieldName = strings.TrimSpace(fieldName)
173 o := order{
174 Direction: ascending,
175 FieldName: fieldName,
176 }
177 if strings.HasPrefix(fieldName, "-") {
178 o.Direction = descending
179 o.FieldName = strings.TrimSpace(fieldName[1:])
180 } else if strings.HasPrefix(fieldName, "+") {
181 q.err = fmt.Errorf("datastore: invalid order: %q", fieldName)
182 return q
183 }
184 if len(o.FieldName) == 0 {
185 q.err = errors.New("datastore: empty order")
186 return q
187 }
188 q.order = append(q.order, o)
189 return q
190 }
191
192 // Project returns a derivative query that yields only the given fields. It
193 // cannot be used with KeysOnly.
194 func (q *Query) Project(fieldNames ...string) *Query {
195 q = q.clone()
196 q.projection = append([]string(nil), fieldNames...)
197 return q
198 }
199
200 // Distinct returns a derivative query that yields de-duplicated entities with
201 // respect to the set of projected fields. It is only used for projection
202 // queries. Distinct cannot be used with DistinctOn.
203 func (q *Query) Distinct() *Query {
204 q = q.clone()
205 q.distinct = true
206 return q
207 }
208
209 // DistinctOn returns a derivative query that yields de-duplicated entities with
210 // respect to the set of the specified fields. It is only used for projection
211 // queries. The field list should be a subset of the projected field list.
212 // DistinctOn cannot be used with Distinct.
213 func (q *Query) DistinctOn(fieldNames ...string) *Query {
214 q = q.clone()
215 q.distinctOn = fieldNames
216 return q
217 }
218
219 // KeysOnly returns a derivative query that yields only keys, not keys and
220 // entities. It cannot be used with projection queries.
221 func (q *Query) KeysOnly() *Query {
222 q = q.clone()
223 q.keysOnly = true
224 return q
225 }
226
227 // Limit returns a derivative query that has a limit on the number of results
228 // returned. A negative value means unlimited.
229 func (q *Query) Limit(limit int) *Query {
230 q = q.clone()
231 if limit < math.MinInt32 || limit > math.MaxInt32 {
232 q.err = errors.New("datastore: query limit overflow")
233 return q
234 }
235 q.limit = int32(limit)
236 return q
237 }
238
239 // Offset returns a derivative query that has an offset of how many keys to
240 // skip over before returning results. A negative value is invalid.
241 func (q *Query) Offset(offset int) *Query {
242 q = q.clone()
243 if offset < 0 {
244 q.err = errors.New("datastore: negative query offset")
245 return q
246 }
247 if offset > math.MaxInt32 {
248 q.err = errors.New("datastore: query offset overflow")
249 return q
250 }
251 q.offset = int32(offset)
252 return q
253 }
254
255 // BatchSize returns a derivative query to fetch the supplied number of results
256 // at once. This value should be greater than zero, and equal to or less than
257 // the Limit.
258 func (q *Query) BatchSize(size int) *Query {
259 q = q.clone()
260 if size <= 0 || size > math.MaxInt32 {
261 q.err = errors.New("datastore: query batch size overflow")
262 return q
263 }
264 q.count = int32(size)
265 return q
266 }
267
268 // Start returns a derivative query with the given start point.
269 func (q *Query) Start(c Cursor) *Query {
270 q = q.clone()
271 if c.cc == nil {
272 q.err = errors.New("datastore: invalid cursor")
273 return q
274 }
275 q.start = c.cc
276 return q
277 }
278
279 // End returns a derivative query with the given end point.
280 func (q *Query) End(c Cursor) *Query {
281 q = q.clone()
282 if c.cc == nil {
283 q.err = errors.New("datastore: invalid cursor")
284 return q
285 }
286 q.end = c.cc
287 return q
288 }
289
290 // toProto converts the query to a protocol buffer.
291 func (q *Query) toProto(dst *pb.Query, appID string) error {
292 if len(q.projection) != 0 && q.keysOnly {
293 return errors.New("datastore: query cannot both project and be keys-only")
294 }
295 if len(q.distinctOn) != 0 && q.distinct {
296 return errors.New("datastore: query cannot be both distinct and distinct-on")
297 }
298 dst.Reset()
299 dst.App = proto.String(appID)
300 if q.kind != "" {
301 dst.Kind = proto.String(q.kind)
302 }
303 if q.ancestor != nil {
304 dst.Ancestor = keyToProto(appID, q.ancestor)
305 if q.eventual {
306 dst.Strong = proto.Bool(false)
307 }
308 }
309 if q.projection != nil {
310 dst.PropertyName = q.projection
311 if len(q.distinctOn) != 0 {
312 dst.GroupByPropertyName = q.distinctOn
313 }
314 if q.distinct {
315 dst.GroupByPropertyName = q.projection
316 }
317 }
318 if q.keysOnly {
319 dst.KeysOnly = proto.Bool(true)
320 dst.RequirePerfectPlan = proto.Bool(true)
321 }
322 for _, qf := range q.filter {
323 if qf.FieldName == "" {
324 return errors.New("datastore: empty query filter field name")
325 }
326 p, errStr := valueToProto(appID, qf.FieldName, reflect.ValueOf(qf.Value), false)
327 if errStr != "" {
328 return errors.New("datastore: bad query filter value type: " + errStr)
329 }
330 xf := &pb.Query_Filter{
331 Op: operatorToProto[qf.Op],
332 Property: []*pb.Property{p},
333 }
334 if xf.Op == nil {
335 return errors.New("datastore: unknown query filter operator")
336 }
337 dst.Filter = append(dst.Filter, xf)
338 }
339 for _, qo := range q.order {
340 if qo.FieldName == "" {
341 return errors.New("datastore: empty query order field name")
342 }
343 xo := &pb.Query_Order{
344 Property: proto.String(qo.FieldName),
345 Direction: sortDirectionToProto[qo.Direction],
346 }
347 if xo.Direction == nil {
348 return errors.New("datastore: unknown query order direction")
349 }
350 dst.Order = append(dst.Order, xo)
351 }
352 if q.limit >= 0 {
353 dst.Limit = proto.Int32(q.limit)
354 }
355 if q.offset != 0 {
356 dst.Offset = proto.Int32(q.offset)
357 }
358 if q.count != 0 {
359 dst.Count = proto.Int32(q.count)
360 }
361 dst.CompiledCursor = q.start
362 dst.EndCompiledCursor = q.end
363 dst.Compile = proto.Bool(true)
364 return nil
365 }
366
367 // Count returns the number of results for the query.
368 //
369 // The running time and number of API calls made by Count scale linearly with
370 // the sum of the query's offset and limit. Unless the result count is
371 // expected to be small, it is best to specify a limit; otherwise Count will
372 // continue until it finishes counting or the provided context expires.
373 func (q *Query) Count(c context.Context) (int, error) {
374 // Check that the query is well-formed.
375 if q.err != nil {
376 return 0, q.err
377 }
378
379 // Run a copy of the query, with keysOnly true (if we're not a projection,
380 // since the two are incompatible), and an adjusted offset. We also set the
381 // limit to zero, as we don't want any actual entity data, just the number
382 // of skipped results.
383 newQ := q.clone()
384 newQ.keysOnly = len(newQ.projection) == 0
385 newQ.limit = 0
386 if q.limit < 0 {
387 // If the original query was unlimited, set the new query's offset to maximum.
388 newQ.offset = math.MaxInt32
389 } else {
390 newQ.offset = q.offset + q.limit
391 if newQ.offset < 0 {
392 // Do the best we can, in the presence of overflow.
393 newQ.offset = math.MaxInt32
394 }
395 }
396 req := &pb.Query{}
397 if err := newQ.toProto(req, internal.FullyQualifiedAppID(c)); err != nil {
398 return 0, err
399 }
400 res := &pb.QueryResult{}
401 if err := internal.Call(c, "datastore_v3", "RunQuery", req, res); err != nil {
402 return 0, err
403 }
404
405 // n is the count we will return. For example, suppose that our original
406 // query had an offset of 4 and a limit of 2008: the count will be 2008,
407 // provided that there are at least 2012 matching entities. However, the
408 // RPCs will only skip 1000 results at a time. The RPC sequence is:
409 // call RunQuery with (offset, limit) = (2012, 0) // 2012 == newQ.offset
410 // response has (skippedResults, moreResults) = (1000, true)
411 // n += 1000 // n == 1000
412 // call Next with (offset, limit) = (1012, 0) // 1012 == newQ.offset - n
413 // response has (skippedResults, moreResults) = (1000, true)
414 // n += 1000 // n == 2000
415 // call Next with (offset, limit) = (12, 0) // 12 == newQ.offset - n
416 // response has (skippedResults, moreResults) = (12, false)
417 // n += 12 // n == 2012
418 // // exit the loop
419 // n -= 4 // n == 2008
420 var n int32
421 for {
422 // The QueryResult should have no actual entity data, just skipped results.
423 if len(res.Result) != 0 {
424 return 0, errors.New("datastore: internal error: Count request returned too much data")
425 }
426 n += res.GetSkippedResults()
427 if !res.GetMoreResults() {
428 break
429 }
430 if err := callNext(c, res, newQ.offset-n, q.count); err != nil {
431 return 0, err
432 }
433 }
434 n -= q.offset
435 if n < 0 {
436 // If the offset was greater than the number of matching entities,
437 // return 0 instead of negative.
438 n = 0
439 }
440 return int(n), nil
441 }
442
443 // callNext issues a datastore_v3/Next RPC to advance a cursor, such as that
444 // returned by a query with more results.
445 func callNext(c context.Context, res *pb.QueryResult, offset, count int32) error {
446 if res.Cursor == nil {
447 return errors.New("datastore: internal error: server did not return a cursor")
448 }
449 req := &pb.NextRequest{
450 Cursor: res.Cursor,
451 }
452 if count >= 0 {
453 req.Count = proto.Int32(count)
454 }
455 if offset != 0 {
456 req.Offset = proto.Int32(offset)
457 }
458 if res.CompiledCursor != nil {
459 req.Compile = proto.Bool(true)
460 }
461 res.Reset()
462 return internal.Call(c, "datastore_v3", "Next", req, res)
463 }
464
465 // GetAll runs the query in the given context and returns all keys that match
466 // that query, as well as appending the values to dst.
467 //
468 // dst must have type *[]S or *[]*S or *[]P, for some struct type S or some non-
469 // interface, non-pointer type P such that P or *P implements PropertyLoadSaver.
470 //
471 // As a special case, *PropertyList is an invalid type for dst, even though a
472 // PropertyList is a slice of structs. It is treated as invalid to avoid being
473 // mistakenly passed when *[]PropertyList was intended.
474 //
475 // The keys returned by GetAll will be in a 1-1 correspondence with the entities
476 // added to dst.
477 //
478 // If q is a “keys-only” query, GetAll ignores dst and only returns the keys.
479 //
480 // The running time and number of API calls made by GetAll scale linearly with
481 // the sum of the query's offset and limit. Unless the result count is
482 // expected to be small, it is best to specify a limit; otherwise GetAll will
483 // continue until it finishes collecting results or the provided context
484 // expires.
485 func (q *Query) GetAll(c context.Context, dst interface{}) ([]*Key, error) {
486 var (
487 dv reflect.Value
488 mat multiArgType
489 elemType reflect.Type
490 errFieldMismatch error
491 )
492 if !q.keysOnly {
493 dv = reflect.ValueOf(dst)
494 if dv.Kind() != reflect.Ptr || dv.IsNil() {
495 return nil, ErrInvalidEntityType
496 }
497 dv = dv.Elem()
498 mat, elemType = checkMultiArg(dv)
499 if mat == multiArgTypeInvalid || mat == multiArgTypeInterface {
500 return nil, ErrInvalidEntityType
501 }
502 }
503
504 var keys []*Key
505 for t := q.Run(c); ; {
506 k, e, err := t.next()
507 if err == Done {
508 break
509 }
510 if err != nil {
511 return keys, err
512 }
513 if !q.keysOnly {
514 ev := reflect.New(elemType)
515 if elemType.Kind() == reflect.Map {
516 // This is a special case. The zero values of a map type are
517 // not immediately useful; they have to be make'd.
518 //
519 // Funcs and channels are similar, in that a zero value is not useful,
520 // but even a freshly make'd channel isn't useful: there's no fixed
521 // channel buffer size that is always going to be large enough, and
522 // there's no goroutine to drain the other end. Theoretically, these
523 // types could be supported, for example by sniffing for a constructor
524 // method or requiring prior registration, but for now it's not a
525 // frequent enough concern to be worth it. Programmers can work around
526 // it by explicitly using Iterator.Next instead of the Query.GetAll
527 // convenience method.
528 x := reflect.MakeMap(elemType)
529 ev.Elem().Set(x)
530 }
531 if err = loadEntity(ev.Interface(), e); err != nil {
532 if _, ok := err.(*ErrFieldMismatch); ok {
533 // We continue loading entities even in the face of field mismatch errors.
534 // If we encounter any other error, that other error is returned. Otherwise,
535 // an ErrFieldMismatch is returned.
536 errFieldMismatch = err
537 } else {
538 return keys, err
539 }
540 }
541 if mat != multiArgTypeStructPtr {
542 ev = ev.Elem()
543 }
544 dv.Set(reflect.Append(dv, ev))
545 }
546 keys = append(keys, k)
547 }
548 return keys, errFieldMismatch
549 }
550
551 // Run runs the query in the given context.
552 func (q *Query) Run(c context.Context) *Iterator {
553 if q.err != nil {
554 return &Iterator{err: q.err}
555 }
556 t := &Iterator{
557 c: c,
558 limit: q.limit,
559 count: q.count,
560 q: q,
561 prevCC: q.start,
562 }
563 var req pb.Query
564 if err := q.toProto(&req, internal.FullyQualifiedAppID(c)); err != nil {
565 t.err = err
566 return t
567 }
568 if err := internal.Call(c, "datastore_v3", "RunQuery", &req, &t.res); err != nil {
569 t.err = err
570 return t
571 }
572 offset := q.offset - t.res.GetSkippedResults()
573 var count int32
574 if t.count > 0 && (t.limit < 0 || t.count < t.limit) {
575 count = t.count
576 } else {
577 count = t.limit
578 }
579 for offset > 0 && t.res.GetMoreResults() {
580 t.prevCC = t.res.CompiledCursor
581 if err := callNext(t.c, &t.res, offset, count); err != nil {
582 t.err = err
583 break
584 }
585 skip := t.res.GetSkippedResults()
586 if skip < 0 {
587 t.err = errors.New("datastore: internal error: negative number of skipped_results")
588 break
589 }
590 offset -= skip
591 }
592 if offset < 0 {
593 t.err = errors.New("datastore: internal error: query offset was overshot")
594 }
595 return t
596 }
597
598 // Iterator is the result of running a query.
599 type Iterator struct {
600 c context.Context
601 err error
602 // res is the result of the most recent RunQuery or Next API call.
603 res pb.QueryResult
604 // i is how many elements of res.Result we have iterated over.
605 i int
606 // limit is the limit on the number of results this iterator should return.
607 // A negative value means unlimited.
608 limit int32
609 // count is the number of results this iterator should fetch at once. This
610 // should be equal to or greater than zero.
611 count int32
612 // q is the original query which yielded this iterator.
613 q *Query
614 // prevCC is the compiled cursor that marks the end of the previous batch
615 // of results.
616 prevCC *pb.CompiledCursor
617 }
618
619 // Done is returned when a query iteration has completed.
620 var Done = errors.New("datastore: query has no more results")
621
622 // Next returns the key of the next result. When there are no more results,
623 // Done is returned as the error.
624 //
625 // If the query is not keys only and dst is non-nil, it also loads the entity
626 // stored for that key into the struct pointer or PropertyLoadSaver dst, with
627 // the same semantics and possible errors as for the Get function.
628 func (t *Iterator) Next(dst interface{}) (*Key, error) {
629 k, e, err := t.next()
630 if err != nil {
631 return nil, err
632 }
633 if dst != nil && !t.q.keysOnly {
634 err = loadEntity(dst, e)
635 }
636 return k, err
637 }
638
639 func (t *Iterator) next() (*Key, *pb.EntityProto, error) {
640 if t.err != nil {
641 return nil, nil, t.err
642 }
643
644 // Issue datastore_v3/Next RPCs as necessary.
645 for t.i == len(t.res.Result) {
646 if !t.res.GetMoreResults() {
647 t.err = Done
648 return nil, nil, t.err
649 }
650 t.prevCC = t.res.CompiledCursor
651 var count int32
652 if t.count > 0 && (t.limit < 0 || t.count < t.limit) {
653 count = t.count
654 } else {
655 count = t.limit
656 }
657 if err := callNext(t.c, &t.res, 0, count); err != nil {
658 t.err = err
659 return nil, nil, t.err
660 }
661 if t.res.GetSkippedResults() != 0 {
662 t.err = errors.New("datastore: internal error: iterator has skipped results")
663 return nil, nil, t.err
664 }
665 t.i = 0
666 if t.limit >= 0 {
667 t.limit -= int32(len(t.res.Result))
668 if t.limit < 0 {
669 t.err = errors.New("datastore: internal error: query returned more results than the limit")
670 return nil, nil, t.err
671 }
672 }
673 }
674
675 // Extract the key from the t.i'th element of t.res.Result.
676 e := t.res.Result[t.i]
677 t.i++
678 if e.Key == nil {
679 return nil, nil, errors.New("datastore: internal error: server did not return a key")
680 }
681 k, err := protoToKey(e.Key)
682 if err != nil || k.Incomplete() {
683 return nil, nil, errors.New("datastore: internal error: server returned an invalid key")
684 }
685 return k, e, nil
686 }
687
688 // Cursor returns a cursor for the iterator's current location.
689 func (t *Iterator) Cursor() (Cursor, error) {
690 if t.err != nil && t.err != Done {
691 return Cursor{}, t.err
692 }
693 // If we are at either end of the current batch of results,
694 // return the compiled cursor at that end.
695 skipped := t.res.GetSkippedResults()
696 if t.i == 0 && skipped == 0 {
697 if t.prevCC == nil {
698 // A nil pointer (of type *pb.CompiledCursor) means no constraint:
699 // passing it as the end cursor of a new query means unlimited results
700 // (glossing over the integer limit parameter for now).
701 // A non-nil pointer to an empty pb.CompiledCursor means the start:
702 // passing it as the end cursor of a new query means 0 results.
703 // If prevCC was nil, then the original query had no start cursor, but
704 // Iterator.Cursor should return "the start" instead of unlimited.
705 return Cursor{&zeroCC}, nil
706 }
707 return Cursor{t.prevCC}, nil
708 }
709 if t.i == len(t.res.Result) {
710 return Cursor{t.res.CompiledCursor}, nil
711 }
712 // Otherwise, re-run the query offset to this iterator's position, starting from
713 // the most recent compiled cursor. This is done on a best-effort basis, as it
714 // is racy; if a concurrent process has added or removed entities, then the
715 // cursor returned may be inconsistent.
716 q := t.q.clone()
717 q.start = t.prevCC
718 q.offset = skipped + int32(t.i)
719 q.limit = 0
720 q.keysOnly = len(q.projection) == 0
721 t1 := q.Run(t.c)
722 _, _, err := t1.next()
723 if err != Done {
724 if err == nil {
725 err = fmt.Errorf("datastore: internal error: zero-limit query did not have zero results")
726 }
727 return Cursor{}, err
728 }
729 return Cursor{t1.res.CompiledCursor}, nil
730 }
731
732 var zeroCC pb.CompiledCursor
733
734 // Cursor is an iterator's position. It can be converted to and from an opaque
735 // string. A cursor can be used from different HTTP requests, but only with a
736 // query with the same kind, ancestor, filter and order constraints.
737 type Cursor struct {
738 cc *pb.CompiledCursor
739 }
740
741 // String returns a base-64 string representation of a cursor.
742 func (c Cursor) String() string {
743 if c.cc == nil {
744 return ""
745 }
746 b, err := proto.Marshal(c.cc)
747 if err != nil {
748 // The only way to construct a Cursor with a non-nil cc field is to
749 // unmarshal from the byte representation. We panic if the unmarshal
750 // succeeds but the marshaling of the unchanged protobuf value fails.
751 panic(fmt.Sprintf("datastore: internal error: malformed cursor: %v", err))
752 }
753 return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
754 }
755
756 // Decode decodes a cursor from its base-64 string representation.
757 func DecodeCursor(s string) (Cursor, error) {
758 if s == "" {
759 return Cursor{&zeroCC}, nil
760 }
761 if n := len(s) % 4; n != 0 {
762 s += strings.Repeat("=", 4-n)
763 }
764 b, err := base64.URLEncoding.DecodeString(s)
765 if err != nil {
766 return Cursor{}, err
767 }
768 cc := &pb.CompiledCursor{}
769 if err := proto.Unmarshal(b, cc); err != nil {
770 return Cursor{}, err
771 }
772 return Cursor{cc}, nil
773 }
0 // Copyright 2011 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "errors"
8 "fmt"
9 "reflect"
10 "strings"
11 "testing"
12
13 "github.com/golang/protobuf/proto"
14
15 "google.golang.org/appengine/v2/internal"
16 "google.golang.org/appengine/v2/internal/aetesting"
17 pb "google.golang.org/appengine/v2/internal/datastore"
18 )
19
20 var (
21 path1 = &pb.Path{
22 Element: []*pb.Path_Element{
23 {
24 Type: proto.String("Gopher"),
25 Id: proto.Int64(6),
26 },
27 },
28 }
29 path2 = &pb.Path{
30 Element: []*pb.Path_Element{
31 {
32 Type: proto.String("Gopher"),
33 Id: proto.Int64(6),
34 },
35 {
36 Type: proto.String("Gopher"),
37 Id: proto.Int64(8),
38 },
39 },
40 }
41 )
42
43 func fakeRunQuery(in *pb.Query, out *pb.QueryResult) error {
44 expectedIn := &pb.Query{
45 App: proto.String("dev~fake-app"),
46 Kind: proto.String("Gopher"),
47 Compile: proto.Bool(true),
48 }
49 if !proto.Equal(in, expectedIn) {
50 return fmt.Errorf("unsupported argument: got %v want %v", in, expectedIn)
51 }
52 *out = pb.QueryResult{
53 Result: []*pb.EntityProto{
54 {
55 Key: &pb.Reference{
56 App: proto.String("s~test-app"),
57 Path: path1,
58 },
59 EntityGroup: path1,
60 Property: []*pb.Property{
61 {
62 Meaning: pb.Property_TEXT.Enum(),
63 Name: proto.String("Name"),
64 Value: &pb.PropertyValue{
65 StringValue: proto.String("George"),
66 },
67 },
68 {
69 Name: proto.String("Height"),
70 Value: &pb.PropertyValue{
71 Int64Value: proto.Int64(32),
72 },
73 },
74 },
75 },
76 {
77 Key: &pb.Reference{
78 App: proto.String("s~test-app"),
79 Path: path2,
80 },
81 EntityGroup: path1, // ancestor is George
82 Property: []*pb.Property{
83 {
84 Meaning: pb.Property_TEXT.Enum(),
85 Name: proto.String("Name"),
86 Value: &pb.PropertyValue{
87 StringValue: proto.String("Rufus"),
88 },
89 },
90 // No height for Rufus.
91 },
92 },
93 },
94 MoreResults: proto.Bool(false),
95 }
96 return nil
97 }
98
99 type StructThatImplementsPLS struct{}
100
101 func (StructThatImplementsPLS) Load(p []Property) error { return nil }
102 func (StructThatImplementsPLS) Save() ([]Property, error) { return nil, nil }
103
104 var _ PropertyLoadSaver = StructThatImplementsPLS{}
105
106 type StructPtrThatImplementsPLS struct{}
107
108 func (*StructPtrThatImplementsPLS) Load(p []Property) error { return nil }
109 func (*StructPtrThatImplementsPLS) Save() ([]Property, error) { return nil, nil }
110
111 var _ PropertyLoadSaver = &StructPtrThatImplementsPLS{}
112
113 type PropertyMap map[string]Property
114
115 func (m PropertyMap) Load(props []Property) error {
116 for _, p := range props {
117 if p.Multiple {
118 return errors.New("PropertyMap does not support multiple properties")
119 }
120 m[p.Name] = p
121 }
122 return nil
123 }
124
125 func (m PropertyMap) Save() ([]Property, error) {
126 props := make([]Property, 0, len(m))
127 for _, p := range m {
128 if p.Multiple {
129 return nil, errors.New("PropertyMap does not support multiple properties")
130 }
131 props = append(props, p)
132 }
133 return props, nil
134 }
135
136 var _ PropertyLoadSaver = PropertyMap{}
137
138 type Gopher struct {
139 Name string
140 Height int
141 }
142
143 // typeOfEmptyInterface is the type of interface{}, but we can't use
144 // reflect.TypeOf((interface{})(nil)) directly because TypeOf takes an
145 // interface{}.
146 var typeOfEmptyInterface = reflect.TypeOf((*interface{})(nil)).Elem()
147
148 func TestCheckMultiArg(t *testing.T) {
149 testCases := []struct {
150 v interface{}
151 mat multiArgType
152 elemType reflect.Type
153 }{
154 // Invalid cases.
155 {nil, multiArgTypeInvalid, nil},
156 {Gopher{}, multiArgTypeInvalid, nil},
157 {&Gopher{}, multiArgTypeInvalid, nil},
158 {PropertyList{}, multiArgTypeInvalid, nil}, // This is a special case.
159 {PropertyMap{}, multiArgTypeInvalid, nil},
160 {[]*PropertyList(nil), multiArgTypeInvalid, nil},
161 {[]*PropertyMap(nil), multiArgTypeInvalid, nil},
162 {[]**Gopher(nil), multiArgTypeInvalid, nil},
163 {[]*interface{}(nil), multiArgTypeInvalid, nil},
164 // Valid cases.
165 {
166 []PropertyList(nil),
167 multiArgTypePropertyLoadSaver,
168 reflect.TypeOf(PropertyList{}),
169 },
170 {
171 []PropertyMap(nil),
172 multiArgTypePropertyLoadSaver,
173 reflect.TypeOf(PropertyMap{}),
174 },
175 {
176 []StructThatImplementsPLS(nil),
177 multiArgTypePropertyLoadSaver,
178 reflect.TypeOf(StructThatImplementsPLS{}),
179 },
180 {
181 []StructPtrThatImplementsPLS(nil),
182 multiArgTypePropertyLoadSaver,
183 reflect.TypeOf(StructPtrThatImplementsPLS{}),
184 },
185 {
186 []Gopher(nil),
187 multiArgTypeStruct,
188 reflect.TypeOf(Gopher{}),
189 },
190 {
191 []*Gopher(nil),
192 multiArgTypeStructPtr,
193 reflect.TypeOf(Gopher{}),
194 },
195 {
196 []interface{}(nil),
197 multiArgTypeInterface,
198 typeOfEmptyInterface,
199 },
200 }
201 for _, tc := range testCases {
202 mat, elemType := checkMultiArg(reflect.ValueOf(tc.v))
203 if mat != tc.mat || elemType != tc.elemType {
204 t.Errorf("checkMultiArg(%T): got %v, %v want %v, %v",
205 tc.v, mat, elemType, tc.mat, tc.elemType)
206 }
207 }
208 }
209
210 func TestSimpleQuery(t *testing.T) {
211 struct1 := Gopher{Name: "George", Height: 32}
212 struct2 := Gopher{Name: "Rufus"}
213 pList1 := PropertyList{
214 {
215 Name: "Name",
216 Value: "George",
217 },
218 {
219 Name: "Height",
220 Value: int64(32),
221 },
222 }
223 pList2 := PropertyList{
224 {
225 Name: "Name",
226 Value: "Rufus",
227 },
228 }
229 pMap1 := PropertyMap{
230 "Name": Property{
231 Name: "Name",
232 Value: "George",
233 },
234 "Height": Property{
235 Name: "Height",
236 Value: int64(32),
237 },
238 }
239 pMap2 := PropertyMap{
240 "Name": Property{
241 Name: "Name",
242 Value: "Rufus",
243 },
244 }
245
246 testCases := []struct {
247 dst interface{}
248 want interface{}
249 }{
250 // The destination must have type *[]P, *[]S or *[]*S, for some non-interface
251 // type P such that *P implements PropertyLoadSaver, or for some struct type S.
252 {new([]Gopher), &[]Gopher{struct1, struct2}},
253 {new([]*Gopher), &[]*Gopher{&struct1, &struct2}},
254 {new([]PropertyList), &[]PropertyList{pList1, pList2}},
255 {new([]PropertyMap), &[]PropertyMap{pMap1, pMap2}},
256
257 // Any other destination type is invalid.
258 {0, nil},
259 {Gopher{}, nil},
260 {PropertyList{}, nil},
261 {PropertyMap{}, nil},
262 {[]int{}, nil},
263 {[]Gopher{}, nil},
264 {[]PropertyList{}, nil},
265 {new(int), nil},
266 {new(Gopher), nil},
267 {new(PropertyList), nil}, // This is a special case.
268 {new(PropertyMap), nil},
269 {new([]int), nil},
270 {new([]map[int]int), nil},
271 {new([]map[string]Property), nil},
272 {new([]map[string]interface{}), nil},
273 {new([]*int), nil},
274 {new([]*map[int]int), nil},
275 {new([]*map[string]Property), nil},
276 {new([]*map[string]interface{}), nil},
277 {new([]**Gopher), nil},
278 {new([]*PropertyList), nil},
279 {new([]*PropertyMap), nil},
280 }
281 for _, tc := range testCases {
282 nCall := 0
283 c := aetesting.FakeSingleContext(t, "datastore_v3", "RunQuery", func(in *pb.Query, out *pb.QueryResult) error {
284 nCall++
285 return fakeRunQuery(in, out)
286 })
287 c = internal.WithAppIDOverride(c, "dev~fake-app")
288
289 var (
290 expectedErr error
291 expectedNCall int
292 )
293 if tc.want == nil {
294 expectedErr = ErrInvalidEntityType
295 } else {
296 expectedNCall = 1
297 }
298 keys, err := NewQuery("Gopher").GetAll(c, tc.dst)
299 if err != expectedErr {
300 t.Errorf("dst type %T: got error [%v], want [%v]", tc.dst, err, expectedErr)
301 continue
302 }
303 if nCall != expectedNCall {
304 t.Errorf("dst type %T: Context.Call was called an incorrect number of times: got %d want %d", tc.dst, nCall, expectedNCall)
305 continue
306 }
307 if err != nil {
308 continue
309 }
310
311 key1 := NewKey(c, "Gopher", "", 6, nil)
312 expectedKeys := []*Key{
313 key1,
314 NewKey(c, "Gopher", "", 8, key1),
315 }
316 if l1, l2 := len(keys), len(expectedKeys); l1 != l2 {
317 t.Errorf("dst type %T: got %d keys, want %d keys", tc.dst, l1, l2)
318 continue
319 }
320 for i, key := range keys {
321 if key.AppID() != "s~test-app" {
322 t.Errorf(`dst type %T: Key #%d's AppID = %q, want "s~test-app"`, tc.dst, i, key.AppID())
323 continue
324 }
325 if !keysEqual(key, expectedKeys[i]) {
326 t.Errorf("dst type %T: got key #%d %v, want %v", tc.dst, i, key, expectedKeys[i])
327 continue
328 }
329 }
330
331 if !reflect.DeepEqual(tc.dst, tc.want) {
332 t.Errorf("dst type %T: Entities got %+v, want %+v", tc.dst, tc.dst, tc.want)
333 continue
334 }
335 }
336 }
337
338 // keysEqual is like (*Key).Equal, but ignores the App ID.
339 func keysEqual(a, b *Key) bool {
340 for a != nil && b != nil {
341 if a.Kind() != b.Kind() || a.StringID() != b.StringID() || a.IntID() != b.IntID() {
342 return false
343 }
344 a, b = a.Parent(), b.Parent()
345 }
346 return a == b
347 }
348
349 func TestQueriesAreImmutable(t *testing.T) {
350 // Test that deriving q2 from q1 does not modify q1.
351 q0 := NewQuery("foo")
352 q1 := NewQuery("foo")
353 q2 := q1.Offset(2)
354 if !reflect.DeepEqual(q0, q1) {
355 t.Errorf("q0 and q1 were not equal")
356 }
357 if reflect.DeepEqual(q1, q2) {
358 t.Errorf("q1 and q2 were equal")
359 }
360
361 // Test that deriving from q4 twice does not conflict, even though
362 // q4 has a long list of order clauses. This tests that the arrays
363 // backed by a query's slice of orders are not shared.
364 f := func() *Query {
365 q := NewQuery("bar")
366 // 47 is an ugly number that is unlikely to be near a re-allocation
367 // point in repeated append calls. For example, it's not near a power
368 // of 2 or a multiple of 10.
369 for i := 0; i < 47; i++ {
370 q = q.Order(fmt.Sprintf("x%d", i))
371 }
372 return q
373 }
374 q3 := f().Order("y")
375 q4 := f()
376 q5 := q4.Order("y")
377 q6 := q4.Order("z")
378 if !reflect.DeepEqual(q3, q5) {
379 t.Errorf("q3 and q5 were not equal")
380 }
381 if reflect.DeepEqual(q5, q6) {
382 t.Errorf("q5 and q6 were equal")
383 }
384 }
385
386 func TestFilterParser(t *testing.T) {
387 testCases := []struct {
388 filterStr string
389 wantOK bool
390 wantFieldName string
391 wantOp operator
392 }{
393 // Supported ops.
394 {"x<", true, "x", lessThan},
395 {"x <", true, "x", lessThan},
396 {"x <", true, "x", lessThan},
397 {" x < ", true, "x", lessThan},
398 {"x <=", true, "x", lessEq},
399 {"x =", true, "x", equal},
400 {"x >=", true, "x", greaterEq},
401 {"x >", true, "x", greaterThan},
402 {"in >", true, "in", greaterThan},
403 {"in>", true, "in", greaterThan},
404 // Valid but (currently) unsupported ops.
405 {"x!=", false, "", 0},
406 {"x !=", false, "", 0},
407 {" x != ", false, "", 0},
408 {"x IN", false, "", 0},
409 {"x in", false, "", 0},
410 // Invalid ops.
411 {"x EQ", false, "", 0},
412 {"x lt", false, "", 0},
413 {"x <>", false, "", 0},
414 {"x >>", false, "", 0},
415 {"x ==", false, "", 0},
416 {"x =<", false, "", 0},
417 {"x =>", false, "", 0},
418 {"x !", false, "", 0},
419 {"x ", false, "", 0},
420 {"x", false, "", 0},
421 }
422 for _, tc := range testCases {
423 q := NewQuery("foo").Filter(tc.filterStr, 42)
424 if ok := q.err == nil; ok != tc.wantOK {
425 t.Errorf("%q: ok=%t, want %t", tc.filterStr, ok, tc.wantOK)
426 continue
427 }
428 if !tc.wantOK {
429 continue
430 }
431 if len(q.filter) != 1 {
432 t.Errorf("%q: len=%d, want %d", tc.filterStr, len(q.filter), 1)
433 continue
434 }
435 got, want := q.filter[0], filter{tc.wantFieldName, tc.wantOp, 42}
436 if got != want {
437 t.Errorf("%q: got %v, want %v", tc.filterStr, got, want)
438 continue
439 }
440 }
441 }
442
443 func TestQueryToProto(t *testing.T) {
444 // The context is required to make Keys for the test cases.
445 var got *pb.Query
446 NoErr := errors.New("No error")
447 c := aetesting.FakeSingleContext(t, "datastore_v3", "RunQuery", func(in *pb.Query, out *pb.QueryResult) error {
448 got = in
449 return NoErr // return a non-nil error so Run doesn't keep going.
450 })
451 c = internal.WithAppIDOverride(c, "dev~fake-app")
452
453 testCases := []struct {
454 desc string
455 query *Query
456 want *pb.Query
457 err string
458 }{
459 {
460 desc: "empty",
461 query: NewQuery(""),
462 want: &pb.Query{},
463 },
464 {
465 desc: "standard query",
466 query: NewQuery("kind").Order("-I").Filter("I >", 17).Filter("U =", "Dave").Limit(7).Offset(42).BatchSize(5),
467 want: &pb.Query{
468 Kind: proto.String("kind"),
469 Filter: []*pb.Query_Filter{
470 {
471 Op: pb.Query_Filter_GREATER_THAN.Enum(),
472 Property: []*pb.Property{
473 {
474 Name: proto.String("I"),
475 Value: &pb.PropertyValue{Int64Value: proto.Int64(17)},
476 Multiple: proto.Bool(false),
477 },
478 },
479 },
480 {
481 Op: pb.Query_Filter_EQUAL.Enum(),
482 Property: []*pb.Property{
483 {
484 Name: proto.String("U"),
485 Value: &pb.PropertyValue{StringValue: proto.String("Dave")},
486 Multiple: proto.Bool(false),
487 },
488 },
489 },
490 },
491 Order: []*pb.Query_Order{
492 {
493 Property: proto.String("I"),
494 Direction: pb.Query_Order_DESCENDING.Enum(),
495 },
496 },
497 Limit: proto.Int32(7),
498 Offset: proto.Int32(42),
499 Count: proto.Int32(5),
500 },
501 },
502 {
503 desc: "ancestor",
504 query: NewQuery("").Ancestor(NewKey(c, "kind", "Mummy", 0, nil)),
505 want: &pb.Query{
506 Ancestor: &pb.Reference{
507 App: proto.String("dev~fake-app"),
508 Path: &pb.Path{
509 Element: []*pb.Path_Element{{Type: proto.String("kind"), Name: proto.String("Mummy")}},
510 },
511 },
512 },
513 },
514 {
515 desc: "projection",
516 query: NewQuery("").Project("A", "B"),
517 want: &pb.Query{
518 PropertyName: []string{"A", "B"},
519 },
520 },
521 {
522 desc: "projection with distinct",
523 query: NewQuery("").Project("A", "B").Distinct(),
524 want: &pb.Query{
525 PropertyName: []string{"A", "B"},
526 GroupByPropertyName: []string{"A", "B"},
527 },
528 },
529 {
530 desc: "distinct on",
531 query: NewQuery("").Project("A", "B").DistinctOn("A"),
532 want: &pb.Query{
533 PropertyName: []string{"A", "B"},
534 GroupByPropertyName: []string{"A"},
535 },
536 },
537 {
538 desc: "keys only",
539 query: NewQuery("").KeysOnly(),
540 want: &pb.Query{
541 KeysOnly: proto.Bool(true),
542 RequirePerfectPlan: proto.Bool(true),
543 },
544 },
545 {
546 desc: "empty filter",
547 query: NewQuery("kind").Filter("=", 17),
548 err: "empty query filter field nam",
549 },
550 {
551 desc: "bad filter type",
552 query: NewQuery("kind").Filter("M =", map[string]bool{}),
553 err: "bad query filter value type",
554 },
555 {
556 desc: "bad filter operator",
557 query: NewQuery("kind").Filter("I <<=", 17),
558 err: `invalid operator "<<=" in filter "I <<="`,
559 },
560 {
561 desc: "empty order",
562 query: NewQuery("kind").Order(""),
563 err: "empty order",
564 },
565 {
566 desc: "bad order direction",
567 query: NewQuery("kind").Order("+I"),
568 err: `invalid order: "+I`,
569 },
570 }
571
572 for _, tt := range testCases {
573 got = nil
574 if _, err := tt.query.Run(c).Next(nil); err != NoErr {
575 if tt.err == "" || !strings.Contains(err.Error(), tt.err) {
576 t.Errorf("%s: error %v, want %q", tt.desc, err, tt.err)
577 }
578 continue
579 }
580 if tt.err != "" {
581 t.Errorf("%s: no error, want %q", tt.desc, tt.err)
582 continue
583 }
584 // Fields that are common to all protos.
585 tt.want.App = proto.String("dev~fake-app")
586 tt.want.Compile = proto.Bool(true)
587 if !proto.Equal(got, tt.want) {
588 t.Errorf("%s:\ngot %v\nwant %v", tt.desc, got, tt.want)
589 }
590 }
591 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "errors"
8 "fmt"
9 "math"
10 "reflect"
11 "time"
12
13 "github.com/golang/protobuf/proto"
14
15 "google.golang.org/appengine/v2"
16 pb "google.golang.org/appengine/v2/internal/datastore"
17 )
18
19 func toUnixMicro(t time.Time) int64 {
20 // We cannot use t.UnixNano() / 1e3 because we want to handle times more than
21 // 2^63 nanoseconds (which is about 292 years) away from 1970, and those cannot
22 // be represented in the numerator of a single int64 divide.
23 return t.Unix()*1e6 + int64(t.Nanosecond()/1e3)
24 }
25
26 func fromUnixMicro(t int64) time.Time {
27 return time.Unix(t/1e6, (t%1e6)*1e3).UTC()
28 }
29
30 var (
31 minTime = time.Unix(int64(math.MinInt64)/1e6, (int64(math.MinInt64)%1e6)*1e3)
32 maxTime = time.Unix(int64(math.MaxInt64)/1e6, (int64(math.MaxInt64)%1e6)*1e3)
33 )
34
35 // valueToProto converts a named value to a newly allocated Property.
36 // The returned error string is empty on success.
37 func valueToProto(defaultAppID, name string, v reflect.Value, multiple bool) (p *pb.Property, errStr string) {
38 var (
39 pv pb.PropertyValue
40 unsupported bool
41 )
42 switch v.Kind() {
43 case reflect.Invalid:
44 // No-op.
45 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
46 pv.Int64Value = proto.Int64(v.Int())
47 case reflect.Bool:
48 pv.BooleanValue = proto.Bool(v.Bool())
49 case reflect.String:
50 pv.StringValue = proto.String(v.String())
51 case reflect.Float32, reflect.Float64:
52 pv.DoubleValue = proto.Float64(v.Float())
53 case reflect.Ptr:
54 if k, ok := v.Interface().(*Key); ok {
55 if k != nil {
56 pv.Referencevalue = keyToReferenceValue(defaultAppID, k)
57 }
58 } else {
59 unsupported = true
60 }
61 case reflect.Struct:
62 switch t := v.Interface().(type) {
63 case time.Time:
64 if t.Before(minTime) || t.After(maxTime) {
65 return nil, "time value out of range"
66 }
67 pv.Int64Value = proto.Int64(toUnixMicro(t))
68 case appengine.GeoPoint:
69 if !t.Valid() {
70 return nil, "invalid GeoPoint value"
71 }
72 // NOTE: Strangely, latitude maps to X, longitude to Y.
73 pv.Pointvalue = &pb.PropertyValue_PointValue{X: &t.Lat, Y: &t.Lng}
74 default:
75 unsupported = true
76 }
77 case reflect.Slice:
78 if b, ok := v.Interface().([]byte); ok {
79 pv.StringValue = proto.String(string(b))
80 } else {
81 // nvToProto should already catch slice values.
82 // If we get here, we have a slice of slice values.
83 unsupported = true
84 }
85 default:
86 unsupported = true
87 }
88 if unsupported {
89 return nil, "unsupported datastore value type: " + v.Type().String()
90 }
91 p = &pb.Property{
92 Name: proto.String(name),
93 Value: &pv,
94 Multiple: proto.Bool(multiple),
95 }
96 if v.IsValid() {
97 switch v.Interface().(type) {
98 case []byte:
99 p.Meaning = pb.Property_BLOB.Enum()
100 case ByteString:
101 p.Meaning = pb.Property_BYTESTRING.Enum()
102 case appengine.BlobKey:
103 p.Meaning = pb.Property_BLOBKEY.Enum()
104 case time.Time:
105 p.Meaning = pb.Property_GD_WHEN.Enum()
106 case appengine.GeoPoint:
107 p.Meaning = pb.Property_GEORSS_POINT.Enum()
108 }
109 }
110 return p, ""
111 }
112
113 type saveOpts struct {
114 noIndex bool
115 multiple bool
116 omitEmpty bool
117 }
118
119 // saveEntity saves an EntityProto into a PropertyLoadSaver or struct pointer.
120 func saveEntity(defaultAppID string, key *Key, src interface{}) (*pb.EntityProto, error) {
121 var err error
122 var props []Property
123 if e, ok := src.(PropertyLoadSaver); ok {
124 props, err = e.Save()
125 } else {
126 props, err = SaveStruct(src)
127 }
128 if err != nil {
129 return nil, err
130 }
131 return propertiesToProto(defaultAppID, key, props)
132 }
133
134 func saveStructProperty(props *[]Property, name string, opts saveOpts, v reflect.Value) error {
135 if opts.omitEmpty && isEmptyValue(v) {
136 return nil
137 }
138 p := Property{
139 Name: name,
140 NoIndex: opts.noIndex,
141 Multiple: opts.multiple,
142 }
143 switch x := v.Interface().(type) {
144 case *Key:
145 p.Value = x
146 case time.Time:
147 p.Value = x
148 case appengine.BlobKey:
149 p.Value = x
150 case appengine.GeoPoint:
151 p.Value = x
152 case ByteString:
153 p.Value = x
154 default:
155 switch v.Kind() {
156 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
157 p.Value = v.Int()
158 case reflect.Bool:
159 p.Value = v.Bool()
160 case reflect.String:
161 p.Value = v.String()
162 case reflect.Float32, reflect.Float64:
163 p.Value = v.Float()
164 case reflect.Slice:
165 if v.Type().Elem().Kind() == reflect.Uint8 {
166 p.NoIndex = true
167 p.Value = v.Bytes()
168 }
169 case reflect.Struct:
170 if !v.CanAddr() {
171 return fmt.Errorf("datastore: unsupported struct field: value is unaddressable")
172 }
173 sub, err := newStructPLS(v.Addr().Interface())
174 if err != nil {
175 return fmt.Errorf("datastore: unsupported struct field: %v", err)
176 }
177 return sub.save(props, name+".", opts)
178 }
179 }
180 if p.Value == nil {
181 return fmt.Errorf("datastore: unsupported struct field type: %v", v.Type())
182 }
183 *props = append(*props, p)
184 return nil
185 }
186
187 func (s structPLS) Save() ([]Property, error) {
188 var props []Property
189 if err := s.save(&props, "", saveOpts{}); err != nil {
190 return nil, err
191 }
192 return props, nil
193 }
194
195 func (s structPLS) save(props *[]Property, prefix string, opts saveOpts) error {
196 for name, f := range s.codec.fields {
197 name = prefix + name
198 v := s.v.FieldByIndex(f.path)
199 if !v.IsValid() || !v.CanSet() {
200 continue
201 }
202 var opts1 saveOpts
203 opts1.noIndex = opts.noIndex || f.noIndex
204 opts1.multiple = opts.multiple
205 opts1.omitEmpty = f.omitEmpty // don't propagate
206 // For slice fields that aren't []byte, save each element.
207 if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
208 opts1.multiple = true
209 for j := 0; j < v.Len(); j++ {
210 if err := saveStructProperty(props, name, opts1, v.Index(j)); err != nil {
211 return err
212 }
213 }
214 continue
215 }
216 // Otherwise, save the field itself.
217 if err := saveStructProperty(props, name, opts1, v); err != nil {
218 return err
219 }
220 }
221 return nil
222 }
223
224 func propertiesToProto(defaultAppID string, key *Key, props []Property) (*pb.EntityProto, error) {
225 e := &pb.EntityProto{
226 Key: keyToProto(defaultAppID, key),
227 }
228 if key.parent == nil {
229 e.EntityGroup = &pb.Path{}
230 } else {
231 e.EntityGroup = keyToProto(defaultAppID, key.root()).Path
232 }
233 prevMultiple := make(map[string]bool)
234
235 for _, p := range props {
236 if pm, ok := prevMultiple[p.Name]; ok {
237 if !pm || !p.Multiple {
238 return nil, fmt.Errorf("datastore: multiple Properties with Name %q, but Multiple is false", p.Name)
239 }
240 } else {
241 prevMultiple[p.Name] = p.Multiple
242 }
243
244 x := &pb.Property{
245 Name: proto.String(p.Name),
246 Value: new(pb.PropertyValue),
247 Multiple: proto.Bool(p.Multiple),
248 }
249 switch v := p.Value.(type) {
250 case int64:
251 x.Value.Int64Value = proto.Int64(v)
252 case bool:
253 x.Value.BooleanValue = proto.Bool(v)
254 case string:
255 x.Value.StringValue = proto.String(v)
256 if p.NoIndex {
257 x.Meaning = pb.Property_TEXT.Enum()
258 }
259 case float64:
260 x.Value.DoubleValue = proto.Float64(v)
261 case *Key:
262 if v != nil {
263 x.Value.Referencevalue = keyToReferenceValue(defaultAppID, v)
264 }
265 case time.Time:
266 if v.Before(minTime) || v.After(maxTime) {
267 return nil, fmt.Errorf("datastore: time value out of range")
268 }
269 x.Value.Int64Value = proto.Int64(toUnixMicro(v))
270 x.Meaning = pb.Property_GD_WHEN.Enum()
271 case appengine.BlobKey:
272 x.Value.StringValue = proto.String(string(v))
273 x.Meaning = pb.Property_BLOBKEY.Enum()
274 case appengine.GeoPoint:
275 if !v.Valid() {
276 return nil, fmt.Errorf("datastore: invalid GeoPoint value")
277 }
278 // NOTE: Strangely, latitude maps to X, longitude to Y.
279 x.Value.Pointvalue = &pb.PropertyValue_PointValue{X: &v.Lat, Y: &v.Lng}
280 x.Meaning = pb.Property_GEORSS_POINT.Enum()
281 case []byte:
282 x.Value.StringValue = proto.String(string(v))
283 x.Meaning = pb.Property_BLOB.Enum()
284 if !p.NoIndex {
285 return nil, fmt.Errorf("datastore: cannot index a []byte valued Property with Name %q", p.Name)
286 }
287 case ByteString:
288 x.Value.StringValue = proto.String(string(v))
289 x.Meaning = pb.Property_BYTESTRING.Enum()
290 default:
291 if p.Value != nil {
292 return nil, fmt.Errorf("datastore: invalid Value type for a Property with Name %q", p.Name)
293 }
294 }
295
296 if p.NoIndex {
297 e.RawProperty = append(e.RawProperty, x)
298 } else {
299 e.Property = append(e.Property, x)
300 if len(e.Property) > maxIndexedProperties {
301 return nil, errors.New("datastore: too many indexed properties")
302 }
303 }
304 }
305 return e, nil
306 }
307
308 // isEmptyValue is taken from the encoding/json package in the standard library.
309 func isEmptyValue(v reflect.Value) bool {
310 switch v.Kind() {
311 case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
312 // TODO(performance): Only reflect.String needed, other property types are not supported (copy/paste from json package)
313 return v.Len() == 0
314 case reflect.Bool:
315 return !v.Bool()
316 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
317 return v.Int() == 0
318 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
319 // TODO(performance): Uint* are unsupported property types - should be removed (copy/paste from json package)
320 return v.Uint() == 0
321 case reflect.Float32, reflect.Float64:
322 return v.Float() == 0
323 case reflect.Interface, reflect.Ptr:
324 return v.IsNil()
325 case reflect.Struct:
326 switch x := v.Interface().(type) {
327 case time.Time:
328 return x.IsZero()
329 }
330 }
331 return false
332 }
0 // Copyright 2012 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "testing"
8 "time"
9 )
10
11 func TestUnixMicro(t *testing.T) {
12 // Test that all these time.Time values survive a round trip to unix micros.
13 testCases := []time.Time{
14 {},
15 time.Date(2, 1, 1, 0, 0, 0, 0, time.UTC),
16 time.Date(23, 1, 1, 0, 0, 0, 0, time.UTC),
17 time.Date(234, 1, 1, 0, 0, 0, 0, time.UTC),
18 time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC),
19 time.Date(1600, 1, 1, 0, 0, 0, 0, time.UTC),
20 time.Date(1700, 1, 1, 0, 0, 0, 0, time.UTC),
21 time.Date(1800, 1, 1, 0, 0, 0, 0, time.UTC),
22 time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC),
23 time.Unix(-1e6, -1000),
24 time.Unix(-1e6, 0),
25 time.Unix(-1e6, +1000),
26 time.Unix(-60, -1000),
27 time.Unix(-60, 0),
28 time.Unix(-60, +1000),
29 time.Unix(-1, -1000),
30 time.Unix(-1, 0),
31 time.Unix(-1, +1000),
32 time.Unix(0, -3000),
33 time.Unix(0, -2000),
34 time.Unix(0, -1000),
35 time.Unix(0, 0),
36 time.Unix(0, +1000),
37 time.Unix(0, +2000),
38 time.Unix(+60, -1000),
39 time.Unix(+60, 0),
40 time.Unix(+60, +1000),
41 time.Unix(+1e6, -1000),
42 time.Unix(+1e6, 0),
43 time.Unix(+1e6, +1000),
44 time.Date(1999, 12, 31, 23, 59, 59, 999000, time.UTC),
45 time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
46 time.Date(2006, 1, 2, 15, 4, 5, 678000, time.UTC),
47 time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC),
48 time.Date(3456, 1, 1, 0, 0, 0, 0, time.UTC),
49 }
50 for _, tc := range testCases {
51 got := fromUnixMicro(toUnixMicro(tc))
52 if !got.Equal(tc) {
53 t.Errorf("got %q, want %q", got, tc)
54 }
55 }
56
57 // Test that a time.Time that isn't an integral number of microseconds
58 // is not perfectly reconstructed after a round trip.
59 t0 := time.Unix(0, 123)
60 t1 := fromUnixMicro(toUnixMicro(t0))
61 if t1.Nanosecond()%1000 != 0 || t0.Nanosecond()%1000 == 0 {
62 t.Errorf("quantization to µs: got %q with %d ns, started with %d ns", t1, t1.Nanosecond(), t0.Nanosecond())
63 }
64 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package datastore
5
6 import (
7 "context"
8 "errors"
9
10 "google.golang.org/appengine/v2/internal"
11 pb "google.golang.org/appengine/v2/internal/datastore"
12 )
13
14 func init() {
15 internal.RegisterTransactionSetter(func(x *pb.Query, t *pb.Transaction) {
16 x.Transaction = t
17 })
18 internal.RegisterTransactionSetter(func(x *pb.GetRequest, t *pb.Transaction) {
19 x.Transaction = t
20 })
21 internal.RegisterTransactionSetter(func(x *pb.PutRequest, t *pb.Transaction) {
22 x.Transaction = t
23 })
24 internal.RegisterTransactionSetter(func(x *pb.DeleteRequest, t *pb.Transaction) {
25 x.Transaction = t
26 })
27 }
28
29 // ErrConcurrentTransaction is returned when a transaction is rolled back due
30 // to a conflict with a concurrent transaction.
31 var ErrConcurrentTransaction = errors.New("datastore: concurrent transaction")
32
33 // RunInTransaction runs f in a transaction. It calls f with a transaction
34 // context tc that f should use for all App Engine operations.
35 //
36 // If f returns nil, RunInTransaction attempts to commit the transaction,
37 // returning nil if it succeeds. If the commit fails due to a conflicting
38 // transaction, RunInTransaction retries f, each time with a new transaction
39 // context. It gives up and returns ErrConcurrentTransaction after three
40 // failed attempts. The number of attempts can be configured by specifying
41 // TransactionOptions.Attempts.
42 //
43 // If f returns non-nil, then any datastore changes will not be applied and
44 // RunInTransaction returns that same error. The function f is not retried.
45 //
46 // Note that when f returns, the transaction is not yet committed. Calling code
47 // must be careful not to assume that any of f's changes have been committed
48 // until RunInTransaction returns nil.
49 //
50 // Since f may be called multiple times, f should usually be idempotent.
51 // datastore.Get is not idempotent when unmarshaling slice fields.
52 //
53 // Nested transactions are not supported; c may not be a transaction context.
54 func RunInTransaction(c context.Context, f func(tc context.Context) error, opts *TransactionOptions) error {
55 xg := false
56 if opts != nil {
57 xg = opts.XG
58 }
59 readOnly := false
60 if opts != nil {
61 readOnly = opts.ReadOnly
62 }
63 attempts := 3
64 if opts != nil && opts.Attempts > 0 {
65 attempts = opts.Attempts
66 }
67 var t *pb.Transaction
68 var err error
69 for i := 0; i < attempts; i++ {
70 if t, err = internal.RunTransactionOnce(c, f, xg, readOnly, t); err != internal.ErrConcurrentTransaction {
71 return err
72 }
73 }
74 return ErrConcurrentTransaction
75 }
76
77 // TransactionOptions are the options for running a transaction.
78 type TransactionOptions struct {
79 // XG is whether the transaction can cross multiple entity groups. In
80 // comparison, a single group transaction is one where all datastore keys
81 // used have the same root key. Note that cross group transactions do not
82 // have the same behavior as single group transactions. In particular, it
83 // is much more likely to see partially applied transactions in different
84 // entity groups, in global queries.
85 // It is valid to set XG to true even if the transaction is within a
86 // single entity group.
87 XG bool
88 // Attempts controls the number of retries to perform when commits fail
89 // due to a conflicting transaction. If omitted, it defaults to 3.
90 Attempts int
91 // ReadOnly controls whether the transaction is a read only transaction.
92 // Read only transactions are potentially more efficient.
93 ReadOnly bool
94 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 /*
5 Package delay provides a way to execute code outside of the scope of
6 a user request by using the Task Queue API.
7 To use a deferred function, you must register the function to be
8 deferred as a top-level var. For example,
9 ```
10 var laterFunc = delay.MustRegister("key", myFunc)
11 func myFunc(ctx context.Context, a, b string) {...}
12 ```
13 You can also inline with a function literal:
14 ```
15 var laterFunc = delay.MustRegister("key", func(ctx context.Context, a, b string) {...})
16 ```
17 In the above example, "key" is a logical name for the function.
18 The key needs to be globally unique across your entire application.
19 To invoke the function in a deferred fashion, call the top-level item:
20 ```
21 laterFunc(ctx, "aaa", "bbb")
22 ```
23
24 This will queue a task and return quickly; the function will be actually
25 run in a new request. The delay package uses the Task Queue API to create
26 tasks that call the reserved application path "/_ah/queue/go/delay".
27 This path may only be marked as "login: admin" or have no access
28 restriction; it will fail if marked as "login: required".
29 */
30
31 package delay // import "google.golang.org/appengine/v2/delay"
32
33 import (
34 "bytes"
35 stdctx "context"
36 "encoding/gob"
37 "errors"
38 "fmt"
39 "go/build"
40 stdlog "log"
41 "net/http"
42 "path/filepath"
43 "reflect"
44 "regexp"
45 "runtime"
46 "strings"
47
48 "golang.org/x/net/context"
49
50 "google.golang.org/appengine/v2"
51 "google.golang.org/appengine/v2/internal"
52 "google.golang.org/appengine/v2/log"
53 "google.golang.org/appengine/v2/taskqueue"
54 )
55
56 // Function represents a function that may have a delayed invocation.
57 type Function struct {
58 fv reflect.Value // Kind() == reflect.Func
59 key string
60 err error // any error during initialization
61 }
62
63 const (
64 // The HTTP path for invocations.
65 path = "/_ah/queue/go/delay"
66 // Use the default queue.
67 queue = ""
68 )
69
70 type contextKey int
71
72 var (
73 // registry of all delayed functions
74 funcs = make(map[string]*Function)
75
76 // precomputed types
77 errorType = reflect.TypeOf((*error)(nil)).Elem()
78
79 // errors
80 errFirstArg = errors.New("first argument must be context.Context")
81 errOutsideDelayFunc = errors.New("request headers are only available inside a delay.Func")
82
83 // context keys
84 headersContextKey contextKey = 0
85 stdContextType = reflect.TypeOf((*stdctx.Context)(nil)).Elem()
86 netContextType = reflect.TypeOf((*context.Context)(nil)).Elem()
87 )
88
89 func isContext(t reflect.Type) bool {
90 return t == stdContextType || t == netContextType
91 }
92
93 var modVersionPat = regexp.MustCompile("@v[^/]+")
94
95 // fileKey finds a stable representation of the caller's file path.
96 // For calls from package main: strip all leading path entries, leaving just the filename.
97 // For calls from anywhere else, strip $GOPATH/src, leaving just the package path and file path.
98 func fileKey(file string) (string, error) {
99 if !internal.IsSecondGen() {
100 return file, nil
101 }
102 // If the caller is in the same Dir as mainPath, then strip everything but the file name.
103 if filepath.Dir(file) == internal.MainPath {
104 return filepath.Base(file), nil
105 }
106 // If the path contains "gopath/src/", which is what the builder uses for
107 // apps which don't use go modules, strip everything up to and including src.
108 // Or, if the path starts with /tmp/staging, then we're importing a package
109 // from the app's module (and we must be using go modules), and we have a
110 // path like /tmp/staging1234/srv/... so strip everything up to and
111 // including the first /srv/.
112 // And be sure to look at the GOPATH, for local development.
113 s := string(filepath.Separator)
114 for _, s := range []string{filepath.Join("gopath", "src") + s, s + "srv" + s, filepath.Join(build.Default.GOPATH, "src") + s} {
115 if idx := strings.Index(file, s); idx > 0 {
116 return file[idx+len(s):], nil
117 }
118 }
119
120 // Finally, if that all fails then we must be using go modules, and the file is a module,
121 // so the path looks like /go/pkg/mod/github.com/foo/bar@v0.0.0-20181026220418-f595d03440dc/baz.go
122 // So... remove everything up to and including mod, plus the @.... version string.
123 m := "/mod/"
124 if idx := strings.Index(file, m); idx > 0 {
125 file = file[idx+len(m):]
126 } else {
127 return file, fmt.Errorf("fileKey: unknown file path format for %q", file)
128 }
129 return modVersionPat.ReplaceAllString(file, ""), nil
130 }
131
132 // Func declares a new function that can be called in a deferred fashion.
133 // The second argument i must be a function with the first argument of
134 // type context.Context.
135 // To make the key globally unique, the SDK code will combine "key" with
136 // the filename of the file in which myFunc is defined
137 // (e.g., /some/path/myfile.go). This is convenient, but can lead to
138 // failed deferred tasks if you refactor your code, or change from
139 // GOPATH to go.mod, and then re-deploy with in-flight deferred tasks.
140 //
141 // This function Func must be called in a global scope to properly
142 // register the function with the framework.
143 //
144 // Deprecated: Use MustRegister instead.
145 func Func(key string, i interface{}) *Function {
146 // Derive unique, somewhat stable key for this func.
147 _, file, _, _ := runtime.Caller(1)
148 fk, err := fileKey(file)
149 if err != nil {
150 // Not fatal, but log the error
151 stdlog.Printf("delay: %v", err)
152 }
153 key = fk + ":" + key
154 f, err := registerFunction(key, i)
155 if err != nil {
156 return f
157 }
158 if old := funcs[f.key]; old != nil {
159 old.err = fmt.Errorf("multiple functions registered for %s", key)
160 }
161 funcs[f.key] = f
162 return f
163 }
164
165 // MustRegister declares a new function that can be called in a deferred fashion.
166 // The second argument i must be a function with the first argument of
167 // type context.Context.
168 // MustRegister requires the key to be globally unique.
169 //
170 // This function MustRegister must be called in a global scope to properly
171 // register the function with the framework.
172 // See the package notes above for more details.
173 func MustRegister(key string, i interface{}) *Function {
174 f, err := registerFunction(key, i)
175 if err != nil {
176 panic(err)
177 }
178
179 if old := funcs[f.key]; old != nil {
180 panic(fmt.Errorf("multiple functions registered for %q", key))
181 }
182 funcs[f.key] = f
183 return f
184 }
185
186 func registerFunction(key string, i interface{}) (*Function, error) {
187 f := &Function{fv: reflect.ValueOf(i)}
188 f.key = key
189
190 t := f.fv.Type()
191 if t.Kind() != reflect.Func {
192 f.err = errors.New("not a function")
193 return f, f.err
194 }
195 if t.NumIn() == 0 || !isContext(t.In(0)) {
196 f.err = errFirstArg
197 return f, errFirstArg
198 }
199
200 // Register the function's arguments with the gob package.
201 // This is required because they are marshaled inside a []interface{}.
202 // gob.Register only expects to be called during initialization;
203 // that's fine because this function expects the same.
204 for i := 0; i < t.NumIn(); i++ {
205 // Only concrete types may be registered. If the argument has
206 // interface type, the client is resposible for registering the
207 // concrete types it will hold.
208 if t.In(i).Kind() == reflect.Interface {
209 continue
210 }
211 gob.Register(reflect.Zero(t.In(i)).Interface())
212 }
213 return f, nil
214 }
215
216 type invocation struct {
217 Key string
218 Args []interface{}
219 }
220
221 // Call invokes a delayed function.
222 //
223 // err := f.Call(c, ...)
224 //
225 // is equivalent to
226 //
227 // t, _ := f.Task(...)
228 // _, err := taskqueue.Add(c, t, "")
229 func (f *Function) Call(c context.Context, args ...interface{}) error {
230 t, err := f.Task(args...)
231 if err != nil {
232 return err
233 }
234 _, err = taskqueueAdder(c, t, queue)
235 return err
236 }
237
238 // Task creates a Task that will invoke the function.
239 // Its parameters may be tweaked before adding it to a queue.
240 // Users should not modify the Path or Payload fields of the returned Task.
241 func (f *Function) Task(args ...interface{}) (*taskqueue.Task, error) {
242 if f.err != nil {
243 return nil, fmt.Errorf("delay: func is invalid: %v", f.err)
244 }
245
246 nArgs := len(args) + 1 // +1 for the context.Context
247 ft := f.fv.Type()
248 minArgs := ft.NumIn()
249 if ft.IsVariadic() {
250 minArgs--
251 }
252 if nArgs < minArgs {
253 return nil, fmt.Errorf("delay: too few arguments to func: %d < %d", nArgs, minArgs)
254 }
255 if !ft.IsVariadic() && nArgs > minArgs {
256 return nil, fmt.Errorf("delay: too many arguments to func: %d > %d", nArgs, minArgs)
257 }
258
259 // Check arg types.
260 for i := 1; i < nArgs; i++ {
261 at := reflect.TypeOf(args[i-1])
262 var dt reflect.Type
263 if i < minArgs {
264 // not a variadic arg
265 dt = ft.In(i)
266 } else {
267 // a variadic arg
268 dt = ft.In(minArgs).Elem()
269 }
270 // nil arguments won't have a type, so they need special handling.
271 if at == nil {
272 // nil interface
273 switch dt.Kind() {
274 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
275 continue // may be nil
276 }
277 return nil, fmt.Errorf("delay: argument %d has wrong type: %v is not nilable", i, dt)
278 }
279 switch at.Kind() {
280 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
281 av := reflect.ValueOf(args[i-1])
282 if av.IsNil() {
283 // nil value in interface; not supported by gob, so we replace it
284 // with a nil interface value
285 args[i-1] = nil
286 }
287 }
288 if !at.AssignableTo(dt) {
289 return nil, fmt.Errorf("delay: argument %d has wrong type: %v is not assignable to %v", i, at, dt)
290 }
291 }
292
293 inv := invocation{
294 Key: f.key,
295 Args: args,
296 }
297
298 buf := new(bytes.Buffer)
299 if err := gob.NewEncoder(buf).Encode(inv); err != nil {
300 return nil, fmt.Errorf("delay: gob encoding failed: %v", err)
301 }
302
303 return &taskqueue.Task{
304 Path: path,
305 Payload: buf.Bytes(),
306 }, nil
307 }
308
309 // Request returns the special task-queue HTTP request headers for the current
310 // task queue handler. Returns an error if called from outside a delay.Func.
311 func RequestHeaders(c context.Context) (*taskqueue.RequestHeaders, error) {
312 if ret, ok := c.Value(headersContextKey).(*taskqueue.RequestHeaders); ok {
313 return ret, nil
314 }
315 return nil, errOutsideDelayFunc
316 }
317
318 var taskqueueAdder = taskqueue.Add // for testing
319
320 func init() {
321 http.HandleFunc(path, func(w http.ResponseWriter, req *http.Request) {
322 runFunc(appengine.NewContext(req), w, req)
323 })
324 }
325
326 func runFunc(c context.Context, w http.ResponseWriter, req *http.Request) {
327 defer req.Body.Close()
328
329 c = context.WithValue(c, headersContextKey, taskqueue.ParseRequestHeaders(req.Header))
330
331 var inv invocation
332 if err := gob.NewDecoder(req.Body).Decode(&inv); err != nil {
333 log.Errorf(c, "delay: failed decoding task payload: %v", err)
334 log.Warningf(c, "delay: dropping task")
335 return
336 }
337
338 f := funcs[inv.Key]
339 if f == nil {
340 log.Errorf(c, "delay: no func with key %q found", inv.Key)
341 log.Warningf(c, "delay: dropping task")
342 return
343 }
344
345 ft := f.fv.Type()
346 in := []reflect.Value{reflect.ValueOf(c)}
347 for _, arg := range inv.Args {
348 var v reflect.Value
349 if arg != nil {
350 v = reflect.ValueOf(arg)
351 } else {
352 // Task was passed a nil argument, so we must construct
353 // the zero value for the argument here.
354 n := len(in) // we're constructing the nth argument
355 var at reflect.Type
356 if !ft.IsVariadic() || n < ft.NumIn()-1 {
357 at = ft.In(n)
358 } else {
359 at = ft.In(ft.NumIn() - 1).Elem()
360 }
361 v = reflect.Zero(at)
362 }
363 in = append(in, v)
364 }
365 out := f.fv.Call(in)
366
367 if n := ft.NumOut(); n > 0 && ft.Out(n-1) == errorType {
368 if errv := out[n-1]; !errv.IsNil() {
369 log.Errorf(c, "delay: func failed (will retry): %v", errv.Interface())
370 w.WriteHeader(http.StatusInternalServerError)
371 return
372 }
373 }
374 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package delay
5
6 import (
7 "bytes"
8 stdctx "context"
9 "encoding/gob"
10 "errors"
11 "fmt"
12 "net/http"
13 "net/http/httptest"
14 "os"
15 "path/filepath"
16 "reflect"
17 "testing"
18
19 "github.com/golang/protobuf/proto"
20 "golang.org/x/net/context"
21
22 "google.golang.org/appengine/v2/internal"
23 "google.golang.org/appengine/v2/taskqueue"
24 )
25
26 type CustomType struct {
27 N int
28 }
29
30 type CustomInterface interface {
31 N() int
32 }
33
34 type CustomImpl int
35
36 func (c CustomImpl) N() int { return int(c) }
37
38 // CustomImpl needs to be registered with gob.
39 func init() {
40 gob.Register(CustomImpl(0))
41 }
42
43 var (
44 regFRuns = 0
45 regFMsg = ""
46 regF = func(c context.Context, arg string) {
47 regFRuns++
48 regFMsg = arg
49 }
50 regFunc = Func("regFunc", regF)
51 regRegister = MustRegister("regRegister", regF)
52
53 custFTally = 0
54 custF = func(c context.Context, ct *CustomType, ci CustomInterface) {
55 a, b := 2, 3
56 if ct != nil {
57 a = ct.N
58 }
59 if ci != nil {
60 b = ci.N()
61 }
62 custFTally += a + b
63 }
64 custFunc = Func("custFunc", custF)
65 custRegister = MustRegister("custRegister", custF)
66
67 anotherCustFunc = Func("custFunc2", func(c context.Context, n int, ct *CustomType, ci CustomInterface) {
68 })
69
70 varFMsg = ""
71 varF = func(c context.Context, format string, args ...int) {
72 // convert []int to []interface{} for fmt.Sprintf.
73 as := make([]interface{}, len(args))
74 for i, a := range args {
75 as[i] = a
76 }
77 varFMsg = fmt.Sprintf(format, as...)
78 }
79 varFunc = Func("variadicFunc", varF)
80 varRegister = MustRegister("variadicRegister", varF)
81
82 errFRuns = 0
83 errFErr = errors.New("error!")
84 errF = func(c context.Context) error {
85 errFRuns++
86 if errFRuns == 1 {
87 return nil
88 }
89 return errFErr
90 }
91 errFunc = Func("errFunc", errF)
92 errRegister = MustRegister("errRegister", errF)
93
94 dupeWhich = 0
95 dupe1F = func(c context.Context) {
96 if dupeWhich == 0 {
97 dupeWhich = 1
98 }
99 }
100 dupe1Func = Func("dupe", dupe1F)
101 dupe2F = func(c context.Context) {
102 if dupeWhich == 0 {
103 dupeWhich = 2
104 }
105 }
106 dupe2Func = Func("dupe", dupe2F)
107
108 requestFuncRuns = 0
109 requestFuncHeaders *taskqueue.RequestHeaders
110 requestFuncErr error
111 requestF = func(c context.Context) {
112 requestFuncRuns++
113 requestFuncHeaders, requestFuncErr = RequestHeaders(c)
114 }
115 requestFunc = Func("requestFunc", requestF)
116 requestRegister = MustRegister("requestRegister", requestF)
117
118 stdCtxRuns = 0
119 stdCtxF = func(c stdctx.Context) {
120 stdCtxRuns++
121 }
122 stdCtxFunc = Func("stdctxFunc", stdCtxF)
123 stdCtxRegister = MustRegister("stdctxRegister", stdCtxF)
124 )
125
126 type fakeContext struct {
127 ctx context.Context
128 logging [][]interface{}
129 }
130
131 func newFakeContext() *fakeContext {
132 f := new(fakeContext)
133 f.ctx = internal.WithCallOverride(context.Background(), f.call)
134 f.ctx = internal.WithLogOverride(f.ctx, f.logf)
135 return f
136 }
137
138 func (f *fakeContext) call(ctx context.Context, service, method string, in, out proto.Message) error {
139 panic("should never be called")
140 }
141
142 var logLevels = map[int64]string{1: "INFO", 3: "ERROR"}
143
144 func (f *fakeContext) logf(level int64, format string, args ...interface{}) {
145 f.logging = append(f.logging, append([]interface{}{logLevels[level], format}, args...))
146 }
147
148 func TestInvalidFunction(t *testing.T) {
149 c := newFakeContext()
150 invalidFunc := Func("invalid", func() {})
151
152 if got, want := invalidFunc.Call(c.ctx), fmt.Errorf("delay: func is invalid: %s", errFirstArg); got.Error() != want.Error() {
153 t.Errorf("Incorrect error: got %q, want %q", got, want)
154 }
155 }
156
157 func TestVariadicFunctionArguments(t *testing.T) {
158 // Check the argument type validation for variadic functions.
159 c := newFakeContext()
160
161 calls := 0
162 taskqueueAdder = func(c context.Context, t *taskqueue.Task, _ string) (*taskqueue.Task, error) {
163 calls++
164 return t, nil
165 }
166
167 for _, testTarget := range []*Function{varFunc, varRegister} {
168 // reset state
169 calls = 0
170 testTarget.Call(c.ctx, "hi")
171 testTarget.Call(c.ctx, "%d", 12)
172 testTarget.Call(c.ctx, "%d %d %d", 3, 1, 4)
173 if calls != 3 {
174 t.Errorf("Got %d calls to taskqueueAdder, want 3", calls)
175 }
176
177 if got, want := testTarget.Call(c.ctx, "%d %s", 12, "a string is bad"), errors.New("delay: argument 3 has wrong type: string is not assignable to int"); got.Error() != want.Error() {
178 t.Errorf("Incorrect error: got %q, want %q", got, want)
179 }
180 }
181 }
182
183 func TestBadArguments(t *testing.T) {
184 // Try running regFunc with different sets of inappropriate arguments.
185
186 c := newFakeContext()
187
188 tests := []struct {
189 args []interface{} // all except context
190 wantErr string
191 }{
192 {
193 args: nil,
194 wantErr: "delay: too few arguments to func: 1 < 2",
195 },
196 {
197 args: []interface{}{"lala", 53},
198 wantErr: "delay: too many arguments to func: 3 > 2",
199 },
200 {
201 args: []interface{}{53},
202 wantErr: "delay: argument 1 has wrong type: int is not assignable to string",
203 },
204 }
205 for _, testTarget := range []*Function{regFunc, regRegister} {
206 for i, tc := range tests {
207 got := testTarget.Call(c.ctx, tc.args...)
208 if got.Error() != tc.wantErr {
209 t.Errorf("Call %v: got %q, want %q", i, got, tc.wantErr)
210 }
211 }
212 }
213 }
214
215 func TestRunningFunction(t *testing.T) {
216 c := newFakeContext()
217 // Fake out the adding of a task.
218 var task *taskqueue.Task
219 taskqueueAdder = func(_ context.Context, tk *taskqueue.Task, queue string) (*taskqueue.Task, error) {
220 if queue != "" {
221 t.Errorf(`Got queue %q, expected ""`, queue)
222 }
223 task = tk
224 return tk, nil
225 }
226
227 for _, testTarget := range []*Function{regFunc, regRegister} {
228 regFRuns, regFMsg = 0, "" // reset state
229 const msg = "Why, hello!"
230 testTarget.Call(c.ctx, msg)
231
232 // Simulate the Task Queue service.
233 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
234 if err != nil {
235 t.Fatalf("Failed making http.Request: %v", err)
236 }
237 rw := httptest.NewRecorder()
238 runFunc(c.ctx, rw, req)
239
240 if regFRuns != 1 {
241 t.Errorf("regFuncRuns: got %d, want 1", regFRuns)
242 }
243 if regFMsg != msg {
244 t.Errorf("regFuncMsg: got %q, want %q", regFMsg, msg)
245 }
246 }
247 }
248
249 func TestCustomType(t *testing.T) {
250 c := newFakeContext()
251
252 // Fake out the adding of a task.
253 var task *taskqueue.Task
254 taskqueueAdder = func(_ context.Context, tk *taskqueue.Task, queue string) (*taskqueue.Task, error) {
255 if queue != "" {
256 t.Errorf(`Got queue %q, expected ""`, queue)
257 }
258 task = tk
259 return tk, nil
260 }
261
262 for _, testTarget := range []*Function{custFunc, custRegister} {
263 custFTally = 0 // reset state
264 testTarget.Call(c.ctx, &CustomType{N: 11}, CustomImpl(13))
265
266 // Simulate the Task Queue service.
267 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
268 if err != nil {
269 t.Fatalf("Failed making http.Request: %v", err)
270 }
271 rw := httptest.NewRecorder()
272 runFunc(c.ctx, rw, req)
273
274 if custFTally != 24 {
275 t.Errorf("custFTally = %d, want 24", custFTally)
276 }
277
278 // Try the same, but with nil values; one is a nil pointer (and thus a non-nil interface value),
279 // and the other is a nil interface value.
280 custFTally = 0 // reset state
281 testTarget.Call(c.ctx, (*CustomType)(nil), nil)
282
283 // Simulate the Task Queue service.
284 req, err = http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
285 if err != nil {
286 t.Fatalf("Failed making http.Request: %v", err)
287 }
288 rw = httptest.NewRecorder()
289 runFunc(c.ctx, rw, req)
290
291 if custFTally != 5 {
292 t.Errorf("custFTally = %d, want 5", custFTally)
293 }
294 }
295 }
296
297 func TestRunningVariadic(t *testing.T) {
298 c := newFakeContext()
299
300 // Fake out the adding of a task.
301 var task *taskqueue.Task
302 taskqueueAdder = func(_ context.Context, tk *taskqueue.Task, queue string) (*taskqueue.Task, error) {
303 if queue != "" {
304 t.Errorf(`Got queue %q, expected ""`, queue)
305 }
306 task = tk
307 return tk, nil
308 }
309
310 for _, testTarget := range []*Function{varFunc, varRegister} {
311 varFMsg = "" // reset state
312 testTarget.Call(c.ctx, "Amiga %d has %d KB RAM", 500, 512)
313
314 // Simulate the Task Queue service.
315 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
316 if err != nil {
317 t.Fatalf("Failed making http.Request: %v", err)
318 }
319 rw := httptest.NewRecorder()
320 runFunc(c.ctx, rw, req)
321
322 const expected = "Amiga 500 has 512 KB RAM"
323 if varFMsg != expected {
324 t.Errorf("varFMsg = %q, want %q", varFMsg, expected)
325 }
326 }
327 }
328
329 func TestErrorFunction(t *testing.T) {
330 c := newFakeContext()
331
332 // Fake out the adding of a task.
333 var task *taskqueue.Task
334 taskqueueAdder = func(_ context.Context, tk *taskqueue.Task, queue string) (*taskqueue.Task, error) {
335 if queue != "" {
336 t.Errorf(`Got queue %q, expected ""`, queue)
337 }
338 task = tk
339 return tk, nil
340 }
341
342 for _, testTarget := range []*Function{errFunc, errRegister} {
343 // reset state
344 c.logging = [][]interface{}{}
345 errFRuns = 0
346 testTarget.Call(c.ctx)
347
348 // Simulate the Task Queue service.
349 // The first call should succeed; the second call should fail.
350 {
351 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
352 if err != nil {
353 t.Fatalf("Failed making http.Request: %v", err)
354 }
355 rw := httptest.NewRecorder()
356 runFunc(c.ctx, rw, req)
357 }
358 {
359 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
360 if err != nil {
361 t.Fatalf("Failed making http.Request: %v", err)
362 }
363 rw := httptest.NewRecorder()
364 runFunc(c.ctx, rw, req)
365 if rw.Code != http.StatusInternalServerError {
366 t.Errorf("Got status code %d, want %d", rw.Code, http.StatusInternalServerError)
367 }
368
369 wantLogging := [][]interface{}{
370 {"ERROR", "delay: func failed (will retry): %v", errFErr},
371 }
372 if !reflect.DeepEqual(c.logging, wantLogging) {
373 t.Errorf("Incorrect logging: got %+v, want %+v", c.logging, wantLogging)
374 }
375 }
376 }
377 }
378
379 func TestFuncDuplicateFunction(t *testing.T) {
380 c := newFakeContext()
381
382 // Fake out the adding of a task.
383 var task *taskqueue.Task
384 taskqueueAdder = func(_ context.Context, tk *taskqueue.Task, queue string) (*taskqueue.Task, error) {
385 if queue != "" {
386 t.Errorf(`Got queue %q, expected ""`, queue)
387 }
388 task = tk
389 return tk, nil
390 }
391
392 if err := dupe1Func.Call(c.ctx); err == nil {
393 t.Error("dupe1Func.Call did not return error")
394 }
395 if task != nil {
396 t.Error("dupe1Func.Call posted a task")
397 }
398 if err := dupe2Func.Call(c.ctx); err != nil {
399 t.Errorf("dupe2Func.Call error: %v", err)
400 }
401 if task == nil {
402 t.Fatalf("dupe2Func.Call did not post a task")
403 }
404
405 // Simulate the Task Queue service.
406 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
407 if err != nil {
408 t.Fatalf("Failed making http.Request: %v", err)
409 }
410 rw := httptest.NewRecorder()
411 runFunc(c.ctx, rw, req)
412
413 if dupeWhich == 1 {
414 t.Error("dupe2Func.Call used old registered function")
415 } else if dupeWhich != 2 {
416 t.Errorf("dupeWhich = %d; want 2", dupeWhich)
417 }
418 }
419
420 func TestMustRegisterDuplicateFunction(t *testing.T) {
421 MustRegister("dupe", dupe1F)
422 defer func() {
423 err := recover()
424 if err == nil {
425 t.Error("MustRegister did not panic")
426 }
427 got := fmt.Sprintf("%s", err)
428 want := fmt.Sprintf("multiple functions registered for %q", "dupe")
429 if got != want {
430 t.Errorf("Incorrect error: got %q, want %q", got, want)
431 }
432 }()
433 MustRegister("dupe", dupe2F)
434 }
435
436 func TestInvalidFunction_MustRegister(t *testing.T) {
437 defer func() {
438 err := recover()
439 if err == nil {
440 t.Error("MustRegister did not panic")
441 }
442 if err != errFirstArg {
443 t.Errorf("Incorrect error: got %q, want %q", err, errFirstArg)
444 }
445 }()
446 MustRegister("invalid", func() {})
447 }
448
449 func TestGetRequestHeadersFromContext(t *testing.T) {
450 for _, testTarget := range []*Function{requestFunc, requestRegister} {
451 c := newFakeContext()
452
453 // Outside a delay.Func should return an error.
454 headers, err := RequestHeaders(c.ctx)
455 if headers != nil {
456 t.Errorf("RequestHeaders outside Func, got %v, want nil", headers)
457 }
458 if err != errOutsideDelayFunc {
459 t.Errorf("RequestHeaders outside Func err, got %v, want %v", err, errOutsideDelayFunc)
460 }
461
462 // Fake out the adding of a task.
463 var task *taskqueue.Task
464 taskqueueAdder = func(_ context.Context, tk *taskqueue.Task, queue string) (*taskqueue.Task, error) {
465 if queue != "" {
466 t.Errorf(`Got queue %q, expected ""`, queue)
467 }
468 task = tk
469 return tk, nil
470 }
471
472 testTarget.Call(c.ctx)
473
474 requestFuncRuns, requestFuncHeaders = 0, nil // reset state
475 // Simulate the Task Queue service.
476 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
477 req.Header.Set("x-appengine-taskname", "foobar")
478 if err != nil {
479 t.Fatalf("Failed making http.Request: %v", err)
480 }
481 rw := httptest.NewRecorder()
482 runFunc(c.ctx, rw, req)
483
484 if requestFuncRuns != 1 {
485 t.Errorf("requestFuncRuns: got %d, want 1", requestFuncRuns)
486 }
487 if requestFuncHeaders.TaskName != "foobar" {
488 t.Errorf("requestFuncHeaders.TaskName: got %v, want 'foobar'", requestFuncHeaders.TaskName)
489 }
490 if requestFuncErr != nil {
491 t.Errorf("requestFuncErr: got %v, want nil", requestFuncErr)
492 }
493 }
494 }
495
496 func TestStandardContext(t *testing.T) {
497 // Fake out the adding of a task.
498 var task *taskqueue.Task
499 taskqueueAdder = func(_ context.Context, tk *taskqueue.Task, queue string) (*taskqueue.Task, error) {
500 if queue != "" {
501 t.Errorf(`Got queue %q, expected ""`, queue)
502 }
503 task = tk
504 return tk, nil
505 }
506
507 for _, testTarget := range []*Function{stdCtxFunc, stdCtxRegister} {
508 c := newFakeContext()
509 stdCtxRuns = 0 // reset state
510 if err := testTarget.Call(c.ctx); err != nil {
511 t.Fatal("Function.Call:", err)
512 }
513
514 // Simulate the Task Queue service.
515 req, err := http.NewRequest("POST", path, bytes.NewBuffer(task.Payload))
516 if err != nil {
517 t.Fatalf("Failed making http.Request: %v", err)
518 }
519 rw := httptest.NewRecorder()
520 runFunc(c.ctx, rw, req)
521
522 if stdCtxRuns != 1 {
523 t.Errorf("stdCtxRuns: got %d, want 1", stdCtxRuns)
524 }
525 }
526 }
527
528 func TestFileKey(t *testing.T) {
529 const firstGenTest = 0
530 tests := []struct {
531 mainPath string
532 file string
533 want string
534 }{
535 // first-gen
536 {
537 "",
538 filepath.FromSlash("srv/foo.go"),
539 filepath.FromSlash("srv/foo.go"),
540 },
541 // gopath
542 {
543 filepath.FromSlash("/tmp/staging1234/srv/"),
544 filepath.FromSlash("/tmp/staging1234/srv/foo.go"),
545 "foo.go",
546 },
547 {
548 filepath.FromSlash("/tmp/staging1234/srv/_gopath/src/example.com/foo"),
549 filepath.FromSlash("/tmp/staging1234/srv/_gopath/src/example.com/foo/foo.go"),
550 "foo.go",
551 },
552 {
553 filepath.FromSlash("/tmp/staging2234/srv/_gopath/src/example.com/foo"),
554 filepath.FromSlash("/tmp/staging2234/srv/_gopath/src/example.com/foo/bar/bar.go"),
555 filepath.FromSlash("example.com/foo/bar/bar.go"),
556 },
557 {
558 filepath.FromSlash("/tmp/staging3234/srv/_gopath/src/example.com/foo"),
559 filepath.FromSlash("/tmp/staging3234/srv/_gopath/src/example.com/bar/main.go"),
560 filepath.FromSlash("example.com/bar/main.go"),
561 },
562 {
563 filepath.FromSlash("/tmp/staging3234/srv/gopath/src/example.com/foo"),
564 filepath.FromSlash("/tmp/staging3234/srv/gopath/src/example.com/bar/main.go"),
565 filepath.FromSlash("example.com/bar/main.go"),
566 },
567 {
568 filepath.FromSlash(""),
569 filepath.FromSlash("/tmp/staging3234/srv/gopath/src/example.com/bar/main.go"),
570 filepath.FromSlash("example.com/bar/main.go"),
571 },
572 // go mod, same package
573 {
574 filepath.FromSlash("/tmp/staging3234/srv"),
575 filepath.FromSlash("/tmp/staging3234/srv/main.go"),
576 "main.go",
577 },
578 {
579 filepath.FromSlash("/tmp/staging3234/srv"),
580 filepath.FromSlash("/tmp/staging3234/srv/bar/main.go"),
581 filepath.FromSlash("bar/main.go"),
582 },
583 {
584 filepath.FromSlash("/tmp/staging3234/srv/cmd"),
585 filepath.FromSlash("/tmp/staging3234/srv/cmd/main.go"),
586 "main.go",
587 },
588 {
589 filepath.FromSlash("/tmp/staging3234/srv/cmd"),
590 filepath.FromSlash("/tmp/staging3234/srv/bar/main.go"),
591 filepath.FromSlash("bar/main.go"),
592 },
593 {
594 filepath.FromSlash(""),
595 filepath.FromSlash("/tmp/staging3234/srv/bar/main.go"),
596 filepath.FromSlash("bar/main.go"),
597 },
598 // go mod, other package
599 {
600 filepath.FromSlash("/tmp/staging3234/srv"),
601 filepath.FromSlash("/go/pkg/mod/github.com/foo/bar@v0.0.0-20181026220418-f595d03440dc/baz.go"),
602 filepath.FromSlash("github.com/foo/bar/baz.go"),
603 },
604 }
605 for i, tc := range tests {
606 if i > firstGenTest {
607 os.Setenv("GAE_ENV", "standard")
608 }
609 internal.MainPath = tc.mainPath
610 got, err := fileKey(tc.file)
611 if err != nil {
612 t.Errorf("Unexpected error, call %v, file %q: %v", i, tc.file, err)
613 continue
614 }
615 if got != tc.want {
616 t.Errorf("Call %v, file %q: got %q, want %q", i, tc.file, got, tc.want)
617 }
618 }
619 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // This file provides error functions for common API failure modes.
5
6 package appengine
7
8 import (
9 "fmt"
10
11 "google.golang.org/appengine/v2/internal"
12 )
13
14 // IsOverQuota reports whether err represents an API call failure
15 // due to insufficient available quota.
16 func IsOverQuota(err error) bool {
17 callErr, ok := err.(*internal.CallError)
18 return ok && callErr.Code == 4
19 }
20
21 // MultiError is returned by batch operations when there are errors with
22 // particular elements. Errors will be in a one-to-one correspondence with
23 // the input elements; successful elements will have a nil entry.
24 type MultiError []error
25
26 func (m MultiError) Error() string {
27 s, n := "", 0
28 for _, e := range m {
29 if e != nil {
30 if n == 0 {
31 s = e.Error()
32 }
33 n++
34 }
35 }
36 switch n {
37 case 0:
38 return "(0 errors)"
39 case 1:
40 return s
41 case 2:
42 return s + " (and 1 other error)"
43 }
44 return fmt.Sprintf("%s (and %d other errors)", s, n-1)
45 }
0 module google.golang.org/appengine/v2
1
2 go 1.11
3
4 require (
5 github.com/golang/protobuf v1.3.1
6 golang.org/x/net v0.0.0-20220708220712-1185a9018129
7 golang.org/x/text v0.3.7
8 )
0 github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
1 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
2 golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
3 golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
4 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
6 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
7 golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
8 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
9 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package appengine
5
6 import (
7 "context"
8 "time"
9
10 "google.golang.org/appengine/v2/internal"
11 pb "google.golang.org/appengine/v2/internal/app_identity"
12 modpb "google.golang.org/appengine/v2/internal/modules"
13 )
14
15 // AppID returns the application ID for the current application.
16 // The string will be a plain application ID (e.g. "appid"), with a
17 // domain prefix for custom domain deployments (e.g. "example.com:appid").
18 func AppID(c context.Context) string { return internal.AppID(c) }
19
20 // DefaultVersionHostname returns the standard hostname of the default version
21 // of the current application (e.g. "my-app.appspot.com"). This is suitable for
22 // use in constructing URLs.
23 func DefaultVersionHostname(c context.Context) string {
24 return internal.DefaultVersionHostname(c)
25 }
26
27 // ModuleName returns the module name of the current instance.
28 func ModuleName(c context.Context) string {
29 return internal.ModuleName(c)
30 }
31
32 // ModuleHostname returns a hostname of a module instance.
33 // If module is the empty string, it refers to the module of the current instance.
34 // If version is empty, it refers to the version of the current instance if valid,
35 // or the default version of the module of the current instance.
36 // If instance is empty, ModuleHostname returns the load-balancing hostname.
37 func ModuleHostname(c context.Context, module, version, instance string) (string, error) {
38 req := &modpb.GetHostnameRequest{}
39 if module != "" {
40 req.Module = &module
41 }
42 if version != "" {
43 req.Version = &version
44 }
45 if instance != "" {
46 req.Instance = &instance
47 }
48 res := &modpb.GetHostnameResponse{}
49 if err := internal.Call(c, "modules", "GetHostname", req, res); err != nil {
50 return "", err
51 }
52 return *res.Hostname, nil
53 }
54
55 // VersionID returns the version ID for the current application.
56 // It will be of the form "X.Y", where X is specified in app.yaml,
57 // and Y is a number generated when each version of the app is uploaded.
58 // It does not include a module name.
59 func VersionID(c context.Context) string { return internal.VersionID(c) }
60
61 // InstanceID returns a mostly-unique identifier for this instance.
62 func InstanceID() string { return internal.InstanceID() }
63
64 // Datacenter returns an identifier for the datacenter that the instance is running in.
65 func Datacenter(c context.Context) string { return internal.Datacenter(c) }
66
67 // ServerSoftware returns the App Engine release version.
68 // In production, it looks like "Google App Engine/X.Y.Z".
69 // In the development appserver, it looks like "Development/X.Y".
70 func ServerSoftware() string { return internal.ServerSoftware() }
71
72 // RequestID returns a string that uniquely identifies the request.
73 func RequestID(c context.Context) string { return internal.RequestID(c) }
74
75 // AccessToken generates an OAuth2 access token for the specified scopes on
76 // behalf of service account of this application. This token will expire after
77 // the returned time.
78 func AccessToken(c context.Context, scopes ...string) (token string, expiry time.Time, err error) {
79 req := &pb.GetAccessTokenRequest{Scope: scopes}
80 res := &pb.GetAccessTokenResponse{}
81
82 err = internal.Call(c, "app_identity_service", "GetAccessToken", req, res)
83 if err != nil {
84 return "", time.Time{}, err
85 }
86 return res.GetAccessToken(), time.Unix(res.GetExpirationTime(), 0), nil
87 }
88
89 // Certificate represents a public certificate for the app.
90 type Certificate struct {
91 KeyName string
92 Data []byte // PEM-encoded X.509 certificate
93 }
94
95 // PublicCertificates retrieves the public certificates for the app.
96 // They can be used to verify a signature returned by SignBytes.
97 func PublicCertificates(c context.Context) ([]Certificate, error) {
98 req := &pb.GetPublicCertificateForAppRequest{}
99 res := &pb.GetPublicCertificateForAppResponse{}
100 if err := internal.Call(c, "app_identity_service", "GetPublicCertificatesForApp", req, res); err != nil {
101 return nil, err
102 }
103 var cs []Certificate
104 for _, pc := range res.PublicCertificateList {
105 cs = append(cs, Certificate{
106 KeyName: pc.GetKeyName(),
107 Data: []byte(pc.GetX509CertificatePem()),
108 })
109 }
110 return cs, nil
111 }
112
113 // ServiceAccount returns a string representing the service account name, in
114 // the form of an email address (typically app_id@appspot.gserviceaccount.com).
115 func ServiceAccount(c context.Context) (string, error) {
116 req := &pb.GetServiceAccountNameRequest{}
117 res := &pb.GetServiceAccountNameResponse{}
118
119 err := internal.Call(c, "app_identity_service", "GetServiceAccountName", req, res)
120 if err != nil {
121 return "", err
122 }
123 return res.GetServiceAccountName(), err
124 }
125
126 // SignBytes signs bytes using a private key unique to your application.
127 func SignBytes(c context.Context, bytes []byte) (keyName string, signature []byte, err error) {
128 req := &pb.SignForAppRequest{BytesToSign: bytes}
129 res := &pb.SignForAppResponse{}
130
131 if err := internal.Call(c, "app_identity_service", "SignForApp", req, res); err != nil {
132 return "", nil, err
133 }
134 return res.GetKeyName(), res.GetSignatureBytes(), nil
135 }
136
137 func init() {
138 internal.RegisterErrorCodeMap("app_identity_service", pb.AppIdentityServiceError_ErrorCode_name)
139 internal.RegisterErrorCodeMap("modules", modpb.ModulesServiceError_ErrorCode_name)
140 }
0 // Copyright 2012 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package image provides image services.
5 package image // import "google.golang.org/appengine/v2/image"
6
7 import (
8 "context"
9 "fmt"
10 "net/url"
11
12 "google.golang.org/appengine/v2"
13 "google.golang.org/appengine/v2/internal"
14 pb "google.golang.org/appengine/v2/internal/image"
15 )
16
17 type ServingURLOptions struct {
18 Secure bool // whether the URL should use HTTPS
19
20 // Size must be between zero and 1600.
21 // If Size is non-zero, a resized version of the image is served,
22 // and Size is the served image's longest dimension. The aspect ratio is preserved.
23 // If Crop is true the image is cropped from the center instead of being resized.
24 Size int
25 Crop bool
26 }
27
28 // ServingURL returns a URL that will serve an image from Blobstore.
29 func ServingURL(c context.Context, key appengine.BlobKey, opts *ServingURLOptions) (*url.URL, error) {
30 req := &pb.ImagesGetUrlBaseRequest{
31 BlobKey: (*string)(&key),
32 }
33 if opts != nil && opts.Secure {
34 req.CreateSecureUrl = &opts.Secure
35 }
36 res := &pb.ImagesGetUrlBaseResponse{}
37 if err := internal.Call(c, "images", "GetUrlBase", req, res); err != nil {
38 return nil, err
39 }
40
41 // The URL may have suffixes added to dynamically resize or crop:
42 // - adding "=s32" will serve the image resized to 32 pixels, preserving the aspect ratio.
43 // - adding "=s32-c" is the same as "=s32" except it will be cropped.
44 u := *res.Url
45 if opts != nil && opts.Size > 0 {
46 u += fmt.Sprintf("=s%d", opts.Size)
47 if opts.Crop {
48 u += "-c"
49 }
50 }
51 return url.Parse(u)
52 }
53
54 // DeleteServingURL deletes the serving URL for an image.
55 func DeleteServingURL(c context.Context, key appengine.BlobKey) error {
56 req := &pb.ImagesDeleteUrlBaseRequest{
57 BlobKey: (*string)(&key),
58 }
59 res := &pb.ImagesDeleteUrlBaseResponse{}
60 return internal.Call(c, "images", "DeleteUrlBase", req, res)
61 }
62
63 func init() {
64 internal.RegisterErrorCodeMap("images", pb.ImagesServiceError_ErrorCode_name)
65 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package aetesting provides utilities for testing App Engine packages.
5 // This is not for testing user applications.
6 package aetesting
7
8 import (
9 "context"
10 "fmt"
11 "net/http"
12 "reflect"
13 "testing"
14
15 "github.com/golang/protobuf/proto"
16
17 "google.golang.org/appengine/v2/internal"
18 )
19
20 // FakeSingleContext returns a context whose Call invocations will be serviced
21 // by f, which should be a function that has two arguments of the input and output
22 // protocol buffer type, and one error return.
23 func FakeSingleContext(t *testing.T, service, method string, f interface{}) context.Context {
24 fv := reflect.ValueOf(f)
25 if fv.Kind() != reflect.Func {
26 t.Fatal("not a function")
27 }
28 ft := fv.Type()
29 if ft.NumIn() != 2 || ft.NumOut() != 1 {
30 t.Fatalf("f has %d in and %d out, want 2 in and 1 out", ft.NumIn(), ft.NumOut())
31 }
32 for i := 0; i < 2; i++ {
33 at := ft.In(i)
34 if !at.Implements(protoMessageType) {
35 t.Fatalf("arg %d does not implement proto.Message", i)
36 }
37 }
38 if ft.Out(0) != errorType {
39 t.Fatalf("f's return is %v, want error", ft.Out(0))
40 }
41 s := &single{
42 t: t,
43 service: service,
44 method: method,
45 f: fv,
46 }
47 return internal.WithCallOverride(internal.ContextForTesting(&http.Request{}), s.call)
48 }
49
50 var (
51 protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem()
52 errorType = reflect.TypeOf((*error)(nil)).Elem()
53 )
54
55 type single struct {
56 t *testing.T
57 service, method string
58 f reflect.Value
59 }
60
61 func (s *single) call(ctx context.Context, service, method string, in, out proto.Message) error {
62 if service == "__go__" {
63 if method == "GetNamespace" {
64 return nil // always yield an empty namespace
65 }
66 return fmt.Errorf("Unknown API call /%s.%s", service, method)
67 }
68 if service != s.service || method != s.method {
69 s.t.Fatalf("Unexpected call to /%s.%s", service, method)
70 }
71 ins := []reflect.Value{
72 reflect.ValueOf(in),
73 reflect.ValueOf(out),
74 }
75 outs := s.f.Call(ins)
76 if outs[0].IsNil() {
77 return nil
78 }
79 return outs[0].Interface().(error)
80 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "bytes"
8 netcontext "context"
9 "errors"
10 "fmt"
11 "io"
12 "io/ioutil"
13 "net"
14 "net/http"
15 "net/url"
16 "os"
17 "runtime"
18 "strconv"
19 "sync/atomic"
20 "time"
21
22 "github.com/golang/protobuf/proto"
23
24 remotepb "google.golang.org/appengine/v2/internal/remote_api"
25 )
26
27 const (
28 apiPath = "/rpc_http"
29 )
30
31 var (
32 // Incoming headers.
33 ticketHeader = http.CanonicalHeaderKey("X-AppEngine-API-Ticket")
34 dapperHeader = http.CanonicalHeaderKey("X-Google-DapperTraceInfo")
35 traceHeader = http.CanonicalHeaderKey("X-Cloud-Trace-Context")
36 curNamespaceHeader = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
37 userIPHeader = http.CanonicalHeaderKey("X-AppEngine-User-IP")
38 remoteAddrHeader = http.CanonicalHeaderKey("X-AppEngine-Remote-Addr")
39 devRequestIdHeader = http.CanonicalHeaderKey("X-Appengine-Dev-Request-Id")
40
41 // Outgoing headers.
42 apiEndpointHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Endpoint")
43 apiEndpointHeaderValue = []string{"app-engine-apis"}
44 apiMethodHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Method")
45 apiMethodHeaderValue = []string{"/VMRemoteAPI.CallRemoteAPI"}
46 apiDeadlineHeader = http.CanonicalHeaderKey("X-Google-RPC-Service-Deadline")
47 apiContentType = http.CanonicalHeaderKey("Content-Type")
48 apiContentTypeValue = []string{"application/octet-stream"}
49 logFlushHeader = http.CanonicalHeaderKey("X-AppEngine-Log-Flush-Count")
50
51 apiHTTPClient = &http.Client{
52 Transport: &http.Transport{
53 Proxy: http.ProxyFromEnvironment,
54 Dial: limitDial,
55 MaxIdleConns: 1000,
56 MaxIdleConnsPerHost: 10000,
57 IdleConnTimeout: 90 * time.Second,
58 },
59 }
60
61 logStream io.Writer = os.Stderr // For test hooks.
62 timeNow func() time.Time = time.Now // For test hooks.
63 )
64
65 func apiURL(ctx netcontext.Context) *url.URL {
66 host, port := "appengine.googleapis.internal", "10001"
67 if h := os.Getenv("API_HOST"); h != "" {
68 host = h
69 }
70 if hostOverride := ctx.Value(apiHostOverrideKey); hostOverride != nil {
71 host = hostOverride.(string)
72 }
73 if p := os.Getenv("API_PORT"); p != "" {
74 port = p
75 }
76 if portOverride := ctx.Value(apiPortOverrideKey); portOverride != nil {
77 port = portOverride.(string)
78 }
79 return &url.URL{
80 Scheme: "http",
81 Host: host + ":" + port,
82 Path: apiPath,
83 }
84 }
85
86 // Middleware wraps an http handler so that it can make GAE API calls
87 func Middleware(next http.Handler) http.Handler {
88 return handleHTTPMiddleware(executeRequestSafelyMiddleware(next))
89 }
90
91 func handleHTTPMiddleware(next http.Handler) http.Handler {
92 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
93 c := &context{
94 req: r,
95 outHeader: w.Header(),
96 }
97 r = r.WithContext(withContext(r.Context(), c))
98 c.req = r
99
100 // Patch up RemoteAddr so it looks reasonable.
101 if addr := r.Header.Get(userIPHeader); addr != "" {
102 r.RemoteAddr = addr
103 } else if addr = r.Header.Get(remoteAddrHeader); addr != "" {
104 r.RemoteAddr = addr
105 } else {
106 // Should not normally reach here, but pick a sensible default anyway.
107 r.RemoteAddr = "127.0.0.1"
108 }
109 // The address in the headers will most likely be of these forms:
110 // 123.123.123.123
111 // 2001:db8::1
112 // net/http.Request.RemoteAddr is specified to be in "IP:port" form.
113 if _, _, err := net.SplitHostPort(r.RemoteAddr); err != nil {
114 // Assume the remote address is only a host; add a default port.
115 r.RemoteAddr = net.JoinHostPort(r.RemoteAddr, "80")
116 }
117
118 next.ServeHTTP(c, r)
119 c.outHeader = nil // make sure header changes aren't respected any more
120
121 // Avoid nil Write call if c.Write is never called.
122 if c.outCode != 0 {
123 w.WriteHeader(c.outCode)
124 }
125 if c.outBody != nil {
126 w.Write(c.outBody)
127 }
128 })
129 }
130
131 func executeRequestSafelyMiddleware(next http.Handler) http.Handler {
132 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
133 defer func() {
134 if x := recover(); x != nil {
135 c := w.(*context)
136 logf(c, 4, "%s", renderPanic(x)) // 4 == critical
137 c.outCode = 500
138 }
139 }()
140
141 next.ServeHTTP(w, r)
142 })
143 }
144
145 func renderPanic(x interface{}) string {
146 buf := make([]byte, 16<<10) // 16 KB should be plenty
147 buf = buf[:runtime.Stack(buf, false)]
148
149 // Remove the first few stack frames:
150 // this func
151 // the recover closure in the caller
152 // That will root the stack trace at the site of the panic.
153 const (
154 skipStart = "internal.renderPanic"
155 skipFrames = 2
156 )
157 start := bytes.Index(buf, []byte(skipStart))
158 p := start
159 for i := 0; i < skipFrames*2 && p+1 < len(buf); i++ {
160 p = bytes.IndexByte(buf[p+1:], '\n') + p + 1
161 if p < 0 {
162 break
163 }
164 }
165 if p >= 0 {
166 // buf[start:p+1] is the block to remove.
167 // Copy buf[p+1:] over buf[start:] and shrink buf.
168 copy(buf[start:], buf[p+1:])
169 buf = buf[:len(buf)-(p+1-start)]
170 }
171
172 // Add panic heading.
173 head := fmt.Sprintf("panic: %v\n\n", x)
174 if len(head) > len(buf) {
175 // Extremely unlikely to happen.
176 return head
177 }
178 copy(buf[len(head):], buf)
179 copy(buf, head)
180
181 return string(buf)
182 }
183
184 // context represents the context of an in-flight HTTP request.
185 // It implements the appengine.Context and http.ResponseWriter interfaces.
186 type context struct {
187 req *http.Request
188
189 outCode int
190 outHeader http.Header
191 outBody []byte
192 }
193
194 var contextKey = "holds a *context"
195
196 // jointContext joins two contexts in a superficial way.
197 // It takes values and timeouts from a base context, and only values from another context.
198 type jointContext struct {
199 base netcontext.Context
200 valuesOnly netcontext.Context
201 }
202
203 func (c jointContext) Deadline() (time.Time, bool) {
204 return c.base.Deadline()
205 }
206
207 func (c jointContext) Done() <-chan struct{} {
208 return c.base.Done()
209 }
210
211 func (c jointContext) Err() error {
212 return c.base.Err()
213 }
214
215 func (c jointContext) Value(key interface{}) interface{} {
216 if val := c.base.Value(key); val != nil {
217 return val
218 }
219 return c.valuesOnly.Value(key)
220 }
221
222 // fromContext returns the App Engine context or nil if ctx is not
223 // derived from an App Engine context.
224 func fromContext(ctx netcontext.Context) *context {
225 c, _ := ctx.Value(&contextKey).(*context)
226 return c
227 }
228
229 func withContext(parent netcontext.Context, c *context) netcontext.Context {
230 ctx := netcontext.WithValue(parent, &contextKey, c)
231 if ns := c.req.Header.Get(curNamespaceHeader); ns != "" {
232 ctx = withNamespace(ctx, ns)
233 }
234 return ctx
235 }
236
237 func toContext(c *context) netcontext.Context {
238 return withContext(netcontext.Background(), c)
239 }
240
241 func IncomingHeaders(ctx netcontext.Context) http.Header {
242 if c := fromContext(ctx); c != nil {
243 return c.req.Header
244 }
245 return nil
246 }
247
248 func ReqContext(req *http.Request) netcontext.Context {
249 return req.Context()
250 }
251
252 func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
253 return jointContext{
254 base: parent,
255 valuesOnly: req.Context(),
256 }
257 }
258
259 // RegisterTestRequest registers the HTTP request req for testing, such that
260 // any API calls are sent to the provided URL. It returns a closure to delete
261 // the registration.
262 // It should only be used by aetest package.
263 func RegisterTestRequest(req *http.Request, apiURL *url.URL, appID string) *http.Request {
264 ctx := req.Context()
265 ctx = withAPIHostOverride(ctx, apiURL.Hostname())
266 ctx = withAPIPortOverride(ctx, apiURL.Port())
267 ctx = WithAppIDOverride(ctx, appID)
268
269 // use the unregistered request as a placeholder so that withContext can read the headers
270 c := &context{req: req}
271 c.req = req.WithContext(withContext(ctx, c))
272 return c.req
273 }
274
275 var errTimeout = &CallError{
276 Detail: "Deadline exceeded",
277 Code: int32(remotepb.RpcError_CANCELLED),
278 Timeout: true,
279 }
280
281 func (c *context) Header() http.Header { return c.outHeader }
282
283 // Copied from $GOROOT/src/pkg/net/http/transfer.go. Some response status
284 // codes do not permit a response body (nor response entity headers such as
285 // Content-Length, Content-Type, etc).
286 func bodyAllowedForStatus(status int) bool {
287 switch {
288 case status >= 100 && status <= 199:
289 return false
290 case status == 204:
291 return false
292 case status == 304:
293 return false
294 }
295 return true
296 }
297
298 func (c *context) Write(b []byte) (int, error) {
299 if c.outCode == 0 {
300 c.WriteHeader(http.StatusOK)
301 }
302 if len(b) > 0 && !bodyAllowedForStatus(c.outCode) {
303 return 0, http.ErrBodyNotAllowed
304 }
305 c.outBody = append(c.outBody, b...)
306 return len(b), nil
307 }
308
309 func (c *context) WriteHeader(code int) {
310 if c.outCode != 0 {
311 logf(c, 3, "WriteHeader called multiple times on request.") // error level
312 return
313 }
314 c.outCode = code
315 }
316
317 func post(ctx netcontext.Context, body []byte, timeout time.Duration) (b []byte, err error) {
318 apiURL := apiURL(ctx)
319 hreq := &http.Request{
320 Method: "POST",
321 URL: apiURL,
322 Header: http.Header{
323 apiEndpointHeader: apiEndpointHeaderValue,
324 apiMethodHeader: apiMethodHeaderValue,
325 apiContentType: apiContentTypeValue,
326 apiDeadlineHeader: []string{strconv.FormatFloat(timeout.Seconds(), 'f', -1, 64)},
327 },
328 Body: ioutil.NopCloser(bytes.NewReader(body)),
329 ContentLength: int64(len(body)),
330 Host: apiURL.Host,
331 }
332 c := fromContext(ctx)
333 if c != nil {
334 if info := c.req.Header.Get(dapperHeader); info != "" {
335 hreq.Header.Set(dapperHeader, info)
336 }
337 if info := c.req.Header.Get(traceHeader); info != "" {
338 hreq.Header.Set(traceHeader, info)
339 }
340 }
341
342 tr := apiHTTPClient.Transport.(*http.Transport)
343
344 var timedOut int32 // atomic; set to 1 if timed out
345 t := time.AfterFunc(timeout, func() {
346 atomic.StoreInt32(&timedOut, 1)
347 tr.CancelRequest(hreq)
348 })
349 defer t.Stop()
350 defer func() {
351 // Check if timeout was exceeded.
352 if atomic.LoadInt32(&timedOut) != 0 {
353 err = errTimeout
354 }
355 }()
356
357 hresp, err := apiHTTPClient.Do(hreq)
358 if err != nil {
359 return nil, &CallError{
360 Detail: fmt.Sprintf("service bridge HTTP failed: %v", err),
361 Code: int32(remotepb.RpcError_UNKNOWN),
362 }
363 }
364 defer hresp.Body.Close()
365 hrespBody, err := ioutil.ReadAll(hresp.Body)
366 if hresp.StatusCode != 200 {
367 return nil, &CallError{
368 Detail: fmt.Sprintf("service bridge returned HTTP %d (%q)", hresp.StatusCode, hrespBody),
369 Code: int32(remotepb.RpcError_UNKNOWN),
370 }
371 }
372 if err != nil {
373 return nil, &CallError{
374 Detail: fmt.Sprintf("service bridge response bad: %v", err),
375 Code: int32(remotepb.RpcError_UNKNOWN),
376 }
377 }
378 return hrespBody, nil
379 }
380
381 func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
382 if ns := NamespaceFromContext(ctx); ns != "" {
383 if fn, ok := NamespaceMods[service]; ok {
384 fn(in, ns)
385 }
386 }
387
388 if f, ctx, ok := callOverrideFromContext(ctx); ok {
389 return f(ctx, service, method, in, out)
390 }
391
392 // Handle already-done contexts quickly.
393 select {
394 case <-ctx.Done():
395 return ctx.Err()
396 default:
397 }
398
399 c := fromContext(ctx)
400
401 // Apply transaction modifications if we're in a transaction.
402 if t := transactionFromContext(ctx); t != nil {
403 if t.finished {
404 return errors.New("transaction context has expired")
405 }
406 applyTransaction(in, &t.transaction)
407 }
408
409 // Default RPC timeout is 60s.
410 timeout := 60 * time.Second
411 if deadline, ok := ctx.Deadline(); ok {
412 timeout = deadline.Sub(time.Now())
413 }
414
415 data, err := proto.Marshal(in)
416 if err != nil {
417 return err
418 }
419
420 ticket := ""
421 if c != nil {
422 ticket = c.req.Header.Get(ticketHeader)
423 if dri := c.req.Header.Get(devRequestIdHeader); IsDevAppServer() && dri != "" {
424 ticket = dri
425 }
426 }
427 req := &remotepb.Request{
428 ServiceName: &service,
429 Method: &method,
430 Request: data,
431 RequestId: &ticket,
432 }
433 hreqBody, err := proto.Marshal(req)
434 if err != nil {
435 return err
436 }
437
438 hrespBody, err := post(ctx, hreqBody, timeout)
439 if err != nil {
440 return err
441 }
442
443 res := &remotepb.Response{}
444 if err := proto.Unmarshal(hrespBody, res); err != nil {
445 return err
446 }
447 if res.RpcError != nil {
448 ce := &CallError{
449 Detail: res.RpcError.GetDetail(),
450 Code: *res.RpcError.Code,
451 }
452 switch remotepb.RpcError_ErrorCode(ce.Code) {
453 case remotepb.RpcError_CANCELLED, remotepb.RpcError_DEADLINE_EXCEEDED:
454 ce.Timeout = true
455 }
456 return ce
457 }
458 if res.ApplicationError != nil {
459 return &APIError{
460 Service: *req.ServiceName,
461 Detail: res.ApplicationError.GetDetail(),
462 Code: *res.ApplicationError.Code,
463 }
464 }
465 if res.Exception != nil || res.JavaException != nil {
466 // This shouldn't happen, but let's be defensive.
467 return &CallError{
468 Detail: "service bridge returned exception",
469 Code: int32(remotepb.RpcError_UNKNOWN),
470 }
471 }
472 return proto.Unmarshal(res.Response, out)
473 }
474
475 func (c *context) Request() *http.Request {
476 return c.req
477 }
478
479 func ContextForTesting(req *http.Request) netcontext.Context {
480 return toContext(&context{req: req})
481 }
0 // Copyright 2015 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 netcontext "context"
8 "errors"
9 "os"
10
11 "github.com/golang/protobuf/proto"
12 )
13
14 type ctxKey string
15
16 func (c ctxKey) String() string {
17 return "appengine context key: " + string(c)
18 }
19
20 var errNotAppEngineContext = errors.New("not an App Engine context")
21
22 type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error
23
24 var callOverrideKey = "holds []CallOverrideFunc"
25
26 func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Context {
27 // We avoid appending to any existing call override
28 // so we don't risk overwriting a popped stack below.
29 var cofs []CallOverrideFunc
30 if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok {
31 cofs = append(cofs, uf...)
32 }
33 cofs = append(cofs, f)
34 return netcontext.WithValue(ctx, &callOverrideKey, cofs)
35 }
36
37 func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.Context, bool) {
38 cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc)
39 if len(cofs) == 0 {
40 return nil, nil, false
41 }
42 // We found a list of overrides; grab the last, and reconstitute a
43 // context that will hide it.
44 f := cofs[len(cofs)-1]
45 ctx = netcontext.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1])
46 return f, ctx, true
47 }
48
49 type logOverrideFunc func(level int64, format string, args ...interface{})
50
51 var logOverrideKey = "holds a logOverrideFunc"
52
53 func WithLogOverride(ctx netcontext.Context, f logOverrideFunc) netcontext.Context {
54 return netcontext.WithValue(ctx, &logOverrideKey, f)
55 }
56
57 var appIDOverrideKey = "holds a string, being the full app ID"
58
59 func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context {
60 return netcontext.WithValue(ctx, &appIDOverrideKey, appID)
61 }
62
63 var apiHostOverrideKey = ctxKey("holds a string, being the alternate API_HOST")
64
65 func withAPIHostOverride(ctx netcontext.Context, apiHost string) netcontext.Context {
66 return netcontext.WithValue(ctx, apiHostOverrideKey, apiHost)
67 }
68
69 var apiPortOverrideKey = ctxKey("holds a string, being the alternate API_PORT")
70
71 func withAPIPortOverride(ctx netcontext.Context, apiPort string) netcontext.Context {
72 return netcontext.WithValue(ctx, apiPortOverrideKey, apiPort)
73 }
74
75 var namespaceKey = "holds the namespace string"
76
77 func withNamespace(ctx netcontext.Context, ns string) netcontext.Context {
78 return netcontext.WithValue(ctx, &namespaceKey, ns)
79 }
80
81 func NamespaceFromContext(ctx netcontext.Context) string {
82 // If there's no namespace, return the empty string.
83 ns, _ := ctx.Value(&namespaceKey).(string)
84 return ns
85 }
86
87 // FullyQualifiedAppID returns the fully-qualified application ID.
88 // This may contain a partition prefix (e.g. "s~" for High Replication apps),
89 // or a domain prefix (e.g. "example.com:").
90 func FullyQualifiedAppID(ctx netcontext.Context) string {
91 if id, ok := ctx.Value(&appIDOverrideKey).(string); ok {
92 return id
93 }
94 return fullyQualifiedAppID(ctx)
95 }
96
97 func Logf(ctx netcontext.Context, level int64, format string, args ...interface{}) {
98 if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok {
99 f(level, format, args...)
100 return
101 }
102 c := fromContext(ctx)
103 if c == nil {
104 panic(errNotAppEngineContext)
105 }
106 logf(c, level, format, args...)
107 }
108
109 // NamespacedContext wraps a Context to support namespaces.
110 func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context {
111 return withNamespace(ctx, namespace)
112 }
113
114 // SetTestEnv sets the env variables for testing background ticket in Flex.
115 func SetTestEnv() func() {
116 var environ = []struct {
117 key, value string
118 }{
119 {"GAE_LONG_APP_ID", "my-app-id"},
120 {"GAE_MINOR_VERSION", "067924799508853122"},
121 {"GAE_MODULE_INSTANCE", "0"},
122 {"GAE_MODULE_NAME", "default"},
123 {"GAE_MODULE_VERSION", "20150612t184001"},
124 }
125
126 for _, v := range environ {
127 old := os.Getenv(v.key)
128 os.Setenv(v.key, v.value)
129 v.value = old
130 }
131 return func() { // Restore old environment after the test completes.
132 for _, v := range environ {
133 if v.value == "" {
134 os.Unsetenv(v.key)
135 continue
136 }
137 os.Setenv(v.key, v.value)
138 }
139 }
140 }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 //go:build race
5 // +build race
6
7 package internal
8
9 func init() { raceDetector = true }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "bufio"
8 "bytes"
9 netcontext "context"
10 "fmt"
11 "io"
12 "io/ioutil"
13 "net/http"
14 "net/http/httptest"
15 "net/url"
16 "os"
17 "os/exec"
18 "strings"
19 "sync/atomic"
20 "testing"
21 "time"
22
23 "github.com/golang/protobuf/proto"
24
25 basepb "google.golang.org/appengine/v2/internal/base"
26 remotepb "google.golang.org/appengine/v2/internal/remote_api"
27 )
28
29 const testTicketHeader = "X-Magic-Ticket-Header"
30
31 func init() {
32 ticketHeader = testTicketHeader
33 }
34
35 type fakeAPIHandler struct {
36 hang chan int // used for RunSlowly RPC
37
38 LogFlushes int32 // atomic
39
40 allowMissingTicket bool
41 }
42
43 func (f *fakeAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
44 writeResponse := func(res *remotepb.Response) {
45 hresBody, err := proto.Marshal(res)
46 if err != nil {
47 http.Error(w, fmt.Sprintf("Failed encoding API response: %v", err), 500)
48 return
49 }
50 w.Write(hresBody)
51 }
52
53 if r.URL.Path != "/rpc_http" {
54 http.NotFound(w, r)
55 return
56 }
57 hreqBody, err := ioutil.ReadAll(r.Body)
58 if err != nil {
59 http.Error(w, fmt.Sprintf("Bad body: %v", err), 500)
60 return
61 }
62 apiReq := &remotepb.Request{}
63 if err := proto.Unmarshal(hreqBody, apiReq); err != nil {
64 http.Error(w, fmt.Sprintf("Bad encoded API request: %v", err), 500)
65 return
66 }
67 if *apiReq.RequestId != "s3cr3t" && !f.allowMissingTicket {
68 writeResponse(&remotepb.Response{
69 RpcError: &remotepb.RpcError{
70 Code: proto.Int32(int32(remotepb.RpcError_SECURITY_VIOLATION)),
71 Detail: proto.String("bad security ticket"),
72 },
73 })
74 return
75 }
76 if got, want := r.Header.Get(dapperHeader), "trace-001"; got != want {
77 writeResponse(&remotepb.Response{
78 RpcError: &remotepb.RpcError{
79 Code: proto.Int32(int32(remotepb.RpcError_BAD_REQUEST)),
80 Detail: proto.String(fmt.Sprintf("trace info = %q, want %q", got, want)),
81 },
82 })
83 return
84 }
85
86 service, method := *apiReq.ServiceName, *apiReq.Method
87 var resOut proto.Message
88 if service == "actordb" && method == "LookupActor" {
89 req := &basepb.StringProto{}
90 res := &basepb.StringProto{}
91 if err := proto.Unmarshal(apiReq.Request, req); err != nil {
92 http.Error(w, fmt.Sprintf("Bad encoded request: %v", err), 500)
93 return
94 }
95 if *req.Value == "Doctor Who" {
96 res.Value = proto.String("David Tennant")
97 }
98 resOut = res
99 }
100 if service == "errors" {
101 switch method {
102 case "Non200":
103 http.Error(w, "I'm a little teapot.", 418)
104 return
105 case "ShortResponse":
106 w.Header().Set("Content-Length", "100")
107 w.Write([]byte("way too short"))
108 return
109 case "OverQuota":
110 writeResponse(&remotepb.Response{
111 RpcError: &remotepb.RpcError{
112 Code: proto.Int32(int32(remotepb.RpcError_OVER_QUOTA)),
113 Detail: proto.String("you are hogging the resources!"),
114 },
115 })
116 return
117 case "RunSlowly":
118 // TestAPICallRPCFailure creates f.hang, but does not strobe it
119 // until Call returns with remotepb.RpcError_CANCELLED.
120 // This is here to force a happens-before relationship between
121 // the httptest server handler and shutdown.
122 <-f.hang
123 resOut = &basepb.VoidProto{}
124 }
125 }
126 if service == "logservice" && method == "Flush" {
127 // Pretend log flushing is slow.
128 time.Sleep(50 * time.Millisecond)
129 atomic.AddInt32(&f.LogFlushes, 1)
130 resOut = &basepb.VoidProto{}
131 }
132
133 encOut, err := proto.Marshal(resOut)
134 if err != nil {
135 http.Error(w, fmt.Sprintf("Failed encoding response: %v", err), 500)
136 return
137 }
138 writeResponse(&remotepb.Response{
139 Response: encOut,
140 })
141 }
142
143 func setup() (f *fakeAPIHandler, c *context, cleanup func()) {
144 f = &fakeAPIHandler{}
145 srv := httptest.NewServer(f)
146 u, err := url.Parse(srv.URL + apiPath)
147 restoreAPIHost := restoreEnvVar("API_HOST")
148 restoreAPIPort := restoreEnvVar("API_HOST")
149 os.Setenv("API_HOST", u.Hostname())
150 os.Setenv("API_PORT", u.Port())
151 if err != nil {
152 panic(fmt.Sprintf("url.Parse(%q): %v", srv.URL+apiPath, err))
153 }
154 return f, &context{
155 req: &http.Request{
156 Header: http.Header{
157 ticketHeader: []string{"s3cr3t"},
158 dapperHeader: []string{"trace-001"},
159 },
160 },
161 }, func() {
162 restoreAPIHost()
163 restoreAPIPort()
164 srv.Close()
165 }
166 }
167
168 func restoreEnvVar(key string) (cleanup func()) {
169 oldval, ok := os.LookupEnv(key)
170 return func() {
171 if ok {
172 os.Setenv(key, oldval)
173 } else {
174 os.Unsetenv(key)
175 }
176 }
177 }
178
179 func TestAPICall(t *testing.T) {
180 _, c, cleanup := setup()
181 defer cleanup()
182
183 req := &basepb.StringProto{
184 Value: proto.String("Doctor Who"),
185 }
186 res := &basepb.StringProto{}
187 err := Call(toContext(c), "actordb", "LookupActor", req, res)
188 if err != nil {
189 t.Fatalf("API call failed: %v", err)
190 }
191 if got, want := *res.Value, "David Tennant"; got != want {
192 t.Errorf("Response is %q, want %q", got, want)
193 }
194 }
195
196 func TestAPICallTicketUnavailable(t *testing.T) {
197 resetEnv := SetTestEnv()
198 defer resetEnv()
199 f, c, cleanup := setup()
200 defer cleanup()
201 f.allowMissingTicket = true
202
203 c.req.Header.Set(ticketHeader, "")
204 req := &basepb.StringProto{
205 Value: proto.String("Doctor Who"),
206 }
207 res := &basepb.StringProto{}
208 err := Call(toContext(c), "actordb", "LookupActor", req, res)
209 if err != nil {
210 t.Fatalf("API call failed: %v", err)
211 }
212 if got, want := *res.Value, "David Tennant"; got != want {
213 t.Errorf("Response is %q, want %q", got, want)
214 }
215 }
216
217 func TestAPICallRPCFailure(t *testing.T) {
218 f, c, cleanup := setup()
219 defer cleanup()
220
221 testCases := []struct {
222 method string
223 code remotepb.RpcError_ErrorCode
224 }{
225 {"Non200", remotepb.RpcError_UNKNOWN},
226 {"ShortResponse", remotepb.RpcError_UNKNOWN},
227 {"OverQuota", remotepb.RpcError_OVER_QUOTA},
228 {"RunSlowly", remotepb.RpcError_CANCELLED},
229 }
230 f.hang = make(chan int) // only for RunSlowly
231 for _, tc := range testCases {
232 ctx, _ := netcontext.WithTimeout(toContext(c), 100*time.Millisecond)
233 err := Call(ctx, "errors", tc.method, &basepb.VoidProto{}, &basepb.VoidProto{})
234 ce, ok := err.(*CallError)
235 if !ok {
236 t.Errorf("%s: API call error is %T (%v), want *CallError", tc.method, err, err)
237 continue
238 }
239 if ce.Code != int32(tc.code) {
240 t.Errorf("%s: ce.Code = %d, want %d", tc.method, ce.Code, tc.code)
241 }
242 if tc.method == "RunSlowly" {
243 f.hang <- 1 // release the HTTP handler
244 }
245 }
246 }
247
248 func TestAPICallDialFailure(t *testing.T) {
249 // See what happens if the API host is unresponsive.
250 // This should time out quickly, not hang forever.
251 // We intentially don't set up the fakeAPIHandler for this test to cause the dail failure.
252 start := time.Now()
253 err := Call(netcontext.Background(), "foo", "bar", &basepb.VoidProto{}, &basepb.VoidProto{})
254 const max = 1 * time.Second
255 if taken := time.Since(start); taken > max {
256 t.Errorf("Dial hang took too long: %v > %v", taken, max)
257 }
258 if err == nil {
259 t.Error("Call did not fail")
260 }
261 }
262
263 func TestRemoteAddr(t *testing.T) {
264 var addr string
265 http.HandleFunc("/remote_addr", func(w http.ResponseWriter, r *http.Request) {
266 addr = r.RemoteAddr
267 })
268
269 testCases := []struct {
270 headers http.Header
271 addr string
272 }{
273 {http.Header{"X-Appengine-User-Ip": []string{"10.5.2.1"}}, "10.5.2.1:80"},
274 {http.Header{"X-Appengine-Remote-Addr": []string{"1.2.3.4"}}, "1.2.3.4:80"},
275 {http.Header{"X-Appengine-Remote-Addr": []string{"1.2.3.4:8080"}}, "1.2.3.4:8080"},
276 {
277 http.Header{"X-Appengine-Remote-Addr": []string{"2401:fa00:9:1:7646:a0ff:fe90:ca66"}},
278 "[2401:fa00:9:1:7646:a0ff:fe90:ca66]:80",
279 },
280 {
281 http.Header{"X-Appengine-Remote-Addr": []string{"[::1]:http"}},
282 "[::1]:http",
283 },
284 {http.Header{}, "127.0.0.1:80"},
285 }
286
287 for _, tc := range testCases {
288 r := &http.Request{
289 Method: "GET",
290 URL: &url.URL{Scheme: "http", Path: "/remote_addr"},
291 Header: tc.headers,
292 Body: ioutil.NopCloser(bytes.NewReader(nil)),
293 }
294 Middleware(http.DefaultServeMux).ServeHTTP(httptest.NewRecorder(), r)
295 if addr != tc.addr {
296 t.Errorf("Header %v, got %q, want %q", tc.headers, addr, tc.addr)
297 }
298 }
299 }
300
301 func TestPanickingHandler(t *testing.T) {
302 http.HandleFunc("/panic", func(http.ResponseWriter, *http.Request) {
303 panic("whoops!")
304 })
305 r := &http.Request{
306 Method: "GET",
307 URL: &url.URL{Scheme: "http", Path: "/panic"},
308 Body: ioutil.NopCloser(bytes.NewReader(nil)),
309 }
310 rec := httptest.NewRecorder()
311 Middleware(http.DefaultServeMux).ServeHTTP(rec, r)
312 if rec.Code != 500 {
313 t.Errorf("Panicking handler returned HTTP %d, want HTTP %d", rec.Code, 500)
314 }
315 }
316
317 var raceDetector = false
318
319 func TestAPICallAllocations(t *testing.T) {
320 if raceDetector {
321 t.Skip("not running under race detector")
322 }
323
324 // Run the test API server in a subprocess so we aren't counting its allocations.
325 cleanup := launchHelperProcess(t)
326 defer cleanup()
327 c := &context{
328 req: &http.Request{
329 Header: http.Header{
330 ticketHeader: []string{"s3cr3t"},
331 dapperHeader: []string{"trace-001"},
332 },
333 },
334 }
335
336 req := &basepb.StringProto{
337 Value: proto.String("Doctor Who"),
338 }
339 res := &basepb.StringProto{}
340 var apiErr error
341 avg := testing.AllocsPerRun(100, func() {
342 ctx, _ := netcontext.WithTimeout(toContext(c), 100*time.Millisecond)
343 if err := Call(ctx, "actordb", "LookupActor", req, res); err != nil && apiErr == nil {
344 apiErr = err // get the first error only
345 }
346 })
347 if apiErr != nil {
348 t.Errorf("API call failed: %v", apiErr)
349 }
350
351 // Lots of room for improvement...
352 const min, max float64 = 60, 86
353 if avg < min || max < avg {
354 t.Errorf("Allocations per API call = %g, want in [%g,%g]", avg, min, max)
355 }
356 }
357
358 func launchHelperProcess(t *testing.T) (cleanup func()) {
359 cmd := exec.Command(os.Args[0], "-test.run=TestHelperProcess")
360 cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
361 stdin, err := cmd.StdinPipe()
362 if err != nil {
363 t.Fatalf("StdinPipe: %v", err)
364 }
365 stdout, err := cmd.StdoutPipe()
366 if err != nil {
367 t.Fatalf("StdoutPipe: %v", err)
368 }
369 if err := cmd.Start(); err != nil {
370 t.Fatalf("Starting helper process: %v", err)
371 }
372
373 scan := bufio.NewScanner(stdout)
374 var u *url.URL
375 for scan.Scan() {
376 line := scan.Text()
377 if hp := strings.TrimPrefix(line, helperProcessMagic); hp != line {
378 var err error
379 u, err = url.Parse(hp)
380 if err != nil {
381 t.Fatalf("Failed to parse %q: %v", hp, err)
382 }
383 break
384 }
385 }
386 if err := scan.Err(); err != nil {
387 t.Fatalf("Scanning helper process stdout: %v", err)
388 }
389 if u == nil {
390 t.Fatal("Helper process never reported")
391 }
392
393 restoreAPIHost := restoreEnvVar("API_HOST")
394 restoreAPIPort := restoreEnvVar("API_HOST")
395 os.Setenv("API_HOST", u.Hostname())
396 os.Setenv("API_PORT", u.Port())
397 return func() {
398 restoreAPIHost()
399 restoreAPIPort()
400 stdin.Close()
401 if err := cmd.Wait(); err != nil {
402 t.Errorf("Helper process did not exit cleanly: %v", err)
403 }
404 }
405 }
406
407 const helperProcessMagic = "A lovely helper process is listening at "
408
409 // This isn't a real test. It's used as a helper process.
410 func TestHelperProcess(*testing.T) {
411 if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
412 return
413 }
414 defer os.Exit(0)
415
416 f := &fakeAPIHandler{}
417 srv := httptest.NewServer(f)
418 defer srv.Close()
419 fmt.Println(helperProcessMagic + srv.URL + apiPath)
420
421 // Wait for stdin to be closed.
422 io.Copy(ioutil.Discard, os.Stdin)
423 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "strings"
8 )
9
10 func parseFullAppID(appid string) (partition, domain, displayID string) {
11 if i := strings.Index(appid, "~"); i != -1 {
12 partition, appid = appid[:i], appid[i+1:]
13 }
14 if i := strings.Index(appid, ":"); i != -1 {
15 domain, appid = appid[:i], appid[i+1:]
16 }
17 return partition, domain, appid
18 }
19
20 // appID returns "appid" or "domain.com:appid".
21 func appID(fullAppID string) string {
22 _, dom, dis := parseFullAppID(fullAppID)
23 if dom != "" {
24 return dom + ":" + dis
25 }
26 return dis
27 }
0 // Copyright 2011 Google Inc. All Rights Reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "testing"
8 )
9
10 func TestAppIDParsing(t *testing.T) {
11 testCases := []struct {
12 in string
13 partition, domain, displayID string
14 }{
15 {"simple-app-id", "", "", "simple-app-id"},
16 {"domain.com:domain-app-id", "", "domain.com", "domain-app-id"},
17 {"part~partition-app-id", "part", "", "partition-app-id"},
18 {"part~domain.com:display", "part", "domain.com", "display"},
19 }
20
21 for _, tc := range testCases {
22 part, dom, dis := parseFullAppID(tc.in)
23 if part != tc.partition {
24 t.Errorf("partition of %q: got %q, want %q", tc.in, part, tc.partition)
25 }
26 if dom != tc.domain {
27 t.Errorf("domain of %q: got %q, want %q", tc.in, dom, tc.domain)
28 }
29 if dis != tc.displayID {
30 t.Errorf("displayID of %q: got %q, want %q", tc.in, dis, tc.displayID)
31 }
32 }
33 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/app_identity/app_identity_service.proto
2
3 package app_identity
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type AppIdentityServiceError_ErrorCode int32
21
22 const (
23 AppIdentityServiceError_SUCCESS AppIdentityServiceError_ErrorCode = 0
24 AppIdentityServiceError_UNKNOWN_SCOPE AppIdentityServiceError_ErrorCode = 9
25 AppIdentityServiceError_BLOB_TOO_LARGE AppIdentityServiceError_ErrorCode = 1000
26 AppIdentityServiceError_DEADLINE_EXCEEDED AppIdentityServiceError_ErrorCode = 1001
27 AppIdentityServiceError_NOT_A_VALID_APP AppIdentityServiceError_ErrorCode = 1002
28 AppIdentityServiceError_UNKNOWN_ERROR AppIdentityServiceError_ErrorCode = 1003
29 AppIdentityServiceError_NOT_ALLOWED AppIdentityServiceError_ErrorCode = 1005
30 AppIdentityServiceError_NOT_IMPLEMENTED AppIdentityServiceError_ErrorCode = 1006
31 )
32
33 var AppIdentityServiceError_ErrorCode_name = map[int32]string{
34 0: "SUCCESS",
35 9: "UNKNOWN_SCOPE",
36 1000: "BLOB_TOO_LARGE",
37 1001: "DEADLINE_EXCEEDED",
38 1002: "NOT_A_VALID_APP",
39 1003: "UNKNOWN_ERROR",
40 1005: "NOT_ALLOWED",
41 1006: "NOT_IMPLEMENTED",
42 }
43 var AppIdentityServiceError_ErrorCode_value = map[string]int32{
44 "SUCCESS": 0,
45 "UNKNOWN_SCOPE": 9,
46 "BLOB_TOO_LARGE": 1000,
47 "DEADLINE_EXCEEDED": 1001,
48 "NOT_A_VALID_APP": 1002,
49 "UNKNOWN_ERROR": 1003,
50 "NOT_ALLOWED": 1005,
51 "NOT_IMPLEMENTED": 1006,
52 }
53
54 func (x AppIdentityServiceError_ErrorCode) Enum() *AppIdentityServiceError_ErrorCode {
55 p := new(AppIdentityServiceError_ErrorCode)
56 *p = x
57 return p
58 }
59 func (x AppIdentityServiceError_ErrorCode) String() string {
60 return proto.EnumName(AppIdentityServiceError_ErrorCode_name, int32(x))
61 }
62 func (x *AppIdentityServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
63 value, err := proto.UnmarshalJSONEnum(AppIdentityServiceError_ErrorCode_value, data, "AppIdentityServiceError_ErrorCode")
64 if err != nil {
65 return err
66 }
67 *x = AppIdentityServiceError_ErrorCode(value)
68 return nil
69 }
70 func (AppIdentityServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
71 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{0, 0}
72 }
73
74 type AppIdentityServiceError struct {
75 XXX_NoUnkeyedLiteral struct{} `json:"-"`
76 XXX_unrecognized []byte `json:"-"`
77 XXX_sizecache int32 `json:"-"`
78 }
79
80 func (m *AppIdentityServiceError) Reset() { *m = AppIdentityServiceError{} }
81 func (m *AppIdentityServiceError) String() string { return proto.CompactTextString(m) }
82 func (*AppIdentityServiceError) ProtoMessage() {}
83 func (*AppIdentityServiceError) Descriptor() ([]byte, []int) {
84 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{0}
85 }
86 func (m *AppIdentityServiceError) XXX_Unmarshal(b []byte) error {
87 return xxx_messageInfo_AppIdentityServiceError.Unmarshal(m, b)
88 }
89 func (m *AppIdentityServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
90 return xxx_messageInfo_AppIdentityServiceError.Marshal(b, m, deterministic)
91 }
92 func (dst *AppIdentityServiceError) XXX_Merge(src proto.Message) {
93 xxx_messageInfo_AppIdentityServiceError.Merge(dst, src)
94 }
95 func (m *AppIdentityServiceError) XXX_Size() int {
96 return xxx_messageInfo_AppIdentityServiceError.Size(m)
97 }
98 func (m *AppIdentityServiceError) XXX_DiscardUnknown() {
99 xxx_messageInfo_AppIdentityServiceError.DiscardUnknown(m)
100 }
101
102 var xxx_messageInfo_AppIdentityServiceError proto.InternalMessageInfo
103
104 type SignForAppRequest struct {
105 BytesToSign []byte `protobuf:"bytes,1,opt,name=bytes_to_sign,json=bytesToSign" json:"bytes_to_sign,omitempty"`
106 XXX_NoUnkeyedLiteral struct{} `json:"-"`
107 XXX_unrecognized []byte `json:"-"`
108 XXX_sizecache int32 `json:"-"`
109 }
110
111 func (m *SignForAppRequest) Reset() { *m = SignForAppRequest{} }
112 func (m *SignForAppRequest) String() string { return proto.CompactTextString(m) }
113 func (*SignForAppRequest) ProtoMessage() {}
114 func (*SignForAppRequest) Descriptor() ([]byte, []int) {
115 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{1}
116 }
117 func (m *SignForAppRequest) XXX_Unmarshal(b []byte) error {
118 return xxx_messageInfo_SignForAppRequest.Unmarshal(m, b)
119 }
120 func (m *SignForAppRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
121 return xxx_messageInfo_SignForAppRequest.Marshal(b, m, deterministic)
122 }
123 func (dst *SignForAppRequest) XXX_Merge(src proto.Message) {
124 xxx_messageInfo_SignForAppRequest.Merge(dst, src)
125 }
126 func (m *SignForAppRequest) XXX_Size() int {
127 return xxx_messageInfo_SignForAppRequest.Size(m)
128 }
129 func (m *SignForAppRequest) XXX_DiscardUnknown() {
130 xxx_messageInfo_SignForAppRequest.DiscardUnknown(m)
131 }
132
133 var xxx_messageInfo_SignForAppRequest proto.InternalMessageInfo
134
135 func (m *SignForAppRequest) GetBytesToSign() []byte {
136 if m != nil {
137 return m.BytesToSign
138 }
139 return nil
140 }
141
142 type SignForAppResponse struct {
143 KeyName *string `protobuf:"bytes,1,opt,name=key_name,json=keyName" json:"key_name,omitempty"`
144 SignatureBytes []byte `protobuf:"bytes,2,opt,name=signature_bytes,json=signatureBytes" json:"signature_bytes,omitempty"`
145 XXX_NoUnkeyedLiteral struct{} `json:"-"`
146 XXX_unrecognized []byte `json:"-"`
147 XXX_sizecache int32 `json:"-"`
148 }
149
150 func (m *SignForAppResponse) Reset() { *m = SignForAppResponse{} }
151 func (m *SignForAppResponse) String() string { return proto.CompactTextString(m) }
152 func (*SignForAppResponse) ProtoMessage() {}
153 func (*SignForAppResponse) Descriptor() ([]byte, []int) {
154 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{2}
155 }
156 func (m *SignForAppResponse) XXX_Unmarshal(b []byte) error {
157 return xxx_messageInfo_SignForAppResponse.Unmarshal(m, b)
158 }
159 func (m *SignForAppResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
160 return xxx_messageInfo_SignForAppResponse.Marshal(b, m, deterministic)
161 }
162 func (dst *SignForAppResponse) XXX_Merge(src proto.Message) {
163 xxx_messageInfo_SignForAppResponse.Merge(dst, src)
164 }
165 func (m *SignForAppResponse) XXX_Size() int {
166 return xxx_messageInfo_SignForAppResponse.Size(m)
167 }
168 func (m *SignForAppResponse) XXX_DiscardUnknown() {
169 xxx_messageInfo_SignForAppResponse.DiscardUnknown(m)
170 }
171
172 var xxx_messageInfo_SignForAppResponse proto.InternalMessageInfo
173
174 func (m *SignForAppResponse) GetKeyName() string {
175 if m != nil && m.KeyName != nil {
176 return *m.KeyName
177 }
178 return ""
179 }
180
181 func (m *SignForAppResponse) GetSignatureBytes() []byte {
182 if m != nil {
183 return m.SignatureBytes
184 }
185 return nil
186 }
187
188 type GetPublicCertificateForAppRequest struct {
189 XXX_NoUnkeyedLiteral struct{} `json:"-"`
190 XXX_unrecognized []byte `json:"-"`
191 XXX_sizecache int32 `json:"-"`
192 }
193
194 func (m *GetPublicCertificateForAppRequest) Reset() { *m = GetPublicCertificateForAppRequest{} }
195 func (m *GetPublicCertificateForAppRequest) String() string { return proto.CompactTextString(m) }
196 func (*GetPublicCertificateForAppRequest) ProtoMessage() {}
197 func (*GetPublicCertificateForAppRequest) Descriptor() ([]byte, []int) {
198 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{3}
199 }
200 func (m *GetPublicCertificateForAppRequest) XXX_Unmarshal(b []byte) error {
201 return xxx_messageInfo_GetPublicCertificateForAppRequest.Unmarshal(m, b)
202 }
203 func (m *GetPublicCertificateForAppRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
204 return xxx_messageInfo_GetPublicCertificateForAppRequest.Marshal(b, m, deterministic)
205 }
206 func (dst *GetPublicCertificateForAppRequest) XXX_Merge(src proto.Message) {
207 xxx_messageInfo_GetPublicCertificateForAppRequest.Merge(dst, src)
208 }
209 func (m *GetPublicCertificateForAppRequest) XXX_Size() int {
210 return xxx_messageInfo_GetPublicCertificateForAppRequest.Size(m)
211 }
212 func (m *GetPublicCertificateForAppRequest) XXX_DiscardUnknown() {
213 xxx_messageInfo_GetPublicCertificateForAppRequest.DiscardUnknown(m)
214 }
215
216 var xxx_messageInfo_GetPublicCertificateForAppRequest proto.InternalMessageInfo
217
218 type PublicCertificate struct {
219 KeyName *string `protobuf:"bytes,1,opt,name=key_name,json=keyName" json:"key_name,omitempty"`
220 X509CertificatePem *string `protobuf:"bytes,2,opt,name=x509_certificate_pem,json=x509CertificatePem" json:"x509_certificate_pem,omitempty"`
221 XXX_NoUnkeyedLiteral struct{} `json:"-"`
222 XXX_unrecognized []byte `json:"-"`
223 XXX_sizecache int32 `json:"-"`
224 }
225
226 func (m *PublicCertificate) Reset() { *m = PublicCertificate{} }
227 func (m *PublicCertificate) String() string { return proto.CompactTextString(m) }
228 func (*PublicCertificate) ProtoMessage() {}
229 func (*PublicCertificate) Descriptor() ([]byte, []int) {
230 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{4}
231 }
232 func (m *PublicCertificate) XXX_Unmarshal(b []byte) error {
233 return xxx_messageInfo_PublicCertificate.Unmarshal(m, b)
234 }
235 func (m *PublicCertificate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
236 return xxx_messageInfo_PublicCertificate.Marshal(b, m, deterministic)
237 }
238 func (dst *PublicCertificate) XXX_Merge(src proto.Message) {
239 xxx_messageInfo_PublicCertificate.Merge(dst, src)
240 }
241 func (m *PublicCertificate) XXX_Size() int {
242 return xxx_messageInfo_PublicCertificate.Size(m)
243 }
244 func (m *PublicCertificate) XXX_DiscardUnknown() {
245 xxx_messageInfo_PublicCertificate.DiscardUnknown(m)
246 }
247
248 var xxx_messageInfo_PublicCertificate proto.InternalMessageInfo
249
250 func (m *PublicCertificate) GetKeyName() string {
251 if m != nil && m.KeyName != nil {
252 return *m.KeyName
253 }
254 return ""
255 }
256
257 func (m *PublicCertificate) GetX509CertificatePem() string {
258 if m != nil && m.X509CertificatePem != nil {
259 return *m.X509CertificatePem
260 }
261 return ""
262 }
263
264 type GetPublicCertificateForAppResponse struct {
265 PublicCertificateList []*PublicCertificate `protobuf:"bytes,1,rep,name=public_certificate_list,json=publicCertificateList" json:"public_certificate_list,omitempty"`
266 MaxClientCacheTimeInSecond *int64 `protobuf:"varint,2,opt,name=max_client_cache_time_in_second,json=maxClientCacheTimeInSecond" json:"max_client_cache_time_in_second,omitempty"`
267 XXX_NoUnkeyedLiteral struct{} `json:"-"`
268 XXX_unrecognized []byte `json:"-"`
269 XXX_sizecache int32 `json:"-"`
270 }
271
272 func (m *GetPublicCertificateForAppResponse) Reset() { *m = GetPublicCertificateForAppResponse{} }
273 func (m *GetPublicCertificateForAppResponse) String() string { return proto.CompactTextString(m) }
274 func (*GetPublicCertificateForAppResponse) ProtoMessage() {}
275 func (*GetPublicCertificateForAppResponse) Descriptor() ([]byte, []int) {
276 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{5}
277 }
278 func (m *GetPublicCertificateForAppResponse) XXX_Unmarshal(b []byte) error {
279 return xxx_messageInfo_GetPublicCertificateForAppResponse.Unmarshal(m, b)
280 }
281 func (m *GetPublicCertificateForAppResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
282 return xxx_messageInfo_GetPublicCertificateForAppResponse.Marshal(b, m, deterministic)
283 }
284 func (dst *GetPublicCertificateForAppResponse) XXX_Merge(src proto.Message) {
285 xxx_messageInfo_GetPublicCertificateForAppResponse.Merge(dst, src)
286 }
287 func (m *GetPublicCertificateForAppResponse) XXX_Size() int {
288 return xxx_messageInfo_GetPublicCertificateForAppResponse.Size(m)
289 }
290 func (m *GetPublicCertificateForAppResponse) XXX_DiscardUnknown() {
291 xxx_messageInfo_GetPublicCertificateForAppResponse.DiscardUnknown(m)
292 }
293
294 var xxx_messageInfo_GetPublicCertificateForAppResponse proto.InternalMessageInfo
295
296 func (m *GetPublicCertificateForAppResponse) GetPublicCertificateList() []*PublicCertificate {
297 if m != nil {
298 return m.PublicCertificateList
299 }
300 return nil
301 }
302
303 func (m *GetPublicCertificateForAppResponse) GetMaxClientCacheTimeInSecond() int64 {
304 if m != nil && m.MaxClientCacheTimeInSecond != nil {
305 return *m.MaxClientCacheTimeInSecond
306 }
307 return 0
308 }
309
310 type GetServiceAccountNameRequest struct {
311 XXX_NoUnkeyedLiteral struct{} `json:"-"`
312 XXX_unrecognized []byte `json:"-"`
313 XXX_sizecache int32 `json:"-"`
314 }
315
316 func (m *GetServiceAccountNameRequest) Reset() { *m = GetServiceAccountNameRequest{} }
317 func (m *GetServiceAccountNameRequest) String() string { return proto.CompactTextString(m) }
318 func (*GetServiceAccountNameRequest) ProtoMessage() {}
319 func (*GetServiceAccountNameRequest) Descriptor() ([]byte, []int) {
320 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{6}
321 }
322 func (m *GetServiceAccountNameRequest) XXX_Unmarshal(b []byte) error {
323 return xxx_messageInfo_GetServiceAccountNameRequest.Unmarshal(m, b)
324 }
325 func (m *GetServiceAccountNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
326 return xxx_messageInfo_GetServiceAccountNameRequest.Marshal(b, m, deterministic)
327 }
328 func (dst *GetServiceAccountNameRequest) XXX_Merge(src proto.Message) {
329 xxx_messageInfo_GetServiceAccountNameRequest.Merge(dst, src)
330 }
331 func (m *GetServiceAccountNameRequest) XXX_Size() int {
332 return xxx_messageInfo_GetServiceAccountNameRequest.Size(m)
333 }
334 func (m *GetServiceAccountNameRequest) XXX_DiscardUnknown() {
335 xxx_messageInfo_GetServiceAccountNameRequest.DiscardUnknown(m)
336 }
337
338 var xxx_messageInfo_GetServiceAccountNameRequest proto.InternalMessageInfo
339
340 type GetServiceAccountNameResponse struct {
341 ServiceAccountName *string `protobuf:"bytes,1,opt,name=service_account_name,json=serviceAccountName" json:"service_account_name,omitempty"`
342 XXX_NoUnkeyedLiteral struct{} `json:"-"`
343 XXX_unrecognized []byte `json:"-"`
344 XXX_sizecache int32 `json:"-"`
345 }
346
347 func (m *GetServiceAccountNameResponse) Reset() { *m = GetServiceAccountNameResponse{} }
348 func (m *GetServiceAccountNameResponse) String() string { return proto.CompactTextString(m) }
349 func (*GetServiceAccountNameResponse) ProtoMessage() {}
350 func (*GetServiceAccountNameResponse) Descriptor() ([]byte, []int) {
351 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{7}
352 }
353 func (m *GetServiceAccountNameResponse) XXX_Unmarshal(b []byte) error {
354 return xxx_messageInfo_GetServiceAccountNameResponse.Unmarshal(m, b)
355 }
356 func (m *GetServiceAccountNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
357 return xxx_messageInfo_GetServiceAccountNameResponse.Marshal(b, m, deterministic)
358 }
359 func (dst *GetServiceAccountNameResponse) XXX_Merge(src proto.Message) {
360 xxx_messageInfo_GetServiceAccountNameResponse.Merge(dst, src)
361 }
362 func (m *GetServiceAccountNameResponse) XXX_Size() int {
363 return xxx_messageInfo_GetServiceAccountNameResponse.Size(m)
364 }
365 func (m *GetServiceAccountNameResponse) XXX_DiscardUnknown() {
366 xxx_messageInfo_GetServiceAccountNameResponse.DiscardUnknown(m)
367 }
368
369 var xxx_messageInfo_GetServiceAccountNameResponse proto.InternalMessageInfo
370
371 func (m *GetServiceAccountNameResponse) GetServiceAccountName() string {
372 if m != nil && m.ServiceAccountName != nil {
373 return *m.ServiceAccountName
374 }
375 return ""
376 }
377
378 type GetAccessTokenRequest struct {
379 Scope []string `protobuf:"bytes,1,rep,name=scope" json:"scope,omitempty"`
380 ServiceAccountId *int64 `protobuf:"varint,2,opt,name=service_account_id,json=serviceAccountId" json:"service_account_id,omitempty"`
381 ServiceAccountName *string `protobuf:"bytes,3,opt,name=service_account_name,json=serviceAccountName" json:"service_account_name,omitempty"`
382 XXX_NoUnkeyedLiteral struct{} `json:"-"`
383 XXX_unrecognized []byte `json:"-"`
384 XXX_sizecache int32 `json:"-"`
385 }
386
387 func (m *GetAccessTokenRequest) Reset() { *m = GetAccessTokenRequest{} }
388 func (m *GetAccessTokenRequest) String() string { return proto.CompactTextString(m) }
389 func (*GetAccessTokenRequest) ProtoMessage() {}
390 func (*GetAccessTokenRequest) Descriptor() ([]byte, []int) {
391 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{8}
392 }
393 func (m *GetAccessTokenRequest) XXX_Unmarshal(b []byte) error {
394 return xxx_messageInfo_GetAccessTokenRequest.Unmarshal(m, b)
395 }
396 func (m *GetAccessTokenRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
397 return xxx_messageInfo_GetAccessTokenRequest.Marshal(b, m, deterministic)
398 }
399 func (dst *GetAccessTokenRequest) XXX_Merge(src proto.Message) {
400 xxx_messageInfo_GetAccessTokenRequest.Merge(dst, src)
401 }
402 func (m *GetAccessTokenRequest) XXX_Size() int {
403 return xxx_messageInfo_GetAccessTokenRequest.Size(m)
404 }
405 func (m *GetAccessTokenRequest) XXX_DiscardUnknown() {
406 xxx_messageInfo_GetAccessTokenRequest.DiscardUnknown(m)
407 }
408
409 var xxx_messageInfo_GetAccessTokenRequest proto.InternalMessageInfo
410
411 func (m *GetAccessTokenRequest) GetScope() []string {
412 if m != nil {
413 return m.Scope
414 }
415 return nil
416 }
417
418 func (m *GetAccessTokenRequest) GetServiceAccountId() int64 {
419 if m != nil && m.ServiceAccountId != nil {
420 return *m.ServiceAccountId
421 }
422 return 0
423 }
424
425 func (m *GetAccessTokenRequest) GetServiceAccountName() string {
426 if m != nil && m.ServiceAccountName != nil {
427 return *m.ServiceAccountName
428 }
429 return ""
430 }
431
432 type GetAccessTokenResponse struct {
433 AccessToken *string `protobuf:"bytes,1,opt,name=access_token,json=accessToken" json:"access_token,omitempty"`
434 ExpirationTime *int64 `protobuf:"varint,2,opt,name=expiration_time,json=expirationTime" json:"expiration_time,omitempty"`
435 XXX_NoUnkeyedLiteral struct{} `json:"-"`
436 XXX_unrecognized []byte `json:"-"`
437 XXX_sizecache int32 `json:"-"`
438 }
439
440 func (m *GetAccessTokenResponse) Reset() { *m = GetAccessTokenResponse{} }
441 func (m *GetAccessTokenResponse) String() string { return proto.CompactTextString(m) }
442 func (*GetAccessTokenResponse) ProtoMessage() {}
443 func (*GetAccessTokenResponse) Descriptor() ([]byte, []int) {
444 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{9}
445 }
446 func (m *GetAccessTokenResponse) XXX_Unmarshal(b []byte) error {
447 return xxx_messageInfo_GetAccessTokenResponse.Unmarshal(m, b)
448 }
449 func (m *GetAccessTokenResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
450 return xxx_messageInfo_GetAccessTokenResponse.Marshal(b, m, deterministic)
451 }
452 func (dst *GetAccessTokenResponse) XXX_Merge(src proto.Message) {
453 xxx_messageInfo_GetAccessTokenResponse.Merge(dst, src)
454 }
455 func (m *GetAccessTokenResponse) XXX_Size() int {
456 return xxx_messageInfo_GetAccessTokenResponse.Size(m)
457 }
458 func (m *GetAccessTokenResponse) XXX_DiscardUnknown() {
459 xxx_messageInfo_GetAccessTokenResponse.DiscardUnknown(m)
460 }
461
462 var xxx_messageInfo_GetAccessTokenResponse proto.InternalMessageInfo
463
464 func (m *GetAccessTokenResponse) GetAccessToken() string {
465 if m != nil && m.AccessToken != nil {
466 return *m.AccessToken
467 }
468 return ""
469 }
470
471 func (m *GetAccessTokenResponse) GetExpirationTime() int64 {
472 if m != nil && m.ExpirationTime != nil {
473 return *m.ExpirationTime
474 }
475 return 0
476 }
477
478 type GetDefaultGcsBucketNameRequest struct {
479 XXX_NoUnkeyedLiteral struct{} `json:"-"`
480 XXX_unrecognized []byte `json:"-"`
481 XXX_sizecache int32 `json:"-"`
482 }
483
484 func (m *GetDefaultGcsBucketNameRequest) Reset() { *m = GetDefaultGcsBucketNameRequest{} }
485 func (m *GetDefaultGcsBucketNameRequest) String() string { return proto.CompactTextString(m) }
486 func (*GetDefaultGcsBucketNameRequest) ProtoMessage() {}
487 func (*GetDefaultGcsBucketNameRequest) Descriptor() ([]byte, []int) {
488 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{10}
489 }
490 func (m *GetDefaultGcsBucketNameRequest) XXX_Unmarshal(b []byte) error {
491 return xxx_messageInfo_GetDefaultGcsBucketNameRequest.Unmarshal(m, b)
492 }
493 func (m *GetDefaultGcsBucketNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
494 return xxx_messageInfo_GetDefaultGcsBucketNameRequest.Marshal(b, m, deterministic)
495 }
496 func (dst *GetDefaultGcsBucketNameRequest) XXX_Merge(src proto.Message) {
497 xxx_messageInfo_GetDefaultGcsBucketNameRequest.Merge(dst, src)
498 }
499 func (m *GetDefaultGcsBucketNameRequest) XXX_Size() int {
500 return xxx_messageInfo_GetDefaultGcsBucketNameRequest.Size(m)
501 }
502 func (m *GetDefaultGcsBucketNameRequest) XXX_DiscardUnknown() {
503 xxx_messageInfo_GetDefaultGcsBucketNameRequest.DiscardUnknown(m)
504 }
505
506 var xxx_messageInfo_GetDefaultGcsBucketNameRequest proto.InternalMessageInfo
507
508 type GetDefaultGcsBucketNameResponse struct {
509 DefaultGcsBucketName *string `protobuf:"bytes,1,opt,name=default_gcs_bucket_name,json=defaultGcsBucketName" json:"default_gcs_bucket_name,omitempty"`
510 XXX_NoUnkeyedLiteral struct{} `json:"-"`
511 XXX_unrecognized []byte `json:"-"`
512 XXX_sizecache int32 `json:"-"`
513 }
514
515 func (m *GetDefaultGcsBucketNameResponse) Reset() { *m = GetDefaultGcsBucketNameResponse{} }
516 func (m *GetDefaultGcsBucketNameResponse) String() string { return proto.CompactTextString(m) }
517 func (*GetDefaultGcsBucketNameResponse) ProtoMessage() {}
518 func (*GetDefaultGcsBucketNameResponse) Descriptor() ([]byte, []int) {
519 return fileDescriptor_app_identity_service_08a6e3f74b04cfa4, []int{11}
520 }
521 func (m *GetDefaultGcsBucketNameResponse) XXX_Unmarshal(b []byte) error {
522 return xxx_messageInfo_GetDefaultGcsBucketNameResponse.Unmarshal(m, b)
523 }
524 func (m *GetDefaultGcsBucketNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
525 return xxx_messageInfo_GetDefaultGcsBucketNameResponse.Marshal(b, m, deterministic)
526 }
527 func (dst *GetDefaultGcsBucketNameResponse) XXX_Merge(src proto.Message) {
528 xxx_messageInfo_GetDefaultGcsBucketNameResponse.Merge(dst, src)
529 }
530 func (m *GetDefaultGcsBucketNameResponse) XXX_Size() int {
531 return xxx_messageInfo_GetDefaultGcsBucketNameResponse.Size(m)
532 }
533 func (m *GetDefaultGcsBucketNameResponse) XXX_DiscardUnknown() {
534 xxx_messageInfo_GetDefaultGcsBucketNameResponse.DiscardUnknown(m)
535 }
536
537 var xxx_messageInfo_GetDefaultGcsBucketNameResponse proto.InternalMessageInfo
538
539 func (m *GetDefaultGcsBucketNameResponse) GetDefaultGcsBucketName() string {
540 if m != nil && m.DefaultGcsBucketName != nil {
541 return *m.DefaultGcsBucketName
542 }
543 return ""
544 }
545
546 func init() {
547 proto.RegisterType((*AppIdentityServiceError)(nil), "appengine.AppIdentityServiceError")
548 proto.RegisterType((*SignForAppRequest)(nil), "appengine.SignForAppRequest")
549 proto.RegisterType((*SignForAppResponse)(nil), "appengine.SignForAppResponse")
550 proto.RegisterType((*GetPublicCertificateForAppRequest)(nil), "appengine.GetPublicCertificateForAppRequest")
551 proto.RegisterType((*PublicCertificate)(nil), "appengine.PublicCertificate")
552 proto.RegisterType((*GetPublicCertificateForAppResponse)(nil), "appengine.GetPublicCertificateForAppResponse")
553 proto.RegisterType((*GetServiceAccountNameRequest)(nil), "appengine.GetServiceAccountNameRequest")
554 proto.RegisterType((*GetServiceAccountNameResponse)(nil), "appengine.GetServiceAccountNameResponse")
555 proto.RegisterType((*GetAccessTokenRequest)(nil), "appengine.GetAccessTokenRequest")
556 proto.RegisterType((*GetAccessTokenResponse)(nil), "appengine.GetAccessTokenResponse")
557 proto.RegisterType((*GetDefaultGcsBucketNameRequest)(nil), "appengine.GetDefaultGcsBucketNameRequest")
558 proto.RegisterType((*GetDefaultGcsBucketNameResponse)(nil), "appengine.GetDefaultGcsBucketNameResponse")
559 }
560
561 func init() {
562 proto.RegisterFile("google.golang.org/appengine/v2/internal/app_identity/app_identity_service.proto", fileDescriptor_app_identity_service_08a6e3f74b04cfa4)
563 }
564
565 var fileDescriptor_app_identity_service_08a6e3f74b04cfa4 = []byte{
566 // 676 bytes of a gzipped FileDescriptorProto
567 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xdb, 0x6e, 0xda, 0x58,
568 0x14, 0x1d, 0x26, 0x1a, 0x31, 0x6c, 0x12, 0x62, 0xce, 0x90, 0xcb, 0x8c, 0x32, 0xb9, 0x78, 0x1e,
569 0x26, 0x0f, 0x15, 0x89, 0x2a, 0x45, 0x55, 0x1f, 0x8d, 0xed, 0x22, 0x54, 0x07, 0x53, 0x43, 0x9a,
570 0xa8, 0x2f, 0xa7, 0xce, 0x61, 0xc7, 0x3d, 0x02, 0x9f, 0xe3, 0xda, 0x87, 0x0a, 0x3e, 0xa2, 0x3f,
571 0xd2, 0x9f, 0xe8, 0x5b, 0xbf, 0xa5, 0x17, 0xb5, 0xdf, 0x50, 0xd9, 0x38, 0x5c, 0x92, 0x92, 0x37,
572 0xbc, 0xf6, 0x5a, 0xcb, 0x6b, 0x2f, 0x6d, 0x0c, 0x4e, 0x20, 0x65, 0x30, 0xc4, 0x7a, 0x20, 0x87,
573 0xbe, 0x08, 0xea, 0x32, 0x0e, 0x4e, 0xfc, 0x28, 0x42, 0x11, 0x70, 0x81, 0x27, 0x5c, 0x28, 0x8c,
574 0x85, 0x3f, 0x4c, 0x21, 0xca, 0xfb, 0x28, 0x14, 0x57, 0x93, 0xa5, 0x07, 0x9a, 0x60, 0xfc, 0x8e,
575 0x33, 0xac, 0x47, 0xb1, 0x54, 0x92, 0x94, 0x66, 0x5a, 0xfd, 0x53, 0x01, 0x76, 0x8c, 0x28, 0x6a,
576 0xe5, 0xc4, 0xee, 0x94, 0x67, 0xc7, 0xb1, 0x8c, 0xf5, 0x0f, 0x05, 0x28, 0x65, 0xbf, 0x4c, 0xd9,
577 0x47, 0x52, 0x86, 0x62, 0xf7, 0xc2, 0x34, 0xed, 0x6e, 0x57, 0xfb, 0x8d, 0x54, 0x61, 0xe3, 0xa2,
578 0xfd, 0xbc, 0xed, 0x5e, 0xb6, 0x69, 0xd7, 0x74, 0x3b, 0xb6, 0x56, 0x22, 0x7f, 0x41, 0xa5, 0xe1,
579 0xb8, 0x0d, 0xda, 0x73, 0x5d, 0xea, 0x18, 0x5e, 0xd3, 0xd6, 0x3e, 0x17, 0xc9, 0x36, 0x54, 0x2d,
580 0xdb, 0xb0, 0x9c, 0x56, 0xdb, 0xa6, 0xf6, 0x95, 0x69, 0xdb, 0x96, 0x6d, 0x69, 0x5f, 0x8a, 0xa4,
581 0x06, 0x9b, 0x6d, 0xb7, 0x47, 0x0d, 0xfa, 0xd2, 0x70, 0x5a, 0x16, 0x35, 0x3a, 0x1d, 0xed, 0x6b,
582 0x91, 0x90, 0xb9, 0xab, 0xed, 0x79, 0xae, 0xa7, 0x7d, 0x2b, 0x12, 0x0d, 0xca, 0x19, 0xd3, 0x71,
583 0xdc, 0x4b, 0xdb, 0xd2, 0xbe, 0xcf, 0xb4, 0xad, 0xf3, 0x8e, 0x63, 0x9f, 0xdb, 0xed, 0x9e, 0x6d,
584 0x69, 0x3f, 0x8a, 0xfa, 0x13, 0xa8, 0x76, 0x79, 0x20, 0x9e, 0xc9, 0xd8, 0x88, 0x22, 0x0f, 0xdf,
585 0x8e, 0x30, 0x51, 0x44, 0x87, 0x8d, 0xeb, 0x89, 0xc2, 0x84, 0x2a, 0x49, 0x13, 0x1e, 0x88, 0xdd,
586 0xc2, 0x61, 0xe1, 0x78, 0xdd, 0x2b, 0x67, 0x60, 0x4f, 0xa6, 0x02, 0xfd, 0x0a, 0xc8, 0xa2, 0x30,
587 0x89, 0xa4, 0x48, 0x90, 0xfc, 0x0d, 0x7f, 0x0e, 0x70, 0x42, 0x85, 0x1f, 0x62, 0x26, 0x2a, 0x79,
588 0xc5, 0x01, 0x4e, 0xda, 0x7e, 0x88, 0xe4, 0x7f, 0xd8, 0x4c, 0xbd, 0x7c, 0x35, 0x8a, 0x91, 0x66,
589 0x4e, 0xbb, 0xbf, 0x67, 0xb6, 0x95, 0x19, 0xdc, 0x48, 0x51, 0xfd, 0x3f, 0x38, 0x6a, 0xa2, 0xea,
590 0x8c, 0xae, 0x87, 0x9c, 0x99, 0x18, 0x2b, 0x7e, 0xc3, 0x99, 0xaf, 0x70, 0x29, 0xa2, 0xfe, 0x1a,
591 0xaa, 0xf7, 0x18, 0x0f, 0xbd, 0xfd, 0x14, 0x6a, 0xe3, 0xb3, 0xd3, 0xa7, 0x94, 0xcd, 0xe9, 0x34,
592 0xc2, 0x30, 0x8b, 0x50, 0xf2, 0x48, 0x3a, 0x5b, 0x70, 0xea, 0x60, 0xa8, 0x7f, 0x2c, 0x80, 0xfe,
593 0x50, 0x8e, 0x7c, 0xe3, 0x1e, 0xec, 0x44, 0x19, 0x65, 0xc9, 0x7a, 0xc8, 0x13, 0xb5, 0x5b, 0x38,
594 0x5c, 0x3b, 0x2e, 0x3f, 0xde, 0xab, 0xcf, 0xce, 0xa6, 0x7e, 0xcf, 0xcc, 0xdb, 0x8a, 0xee, 0x42,
595 0x0e, 0x4f, 0x14, 0x31, 0xe1, 0x20, 0xf4, 0xc7, 0x94, 0x0d, 0x39, 0x0a, 0x45, 0x99, 0xcf, 0xde,
596 0x20, 0x55, 0x3c, 0x44, 0xca, 0x05, 0x4d, 0x90, 0x49, 0xd1, 0xcf, 0x92, 0xaf, 0x79, 0xff, 0x84,
597 0xfe, 0xd8, 0xcc, 0x58, 0x66, 0x4a, 0xea, 0xf1, 0x10, 0x5b, 0xa2, 0x9b, 0x31, 0xf4, 0x7d, 0xd8,
598 0x6b, 0xa2, 0xca, 0x6f, 0xd3, 0x60, 0x4c, 0x8e, 0x84, 0x4a, 0xcb, 0xb8, 0xed, 0xf0, 0x05, 0xfc,
599 0xbb, 0x62, 0x9e, 0xef, 0x76, 0x0a, 0xb5, 0xfc, 0x1f, 0x40, 0xfd, 0xe9, 0x78, 0xb1, 0x5b, 0x92,
600 0xdc, 0x53, 0xea, 0xef, 0x0b, 0xb0, 0xd5, 0x44, 0x65, 0x30, 0x86, 0x49, 0xd2, 0x93, 0x03, 0x14,
601 0xb7, 0x37, 0x55, 0x83, 0x3f, 0x12, 0x26, 0x23, 0xcc, 0x5a, 0x29, 0x79, 0xd3, 0x07, 0xf2, 0x08,
602 0xc8, 0xdd, 0x37, 0xf0, 0xdb, 0xd5, 0xb4, 0x65, 0xff, 0x56, 0x7f, 0x65, 0x9e, 0xb5, 0x95, 0x79,
603 0xfa, 0xb0, 0x7d, 0x37, 0x4e, 0xbe, 0xdb, 0x11, 0xac, 0xfb, 0x19, 0x4c, 0x55, 0x8a, 0xe7, 0x3b,
604 0x95, 0xfd, 0x39, 0x35, 0xbd, 0x58, 0x1c, 0x47, 0x3c, 0xf6, 0x15, 0x97, 0x22, 0xab, 0x3f, 0x4f,
605 0x56, 0x99, 0xc3, 0x69, 0xe1, 0xfa, 0x21, 0xec, 0x37, 0x51, 0x59, 0x78, 0xe3, 0x8f, 0x86, 0xaa,
606 0xc9, 0x92, 0xc6, 0x88, 0x0d, 0x70, 0xa9, 0xea, 0x2b, 0x38, 0x58, 0xc9, 0xc8, 0x03, 0x9d, 0xc1,
607 0x4e, 0x7f, 0x3a, 0xa7, 0x01, 0x4b, 0xe8, 0x75, 0xc6, 0x58, 0xec, 0xbb, 0xd6, 0xff, 0x85, 0xbc,
608 0x51, 0x79, 0xb5, 0xbe, 0xf8, 0xc9, 0xfa, 0x19, 0x00, 0x00, 0xff, 0xff, 0x37, 0x4c, 0x56, 0x38,
609 0xf3, 0x04, 0x00, 0x00,
610 }
0 syntax = "proto2";
1 option go_package = "app_identity";
2
3 package appengine;
4
5 message AppIdentityServiceError {
6 enum ErrorCode {
7 SUCCESS = 0;
8 UNKNOWN_SCOPE = 9;
9 BLOB_TOO_LARGE = 1000;
10 DEADLINE_EXCEEDED = 1001;
11 NOT_A_VALID_APP = 1002;
12 UNKNOWN_ERROR = 1003;
13 NOT_ALLOWED = 1005;
14 NOT_IMPLEMENTED = 1006;
15 }
16 }
17
18 message SignForAppRequest {
19 optional bytes bytes_to_sign = 1;
20 }
21
22 message SignForAppResponse {
23 optional string key_name = 1;
24 optional bytes signature_bytes = 2;
25 }
26
27 message GetPublicCertificateForAppRequest {
28 }
29
30 message PublicCertificate {
31 optional string key_name = 1;
32 optional string x509_certificate_pem = 2;
33 }
34
35 message GetPublicCertificateForAppResponse {
36 repeated PublicCertificate public_certificate_list = 1;
37 optional int64 max_client_cache_time_in_second = 2;
38 }
39
40 message GetServiceAccountNameRequest {
41 }
42
43 message GetServiceAccountNameResponse {
44 optional string service_account_name = 1;
45 }
46
47 message GetAccessTokenRequest {
48 repeated string scope = 1;
49 optional int64 service_account_id = 2;
50 optional string service_account_name = 3;
51 }
52
53 message GetAccessTokenResponse {
54 optional string access_token = 1;
55 optional int64 expiration_time = 2;
56 }
57
58 message GetDefaultGcsBucketNameRequest {
59 }
60
61 message GetDefaultGcsBucketNameResponse {
62 optional string default_gcs_bucket_name = 1;
63 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/base/api_base.proto
2
3 package base
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type StringProto struct {
21 Value *string `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
22 XXX_NoUnkeyedLiteral struct{} `json:"-"`
23 XXX_unrecognized []byte `json:"-"`
24 XXX_sizecache int32 `json:"-"`
25 }
26
27 func (m *StringProto) Reset() { *m = StringProto{} }
28 func (m *StringProto) String() string { return proto.CompactTextString(m) }
29 func (*StringProto) ProtoMessage() {}
30 func (*StringProto) Descriptor() ([]byte, []int) {
31 return fileDescriptor_api_base_9d49f8792e0c1140, []int{0}
32 }
33 func (m *StringProto) XXX_Unmarshal(b []byte) error {
34 return xxx_messageInfo_StringProto.Unmarshal(m, b)
35 }
36 func (m *StringProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
37 return xxx_messageInfo_StringProto.Marshal(b, m, deterministic)
38 }
39 func (dst *StringProto) XXX_Merge(src proto.Message) {
40 xxx_messageInfo_StringProto.Merge(dst, src)
41 }
42 func (m *StringProto) XXX_Size() int {
43 return xxx_messageInfo_StringProto.Size(m)
44 }
45 func (m *StringProto) XXX_DiscardUnknown() {
46 xxx_messageInfo_StringProto.DiscardUnknown(m)
47 }
48
49 var xxx_messageInfo_StringProto proto.InternalMessageInfo
50
51 func (m *StringProto) GetValue() string {
52 if m != nil && m.Value != nil {
53 return *m.Value
54 }
55 return ""
56 }
57
58 type Integer32Proto struct {
59 Value *int32 `protobuf:"varint,1,req,name=value" json:"value,omitempty"`
60 XXX_NoUnkeyedLiteral struct{} `json:"-"`
61 XXX_unrecognized []byte `json:"-"`
62 XXX_sizecache int32 `json:"-"`
63 }
64
65 func (m *Integer32Proto) Reset() { *m = Integer32Proto{} }
66 func (m *Integer32Proto) String() string { return proto.CompactTextString(m) }
67 func (*Integer32Proto) ProtoMessage() {}
68 func (*Integer32Proto) Descriptor() ([]byte, []int) {
69 return fileDescriptor_api_base_9d49f8792e0c1140, []int{1}
70 }
71 func (m *Integer32Proto) XXX_Unmarshal(b []byte) error {
72 return xxx_messageInfo_Integer32Proto.Unmarshal(m, b)
73 }
74 func (m *Integer32Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
75 return xxx_messageInfo_Integer32Proto.Marshal(b, m, deterministic)
76 }
77 func (dst *Integer32Proto) XXX_Merge(src proto.Message) {
78 xxx_messageInfo_Integer32Proto.Merge(dst, src)
79 }
80 func (m *Integer32Proto) XXX_Size() int {
81 return xxx_messageInfo_Integer32Proto.Size(m)
82 }
83 func (m *Integer32Proto) XXX_DiscardUnknown() {
84 xxx_messageInfo_Integer32Proto.DiscardUnknown(m)
85 }
86
87 var xxx_messageInfo_Integer32Proto proto.InternalMessageInfo
88
89 func (m *Integer32Proto) GetValue() int32 {
90 if m != nil && m.Value != nil {
91 return *m.Value
92 }
93 return 0
94 }
95
96 type Integer64Proto struct {
97 Value *int64 `protobuf:"varint,1,req,name=value" json:"value,omitempty"`
98 XXX_NoUnkeyedLiteral struct{} `json:"-"`
99 XXX_unrecognized []byte `json:"-"`
100 XXX_sizecache int32 `json:"-"`
101 }
102
103 func (m *Integer64Proto) Reset() { *m = Integer64Proto{} }
104 func (m *Integer64Proto) String() string { return proto.CompactTextString(m) }
105 func (*Integer64Proto) ProtoMessage() {}
106 func (*Integer64Proto) Descriptor() ([]byte, []int) {
107 return fileDescriptor_api_base_9d49f8792e0c1140, []int{2}
108 }
109 func (m *Integer64Proto) XXX_Unmarshal(b []byte) error {
110 return xxx_messageInfo_Integer64Proto.Unmarshal(m, b)
111 }
112 func (m *Integer64Proto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
113 return xxx_messageInfo_Integer64Proto.Marshal(b, m, deterministic)
114 }
115 func (dst *Integer64Proto) XXX_Merge(src proto.Message) {
116 xxx_messageInfo_Integer64Proto.Merge(dst, src)
117 }
118 func (m *Integer64Proto) XXX_Size() int {
119 return xxx_messageInfo_Integer64Proto.Size(m)
120 }
121 func (m *Integer64Proto) XXX_DiscardUnknown() {
122 xxx_messageInfo_Integer64Proto.DiscardUnknown(m)
123 }
124
125 var xxx_messageInfo_Integer64Proto proto.InternalMessageInfo
126
127 func (m *Integer64Proto) GetValue() int64 {
128 if m != nil && m.Value != nil {
129 return *m.Value
130 }
131 return 0
132 }
133
134 type BoolProto struct {
135 Value *bool `protobuf:"varint,1,req,name=value" json:"value,omitempty"`
136 XXX_NoUnkeyedLiteral struct{} `json:"-"`
137 XXX_unrecognized []byte `json:"-"`
138 XXX_sizecache int32 `json:"-"`
139 }
140
141 func (m *BoolProto) Reset() { *m = BoolProto{} }
142 func (m *BoolProto) String() string { return proto.CompactTextString(m) }
143 func (*BoolProto) ProtoMessage() {}
144 func (*BoolProto) Descriptor() ([]byte, []int) {
145 return fileDescriptor_api_base_9d49f8792e0c1140, []int{3}
146 }
147 func (m *BoolProto) XXX_Unmarshal(b []byte) error {
148 return xxx_messageInfo_BoolProto.Unmarshal(m, b)
149 }
150 func (m *BoolProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
151 return xxx_messageInfo_BoolProto.Marshal(b, m, deterministic)
152 }
153 func (dst *BoolProto) XXX_Merge(src proto.Message) {
154 xxx_messageInfo_BoolProto.Merge(dst, src)
155 }
156 func (m *BoolProto) XXX_Size() int {
157 return xxx_messageInfo_BoolProto.Size(m)
158 }
159 func (m *BoolProto) XXX_DiscardUnknown() {
160 xxx_messageInfo_BoolProto.DiscardUnknown(m)
161 }
162
163 var xxx_messageInfo_BoolProto proto.InternalMessageInfo
164
165 func (m *BoolProto) GetValue() bool {
166 if m != nil && m.Value != nil {
167 return *m.Value
168 }
169 return false
170 }
171
172 type DoubleProto struct {
173 Value *float64 `protobuf:"fixed64,1,req,name=value" json:"value,omitempty"`
174 XXX_NoUnkeyedLiteral struct{} `json:"-"`
175 XXX_unrecognized []byte `json:"-"`
176 XXX_sizecache int32 `json:"-"`
177 }
178
179 func (m *DoubleProto) Reset() { *m = DoubleProto{} }
180 func (m *DoubleProto) String() string { return proto.CompactTextString(m) }
181 func (*DoubleProto) ProtoMessage() {}
182 func (*DoubleProto) Descriptor() ([]byte, []int) {
183 return fileDescriptor_api_base_9d49f8792e0c1140, []int{4}
184 }
185 func (m *DoubleProto) XXX_Unmarshal(b []byte) error {
186 return xxx_messageInfo_DoubleProto.Unmarshal(m, b)
187 }
188 func (m *DoubleProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
189 return xxx_messageInfo_DoubleProto.Marshal(b, m, deterministic)
190 }
191 func (dst *DoubleProto) XXX_Merge(src proto.Message) {
192 xxx_messageInfo_DoubleProto.Merge(dst, src)
193 }
194 func (m *DoubleProto) XXX_Size() int {
195 return xxx_messageInfo_DoubleProto.Size(m)
196 }
197 func (m *DoubleProto) XXX_DiscardUnknown() {
198 xxx_messageInfo_DoubleProto.DiscardUnknown(m)
199 }
200
201 var xxx_messageInfo_DoubleProto proto.InternalMessageInfo
202
203 func (m *DoubleProto) GetValue() float64 {
204 if m != nil && m.Value != nil {
205 return *m.Value
206 }
207 return 0
208 }
209
210 type BytesProto struct {
211 Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
212 XXX_NoUnkeyedLiteral struct{} `json:"-"`
213 XXX_unrecognized []byte `json:"-"`
214 XXX_sizecache int32 `json:"-"`
215 }
216
217 func (m *BytesProto) Reset() { *m = BytesProto{} }
218 func (m *BytesProto) String() string { return proto.CompactTextString(m) }
219 func (*BytesProto) ProtoMessage() {}
220 func (*BytesProto) Descriptor() ([]byte, []int) {
221 return fileDescriptor_api_base_9d49f8792e0c1140, []int{5}
222 }
223 func (m *BytesProto) XXX_Unmarshal(b []byte) error {
224 return xxx_messageInfo_BytesProto.Unmarshal(m, b)
225 }
226 func (m *BytesProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
227 return xxx_messageInfo_BytesProto.Marshal(b, m, deterministic)
228 }
229 func (dst *BytesProto) XXX_Merge(src proto.Message) {
230 xxx_messageInfo_BytesProto.Merge(dst, src)
231 }
232 func (m *BytesProto) XXX_Size() int {
233 return xxx_messageInfo_BytesProto.Size(m)
234 }
235 func (m *BytesProto) XXX_DiscardUnknown() {
236 xxx_messageInfo_BytesProto.DiscardUnknown(m)
237 }
238
239 var xxx_messageInfo_BytesProto proto.InternalMessageInfo
240
241 func (m *BytesProto) GetValue() []byte {
242 if m != nil {
243 return m.Value
244 }
245 return nil
246 }
247
248 type VoidProto struct {
249 XXX_NoUnkeyedLiteral struct{} `json:"-"`
250 XXX_unrecognized []byte `json:"-"`
251 XXX_sizecache int32 `json:"-"`
252 }
253
254 func (m *VoidProto) Reset() { *m = VoidProto{} }
255 func (m *VoidProto) String() string { return proto.CompactTextString(m) }
256 func (*VoidProto) ProtoMessage() {}
257 func (*VoidProto) Descriptor() ([]byte, []int) {
258 return fileDescriptor_api_base_9d49f8792e0c1140, []int{6}
259 }
260 func (m *VoidProto) XXX_Unmarshal(b []byte) error {
261 return xxx_messageInfo_VoidProto.Unmarshal(m, b)
262 }
263 func (m *VoidProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
264 return xxx_messageInfo_VoidProto.Marshal(b, m, deterministic)
265 }
266 func (dst *VoidProto) XXX_Merge(src proto.Message) {
267 xxx_messageInfo_VoidProto.Merge(dst, src)
268 }
269 func (m *VoidProto) XXX_Size() int {
270 return xxx_messageInfo_VoidProto.Size(m)
271 }
272 func (m *VoidProto) XXX_DiscardUnknown() {
273 xxx_messageInfo_VoidProto.DiscardUnknown(m)
274 }
275
276 var xxx_messageInfo_VoidProto proto.InternalMessageInfo
277
278 func init() {
279 proto.RegisterType((*StringProto)(nil), "appengine.base.StringProto")
280 proto.RegisterType((*Integer32Proto)(nil), "appengine.base.Integer32Proto")
281 proto.RegisterType((*Integer64Proto)(nil), "appengine.base.Integer64Proto")
282 proto.RegisterType((*BoolProto)(nil), "appengine.base.BoolProto")
283 proto.RegisterType((*DoubleProto)(nil), "appengine.base.DoubleProto")
284 proto.RegisterType((*BytesProto)(nil), "appengine.base.BytesProto")
285 proto.RegisterType((*VoidProto)(nil), "appengine.base.VoidProto")
286 }
287
288 func init() {
289 proto.RegisterFile("google.golang.org/appengine/v2/internal/base/api_base.proto", fileDescriptor_api_base_9d49f8792e0c1140)
290 }
291
292 var fileDescriptor_api_base_9d49f8792e0c1140 = []byte{
293 // 199 bytes of a gzipped FileDescriptorProto
294 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0xcf, 0x3f, 0x4b, 0xc6, 0x30,
295 0x10, 0x06, 0x70, 0x5a, 0xad, 0xb4, 0x57, 0xe9, 0x20, 0x0e, 0x1d, 0xb5, 0x05, 0x71, 0x4a, 0x40,
296 0x45, 0x9c, 0x83, 0x8b, 0x9b, 0x28, 0x38, 0xb8, 0x48, 0x8a, 0xc7, 0x11, 0x08, 0xb9, 0x90, 0xa6,
297 0x82, 0xdf, 0x5e, 0xda, 0xd2, 0xfa, 0xc2, 0x9b, 0xed, 0xfe, 0xfc, 0xe0, 0xe1, 0x81, 0x27, 0x62,
298 0x26, 0x8b, 0x82, 0xd8, 0x6a, 0x47, 0x82, 0x03, 0x49, 0xed, 0x3d, 0x3a, 0x32, 0x0e, 0xa5, 0x71,
299 0x11, 0x83, 0xd3, 0x56, 0x0e, 0x7a, 0x44, 0xa9, 0xbd, 0xf9, 0x9a, 0x07, 0xe1, 0x03, 0x47, 0xbe,
300 0x68, 0x76, 0x27, 0xe6, 0x6b, 0xd7, 0x43, 0xfd, 0x1e, 0x83, 0x71, 0xf4, 0xba, 0xbc, 0x2f, 0xa1,
301 0xf8, 0xd1, 0x76, 0xc2, 0x36, 0xbb, 0xca, 0x6f, 0xab, 0xb7, 0x75, 0xe9, 0x6e, 0xa0, 0x79, 0x71,
302 0x11, 0x09, 0xc3, 0xfd, 0x5d, 0xc2, 0x15, 0xc7, 0xee, 0xf1, 0x21, 0xe1, 0x4e, 0x36, 0x77, 0x0d,
303 0x95, 0x62, 0xb6, 0x09, 0x52, 0x6e, 0xa4, 0x87, 0xfa, 0x99, 0xa7, 0xc1, 0x62, 0x02, 0x65, 0xff,
304 0x79, 0xa0, 0x7e, 0x23, 0x8e, 0xab, 0x69, 0x0f, 0xcd, 0xb9, 0xca, 0xcb, 0xdd, 0xd5, 0x50, 0x7d,
305 0xb0, 0xf9, 0x5e, 0x98, 0x3a, 0xfb, 0x3c, 0x9d, 0x9b, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0xba,
306 0x37, 0x25, 0xea, 0x44, 0x01, 0x00, 0x00,
307 }
0 // Built-in base types for API calls. Primarily useful as return types.
1
2 syntax = "proto2";
3 option go_package = "base";
4
5 package appengine.base;
6
7 message StringProto {
8 required string value = 1;
9 }
10
11 message Integer32Proto {
12 required int32 value = 1;
13 }
14
15 message Integer64Proto {
16 required int64 value = 1;
17 }
18
19 message BoolProto {
20 required bool value = 1;
21 }
22
23 message DoubleProto {
24 required double value = 1;
25 }
26
27 message BytesProto {
28 required bytes value = 1 [ctype=CORD];
29 }
30
31 message VoidProto {
32 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/blobstore/blobstore_service.proto
2
3 package blobstore
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type BlobstoreServiceError_ErrorCode int32
21
22 const (
23 BlobstoreServiceError_OK BlobstoreServiceError_ErrorCode = 0
24 BlobstoreServiceError_INTERNAL_ERROR BlobstoreServiceError_ErrorCode = 1
25 BlobstoreServiceError_URL_TOO_LONG BlobstoreServiceError_ErrorCode = 2
26 BlobstoreServiceError_PERMISSION_DENIED BlobstoreServiceError_ErrorCode = 3
27 BlobstoreServiceError_BLOB_NOT_FOUND BlobstoreServiceError_ErrorCode = 4
28 BlobstoreServiceError_DATA_INDEX_OUT_OF_RANGE BlobstoreServiceError_ErrorCode = 5
29 BlobstoreServiceError_BLOB_FETCH_SIZE_TOO_LARGE BlobstoreServiceError_ErrorCode = 6
30 BlobstoreServiceError_ARGUMENT_OUT_OF_RANGE BlobstoreServiceError_ErrorCode = 8
31 BlobstoreServiceError_INVALID_BLOB_KEY BlobstoreServiceError_ErrorCode = 9
32 )
33
34 var BlobstoreServiceError_ErrorCode_name = map[int32]string{
35 0: "OK",
36 1: "INTERNAL_ERROR",
37 2: "URL_TOO_LONG",
38 3: "PERMISSION_DENIED",
39 4: "BLOB_NOT_FOUND",
40 5: "DATA_INDEX_OUT_OF_RANGE",
41 6: "BLOB_FETCH_SIZE_TOO_LARGE",
42 8: "ARGUMENT_OUT_OF_RANGE",
43 9: "INVALID_BLOB_KEY",
44 }
45 var BlobstoreServiceError_ErrorCode_value = map[string]int32{
46 "OK": 0,
47 "INTERNAL_ERROR": 1,
48 "URL_TOO_LONG": 2,
49 "PERMISSION_DENIED": 3,
50 "BLOB_NOT_FOUND": 4,
51 "DATA_INDEX_OUT_OF_RANGE": 5,
52 "BLOB_FETCH_SIZE_TOO_LARGE": 6,
53 "ARGUMENT_OUT_OF_RANGE": 8,
54 "INVALID_BLOB_KEY": 9,
55 }
56
57 func (x BlobstoreServiceError_ErrorCode) Enum() *BlobstoreServiceError_ErrorCode {
58 p := new(BlobstoreServiceError_ErrorCode)
59 *p = x
60 return p
61 }
62 func (x BlobstoreServiceError_ErrorCode) String() string {
63 return proto.EnumName(BlobstoreServiceError_ErrorCode_name, int32(x))
64 }
65 func (x *BlobstoreServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
66 value, err := proto.UnmarshalJSONEnum(BlobstoreServiceError_ErrorCode_value, data, "BlobstoreServiceError_ErrorCode")
67 if err != nil {
68 return err
69 }
70 *x = BlobstoreServiceError_ErrorCode(value)
71 return nil
72 }
73 func (BlobstoreServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
74 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{0, 0}
75 }
76
77 type BlobstoreServiceError struct {
78 XXX_NoUnkeyedLiteral struct{} `json:"-"`
79 XXX_unrecognized []byte `json:"-"`
80 XXX_sizecache int32 `json:"-"`
81 }
82
83 func (m *BlobstoreServiceError) Reset() { *m = BlobstoreServiceError{} }
84 func (m *BlobstoreServiceError) String() string { return proto.CompactTextString(m) }
85 func (*BlobstoreServiceError) ProtoMessage() {}
86 func (*BlobstoreServiceError) Descriptor() ([]byte, []int) {
87 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{0}
88 }
89 func (m *BlobstoreServiceError) XXX_Unmarshal(b []byte) error {
90 return xxx_messageInfo_BlobstoreServiceError.Unmarshal(m, b)
91 }
92 func (m *BlobstoreServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
93 return xxx_messageInfo_BlobstoreServiceError.Marshal(b, m, deterministic)
94 }
95 func (dst *BlobstoreServiceError) XXX_Merge(src proto.Message) {
96 xxx_messageInfo_BlobstoreServiceError.Merge(dst, src)
97 }
98 func (m *BlobstoreServiceError) XXX_Size() int {
99 return xxx_messageInfo_BlobstoreServiceError.Size(m)
100 }
101 func (m *BlobstoreServiceError) XXX_DiscardUnknown() {
102 xxx_messageInfo_BlobstoreServiceError.DiscardUnknown(m)
103 }
104
105 var xxx_messageInfo_BlobstoreServiceError proto.InternalMessageInfo
106
107 type CreateUploadURLRequest struct {
108 SuccessPath *string `protobuf:"bytes,1,req,name=success_path,json=successPath" json:"success_path,omitempty"`
109 MaxUploadSizeBytes *int64 `protobuf:"varint,2,opt,name=max_upload_size_bytes,json=maxUploadSizeBytes" json:"max_upload_size_bytes,omitempty"`
110 MaxUploadSizePerBlobBytes *int64 `protobuf:"varint,3,opt,name=max_upload_size_per_blob_bytes,json=maxUploadSizePerBlobBytes" json:"max_upload_size_per_blob_bytes,omitempty"`
111 GsBucketName *string `protobuf:"bytes,4,opt,name=gs_bucket_name,json=gsBucketName" json:"gs_bucket_name,omitempty"`
112 UrlExpiryTimeSeconds *int32 `protobuf:"varint,5,opt,name=url_expiry_time_seconds,json=urlExpiryTimeSeconds" json:"url_expiry_time_seconds,omitempty"`
113 XXX_NoUnkeyedLiteral struct{} `json:"-"`
114 XXX_unrecognized []byte `json:"-"`
115 XXX_sizecache int32 `json:"-"`
116 }
117
118 func (m *CreateUploadURLRequest) Reset() { *m = CreateUploadURLRequest{} }
119 func (m *CreateUploadURLRequest) String() string { return proto.CompactTextString(m) }
120 func (*CreateUploadURLRequest) ProtoMessage() {}
121 func (*CreateUploadURLRequest) Descriptor() ([]byte, []int) {
122 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{1}
123 }
124 func (m *CreateUploadURLRequest) XXX_Unmarshal(b []byte) error {
125 return xxx_messageInfo_CreateUploadURLRequest.Unmarshal(m, b)
126 }
127 func (m *CreateUploadURLRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
128 return xxx_messageInfo_CreateUploadURLRequest.Marshal(b, m, deterministic)
129 }
130 func (dst *CreateUploadURLRequest) XXX_Merge(src proto.Message) {
131 xxx_messageInfo_CreateUploadURLRequest.Merge(dst, src)
132 }
133 func (m *CreateUploadURLRequest) XXX_Size() int {
134 return xxx_messageInfo_CreateUploadURLRequest.Size(m)
135 }
136 func (m *CreateUploadURLRequest) XXX_DiscardUnknown() {
137 xxx_messageInfo_CreateUploadURLRequest.DiscardUnknown(m)
138 }
139
140 var xxx_messageInfo_CreateUploadURLRequest proto.InternalMessageInfo
141
142 func (m *CreateUploadURLRequest) GetSuccessPath() string {
143 if m != nil && m.SuccessPath != nil {
144 return *m.SuccessPath
145 }
146 return ""
147 }
148
149 func (m *CreateUploadURLRequest) GetMaxUploadSizeBytes() int64 {
150 if m != nil && m.MaxUploadSizeBytes != nil {
151 return *m.MaxUploadSizeBytes
152 }
153 return 0
154 }
155
156 func (m *CreateUploadURLRequest) GetMaxUploadSizePerBlobBytes() int64 {
157 if m != nil && m.MaxUploadSizePerBlobBytes != nil {
158 return *m.MaxUploadSizePerBlobBytes
159 }
160 return 0
161 }
162
163 func (m *CreateUploadURLRequest) GetGsBucketName() string {
164 if m != nil && m.GsBucketName != nil {
165 return *m.GsBucketName
166 }
167 return ""
168 }
169
170 func (m *CreateUploadURLRequest) GetUrlExpiryTimeSeconds() int32 {
171 if m != nil && m.UrlExpiryTimeSeconds != nil {
172 return *m.UrlExpiryTimeSeconds
173 }
174 return 0
175 }
176
177 type CreateUploadURLResponse struct {
178 Url *string `protobuf:"bytes,1,req,name=url" json:"url,omitempty"`
179 XXX_NoUnkeyedLiteral struct{} `json:"-"`
180 XXX_unrecognized []byte `json:"-"`
181 XXX_sizecache int32 `json:"-"`
182 }
183
184 func (m *CreateUploadURLResponse) Reset() { *m = CreateUploadURLResponse{} }
185 func (m *CreateUploadURLResponse) String() string { return proto.CompactTextString(m) }
186 func (*CreateUploadURLResponse) ProtoMessage() {}
187 func (*CreateUploadURLResponse) Descriptor() ([]byte, []int) {
188 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{2}
189 }
190 func (m *CreateUploadURLResponse) XXX_Unmarshal(b []byte) error {
191 return xxx_messageInfo_CreateUploadURLResponse.Unmarshal(m, b)
192 }
193 func (m *CreateUploadURLResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
194 return xxx_messageInfo_CreateUploadURLResponse.Marshal(b, m, deterministic)
195 }
196 func (dst *CreateUploadURLResponse) XXX_Merge(src proto.Message) {
197 xxx_messageInfo_CreateUploadURLResponse.Merge(dst, src)
198 }
199 func (m *CreateUploadURLResponse) XXX_Size() int {
200 return xxx_messageInfo_CreateUploadURLResponse.Size(m)
201 }
202 func (m *CreateUploadURLResponse) XXX_DiscardUnknown() {
203 xxx_messageInfo_CreateUploadURLResponse.DiscardUnknown(m)
204 }
205
206 var xxx_messageInfo_CreateUploadURLResponse proto.InternalMessageInfo
207
208 func (m *CreateUploadURLResponse) GetUrl() string {
209 if m != nil && m.Url != nil {
210 return *m.Url
211 }
212 return ""
213 }
214
215 type DeleteBlobRequest struct {
216 BlobKey []string `protobuf:"bytes,1,rep,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
217 Token *string `protobuf:"bytes,2,opt,name=token" json:"token,omitempty"`
218 XXX_NoUnkeyedLiteral struct{} `json:"-"`
219 XXX_unrecognized []byte `json:"-"`
220 XXX_sizecache int32 `json:"-"`
221 }
222
223 func (m *DeleteBlobRequest) Reset() { *m = DeleteBlobRequest{} }
224 func (m *DeleteBlobRequest) String() string { return proto.CompactTextString(m) }
225 func (*DeleteBlobRequest) ProtoMessage() {}
226 func (*DeleteBlobRequest) Descriptor() ([]byte, []int) {
227 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{3}
228 }
229 func (m *DeleteBlobRequest) XXX_Unmarshal(b []byte) error {
230 return xxx_messageInfo_DeleteBlobRequest.Unmarshal(m, b)
231 }
232 func (m *DeleteBlobRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
233 return xxx_messageInfo_DeleteBlobRequest.Marshal(b, m, deterministic)
234 }
235 func (dst *DeleteBlobRequest) XXX_Merge(src proto.Message) {
236 xxx_messageInfo_DeleteBlobRequest.Merge(dst, src)
237 }
238 func (m *DeleteBlobRequest) XXX_Size() int {
239 return xxx_messageInfo_DeleteBlobRequest.Size(m)
240 }
241 func (m *DeleteBlobRequest) XXX_DiscardUnknown() {
242 xxx_messageInfo_DeleteBlobRequest.DiscardUnknown(m)
243 }
244
245 var xxx_messageInfo_DeleteBlobRequest proto.InternalMessageInfo
246
247 func (m *DeleteBlobRequest) GetBlobKey() []string {
248 if m != nil {
249 return m.BlobKey
250 }
251 return nil
252 }
253
254 func (m *DeleteBlobRequest) GetToken() string {
255 if m != nil && m.Token != nil {
256 return *m.Token
257 }
258 return ""
259 }
260
261 type FetchDataRequest struct {
262 BlobKey *string `protobuf:"bytes,1,req,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
263 StartIndex *int64 `protobuf:"varint,2,req,name=start_index,json=startIndex" json:"start_index,omitempty"`
264 EndIndex *int64 `protobuf:"varint,3,req,name=end_index,json=endIndex" json:"end_index,omitempty"`
265 XXX_NoUnkeyedLiteral struct{} `json:"-"`
266 XXX_unrecognized []byte `json:"-"`
267 XXX_sizecache int32 `json:"-"`
268 }
269
270 func (m *FetchDataRequest) Reset() { *m = FetchDataRequest{} }
271 func (m *FetchDataRequest) String() string { return proto.CompactTextString(m) }
272 func (*FetchDataRequest) ProtoMessage() {}
273 func (*FetchDataRequest) Descriptor() ([]byte, []int) {
274 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{4}
275 }
276 func (m *FetchDataRequest) XXX_Unmarshal(b []byte) error {
277 return xxx_messageInfo_FetchDataRequest.Unmarshal(m, b)
278 }
279 func (m *FetchDataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
280 return xxx_messageInfo_FetchDataRequest.Marshal(b, m, deterministic)
281 }
282 func (dst *FetchDataRequest) XXX_Merge(src proto.Message) {
283 xxx_messageInfo_FetchDataRequest.Merge(dst, src)
284 }
285 func (m *FetchDataRequest) XXX_Size() int {
286 return xxx_messageInfo_FetchDataRequest.Size(m)
287 }
288 func (m *FetchDataRequest) XXX_DiscardUnknown() {
289 xxx_messageInfo_FetchDataRequest.DiscardUnknown(m)
290 }
291
292 var xxx_messageInfo_FetchDataRequest proto.InternalMessageInfo
293
294 func (m *FetchDataRequest) GetBlobKey() string {
295 if m != nil && m.BlobKey != nil {
296 return *m.BlobKey
297 }
298 return ""
299 }
300
301 func (m *FetchDataRequest) GetStartIndex() int64 {
302 if m != nil && m.StartIndex != nil {
303 return *m.StartIndex
304 }
305 return 0
306 }
307
308 func (m *FetchDataRequest) GetEndIndex() int64 {
309 if m != nil && m.EndIndex != nil {
310 return *m.EndIndex
311 }
312 return 0
313 }
314
315 type FetchDataResponse struct {
316 Data []byte `protobuf:"bytes,1000,req,name=data" json:"data,omitempty"`
317 XXX_NoUnkeyedLiteral struct{} `json:"-"`
318 XXX_unrecognized []byte `json:"-"`
319 XXX_sizecache int32 `json:"-"`
320 }
321
322 func (m *FetchDataResponse) Reset() { *m = FetchDataResponse{} }
323 func (m *FetchDataResponse) String() string { return proto.CompactTextString(m) }
324 func (*FetchDataResponse) ProtoMessage() {}
325 func (*FetchDataResponse) Descriptor() ([]byte, []int) {
326 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{5}
327 }
328 func (m *FetchDataResponse) XXX_Unmarshal(b []byte) error {
329 return xxx_messageInfo_FetchDataResponse.Unmarshal(m, b)
330 }
331 func (m *FetchDataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
332 return xxx_messageInfo_FetchDataResponse.Marshal(b, m, deterministic)
333 }
334 func (dst *FetchDataResponse) XXX_Merge(src proto.Message) {
335 xxx_messageInfo_FetchDataResponse.Merge(dst, src)
336 }
337 func (m *FetchDataResponse) XXX_Size() int {
338 return xxx_messageInfo_FetchDataResponse.Size(m)
339 }
340 func (m *FetchDataResponse) XXX_DiscardUnknown() {
341 xxx_messageInfo_FetchDataResponse.DiscardUnknown(m)
342 }
343
344 var xxx_messageInfo_FetchDataResponse proto.InternalMessageInfo
345
346 func (m *FetchDataResponse) GetData() []byte {
347 if m != nil {
348 return m.Data
349 }
350 return nil
351 }
352
353 type CloneBlobRequest struct {
354 BlobKey []byte `protobuf:"bytes,1,req,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
355 MimeType []byte `protobuf:"bytes,2,req,name=mime_type,json=mimeType" json:"mime_type,omitempty"`
356 TargetAppId []byte `protobuf:"bytes,3,req,name=target_app_id,json=targetAppId" json:"target_app_id,omitempty"`
357 XXX_NoUnkeyedLiteral struct{} `json:"-"`
358 XXX_unrecognized []byte `json:"-"`
359 XXX_sizecache int32 `json:"-"`
360 }
361
362 func (m *CloneBlobRequest) Reset() { *m = CloneBlobRequest{} }
363 func (m *CloneBlobRequest) String() string { return proto.CompactTextString(m) }
364 func (*CloneBlobRequest) ProtoMessage() {}
365 func (*CloneBlobRequest) Descriptor() ([]byte, []int) {
366 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{6}
367 }
368 func (m *CloneBlobRequest) XXX_Unmarshal(b []byte) error {
369 return xxx_messageInfo_CloneBlobRequest.Unmarshal(m, b)
370 }
371 func (m *CloneBlobRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
372 return xxx_messageInfo_CloneBlobRequest.Marshal(b, m, deterministic)
373 }
374 func (dst *CloneBlobRequest) XXX_Merge(src proto.Message) {
375 xxx_messageInfo_CloneBlobRequest.Merge(dst, src)
376 }
377 func (m *CloneBlobRequest) XXX_Size() int {
378 return xxx_messageInfo_CloneBlobRequest.Size(m)
379 }
380 func (m *CloneBlobRequest) XXX_DiscardUnknown() {
381 xxx_messageInfo_CloneBlobRequest.DiscardUnknown(m)
382 }
383
384 var xxx_messageInfo_CloneBlobRequest proto.InternalMessageInfo
385
386 func (m *CloneBlobRequest) GetBlobKey() []byte {
387 if m != nil {
388 return m.BlobKey
389 }
390 return nil
391 }
392
393 func (m *CloneBlobRequest) GetMimeType() []byte {
394 if m != nil {
395 return m.MimeType
396 }
397 return nil
398 }
399
400 func (m *CloneBlobRequest) GetTargetAppId() []byte {
401 if m != nil {
402 return m.TargetAppId
403 }
404 return nil
405 }
406
407 type CloneBlobResponse struct {
408 BlobKey []byte `protobuf:"bytes,1,req,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
409 XXX_NoUnkeyedLiteral struct{} `json:"-"`
410 XXX_unrecognized []byte `json:"-"`
411 XXX_sizecache int32 `json:"-"`
412 }
413
414 func (m *CloneBlobResponse) Reset() { *m = CloneBlobResponse{} }
415 func (m *CloneBlobResponse) String() string { return proto.CompactTextString(m) }
416 func (*CloneBlobResponse) ProtoMessage() {}
417 func (*CloneBlobResponse) Descriptor() ([]byte, []int) {
418 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{7}
419 }
420 func (m *CloneBlobResponse) XXX_Unmarshal(b []byte) error {
421 return xxx_messageInfo_CloneBlobResponse.Unmarshal(m, b)
422 }
423 func (m *CloneBlobResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
424 return xxx_messageInfo_CloneBlobResponse.Marshal(b, m, deterministic)
425 }
426 func (dst *CloneBlobResponse) XXX_Merge(src proto.Message) {
427 xxx_messageInfo_CloneBlobResponse.Merge(dst, src)
428 }
429 func (m *CloneBlobResponse) XXX_Size() int {
430 return xxx_messageInfo_CloneBlobResponse.Size(m)
431 }
432 func (m *CloneBlobResponse) XXX_DiscardUnknown() {
433 xxx_messageInfo_CloneBlobResponse.DiscardUnknown(m)
434 }
435
436 var xxx_messageInfo_CloneBlobResponse proto.InternalMessageInfo
437
438 func (m *CloneBlobResponse) GetBlobKey() []byte {
439 if m != nil {
440 return m.BlobKey
441 }
442 return nil
443 }
444
445 type DecodeBlobKeyRequest struct {
446 BlobKey []string `protobuf:"bytes,1,rep,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
447 XXX_NoUnkeyedLiteral struct{} `json:"-"`
448 XXX_unrecognized []byte `json:"-"`
449 XXX_sizecache int32 `json:"-"`
450 }
451
452 func (m *DecodeBlobKeyRequest) Reset() { *m = DecodeBlobKeyRequest{} }
453 func (m *DecodeBlobKeyRequest) String() string { return proto.CompactTextString(m) }
454 func (*DecodeBlobKeyRequest) ProtoMessage() {}
455 func (*DecodeBlobKeyRequest) Descriptor() ([]byte, []int) {
456 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{8}
457 }
458 func (m *DecodeBlobKeyRequest) XXX_Unmarshal(b []byte) error {
459 return xxx_messageInfo_DecodeBlobKeyRequest.Unmarshal(m, b)
460 }
461 func (m *DecodeBlobKeyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
462 return xxx_messageInfo_DecodeBlobKeyRequest.Marshal(b, m, deterministic)
463 }
464 func (dst *DecodeBlobKeyRequest) XXX_Merge(src proto.Message) {
465 xxx_messageInfo_DecodeBlobKeyRequest.Merge(dst, src)
466 }
467 func (m *DecodeBlobKeyRequest) XXX_Size() int {
468 return xxx_messageInfo_DecodeBlobKeyRequest.Size(m)
469 }
470 func (m *DecodeBlobKeyRequest) XXX_DiscardUnknown() {
471 xxx_messageInfo_DecodeBlobKeyRequest.DiscardUnknown(m)
472 }
473
474 var xxx_messageInfo_DecodeBlobKeyRequest proto.InternalMessageInfo
475
476 func (m *DecodeBlobKeyRequest) GetBlobKey() []string {
477 if m != nil {
478 return m.BlobKey
479 }
480 return nil
481 }
482
483 type DecodeBlobKeyResponse struct {
484 Decoded []string `protobuf:"bytes,1,rep,name=decoded" json:"decoded,omitempty"`
485 XXX_NoUnkeyedLiteral struct{} `json:"-"`
486 XXX_unrecognized []byte `json:"-"`
487 XXX_sizecache int32 `json:"-"`
488 }
489
490 func (m *DecodeBlobKeyResponse) Reset() { *m = DecodeBlobKeyResponse{} }
491 func (m *DecodeBlobKeyResponse) String() string { return proto.CompactTextString(m) }
492 func (*DecodeBlobKeyResponse) ProtoMessage() {}
493 func (*DecodeBlobKeyResponse) Descriptor() ([]byte, []int) {
494 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{9}
495 }
496 func (m *DecodeBlobKeyResponse) XXX_Unmarshal(b []byte) error {
497 return xxx_messageInfo_DecodeBlobKeyResponse.Unmarshal(m, b)
498 }
499 func (m *DecodeBlobKeyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
500 return xxx_messageInfo_DecodeBlobKeyResponse.Marshal(b, m, deterministic)
501 }
502 func (dst *DecodeBlobKeyResponse) XXX_Merge(src proto.Message) {
503 xxx_messageInfo_DecodeBlobKeyResponse.Merge(dst, src)
504 }
505 func (m *DecodeBlobKeyResponse) XXX_Size() int {
506 return xxx_messageInfo_DecodeBlobKeyResponse.Size(m)
507 }
508 func (m *DecodeBlobKeyResponse) XXX_DiscardUnknown() {
509 xxx_messageInfo_DecodeBlobKeyResponse.DiscardUnknown(m)
510 }
511
512 var xxx_messageInfo_DecodeBlobKeyResponse proto.InternalMessageInfo
513
514 func (m *DecodeBlobKeyResponse) GetDecoded() []string {
515 if m != nil {
516 return m.Decoded
517 }
518 return nil
519 }
520
521 type CreateEncodedGoogleStorageKeyRequest struct {
522 Filename *string `protobuf:"bytes,1,req,name=filename" json:"filename,omitempty"`
523 XXX_NoUnkeyedLiteral struct{} `json:"-"`
524 XXX_unrecognized []byte `json:"-"`
525 XXX_sizecache int32 `json:"-"`
526 }
527
528 func (m *CreateEncodedGoogleStorageKeyRequest) Reset() { *m = CreateEncodedGoogleStorageKeyRequest{} }
529 func (m *CreateEncodedGoogleStorageKeyRequest) String() string { return proto.CompactTextString(m) }
530 func (*CreateEncodedGoogleStorageKeyRequest) ProtoMessage() {}
531 func (*CreateEncodedGoogleStorageKeyRequest) Descriptor() ([]byte, []int) {
532 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{10}
533 }
534 func (m *CreateEncodedGoogleStorageKeyRequest) XXX_Unmarshal(b []byte) error {
535 return xxx_messageInfo_CreateEncodedGoogleStorageKeyRequest.Unmarshal(m, b)
536 }
537 func (m *CreateEncodedGoogleStorageKeyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
538 return xxx_messageInfo_CreateEncodedGoogleStorageKeyRequest.Marshal(b, m, deterministic)
539 }
540 func (dst *CreateEncodedGoogleStorageKeyRequest) XXX_Merge(src proto.Message) {
541 xxx_messageInfo_CreateEncodedGoogleStorageKeyRequest.Merge(dst, src)
542 }
543 func (m *CreateEncodedGoogleStorageKeyRequest) XXX_Size() int {
544 return xxx_messageInfo_CreateEncodedGoogleStorageKeyRequest.Size(m)
545 }
546 func (m *CreateEncodedGoogleStorageKeyRequest) XXX_DiscardUnknown() {
547 xxx_messageInfo_CreateEncodedGoogleStorageKeyRequest.DiscardUnknown(m)
548 }
549
550 var xxx_messageInfo_CreateEncodedGoogleStorageKeyRequest proto.InternalMessageInfo
551
552 func (m *CreateEncodedGoogleStorageKeyRequest) GetFilename() string {
553 if m != nil && m.Filename != nil {
554 return *m.Filename
555 }
556 return ""
557 }
558
559 type CreateEncodedGoogleStorageKeyResponse struct {
560 BlobKey *string `protobuf:"bytes,1,req,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
561 XXX_NoUnkeyedLiteral struct{} `json:"-"`
562 XXX_unrecognized []byte `json:"-"`
563 XXX_sizecache int32 `json:"-"`
564 }
565
566 func (m *CreateEncodedGoogleStorageKeyResponse) Reset() { *m = CreateEncodedGoogleStorageKeyResponse{} }
567 func (m *CreateEncodedGoogleStorageKeyResponse) String() string { return proto.CompactTextString(m) }
568 func (*CreateEncodedGoogleStorageKeyResponse) ProtoMessage() {}
569 func (*CreateEncodedGoogleStorageKeyResponse) Descriptor() ([]byte, []int) {
570 return fileDescriptor_blobstore_service_3604fb6033ea2e2e, []int{11}
571 }
572 func (m *CreateEncodedGoogleStorageKeyResponse) XXX_Unmarshal(b []byte) error {
573 return xxx_messageInfo_CreateEncodedGoogleStorageKeyResponse.Unmarshal(m, b)
574 }
575 func (m *CreateEncodedGoogleStorageKeyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
576 return xxx_messageInfo_CreateEncodedGoogleStorageKeyResponse.Marshal(b, m, deterministic)
577 }
578 func (dst *CreateEncodedGoogleStorageKeyResponse) XXX_Merge(src proto.Message) {
579 xxx_messageInfo_CreateEncodedGoogleStorageKeyResponse.Merge(dst, src)
580 }
581 func (m *CreateEncodedGoogleStorageKeyResponse) XXX_Size() int {
582 return xxx_messageInfo_CreateEncodedGoogleStorageKeyResponse.Size(m)
583 }
584 func (m *CreateEncodedGoogleStorageKeyResponse) XXX_DiscardUnknown() {
585 xxx_messageInfo_CreateEncodedGoogleStorageKeyResponse.DiscardUnknown(m)
586 }
587
588 var xxx_messageInfo_CreateEncodedGoogleStorageKeyResponse proto.InternalMessageInfo
589
590 func (m *CreateEncodedGoogleStorageKeyResponse) GetBlobKey() string {
591 if m != nil && m.BlobKey != nil {
592 return *m.BlobKey
593 }
594 return ""
595 }
596
597 func init() {
598 proto.RegisterType((*BlobstoreServiceError)(nil), "appengine.BlobstoreServiceError")
599 proto.RegisterType((*CreateUploadURLRequest)(nil), "appengine.CreateUploadURLRequest")
600 proto.RegisterType((*CreateUploadURLResponse)(nil), "appengine.CreateUploadURLResponse")
601 proto.RegisterType((*DeleteBlobRequest)(nil), "appengine.DeleteBlobRequest")
602 proto.RegisterType((*FetchDataRequest)(nil), "appengine.FetchDataRequest")
603 proto.RegisterType((*FetchDataResponse)(nil), "appengine.FetchDataResponse")
604 proto.RegisterType((*CloneBlobRequest)(nil), "appengine.CloneBlobRequest")
605 proto.RegisterType((*CloneBlobResponse)(nil), "appengine.CloneBlobResponse")
606 proto.RegisterType((*DecodeBlobKeyRequest)(nil), "appengine.DecodeBlobKeyRequest")
607 proto.RegisterType((*DecodeBlobKeyResponse)(nil), "appengine.DecodeBlobKeyResponse")
608 proto.RegisterType((*CreateEncodedGoogleStorageKeyRequest)(nil), "appengine.CreateEncodedGoogleStorageKeyRequest")
609 proto.RegisterType((*CreateEncodedGoogleStorageKeyResponse)(nil), "appengine.CreateEncodedGoogleStorageKeyResponse")
610 }
611
612 func init() {
613 proto.RegisterFile("google.golang.org/appengine/v2/internal/blobstore/blobstore_service.proto", fileDescriptor_blobstore_service_3604fb6033ea2e2e)
614 }
615
616 var fileDescriptor_blobstore_service_3604fb6033ea2e2e = []byte{
617 // 737 bytes of a gzipped FileDescriptorProto
618 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0xe1, 0x6e, 0xe3, 0x44,
619 0x10, 0xc6, 0x4e, 0x7b, 0x8d, 0xa7, 0xe1, 0xe4, 0xae, 0x1a, 0x9a, 0x52, 0x01, 0xc1, 0x3a, 0xa4,
620 0x48, 0xa0, 0x56, 0xfd, 0xc1, 0x03, 0xd8, 0xb5, 0x13, 0xac, 0xe6, 0xec, 0x6a, 0xe3, 0x20, 0xb8,
621 0x3f, 0xab, 0x6d, 0x3c, 0xb8, 0x56, 0x1d, 0xaf, 0x59, 0x6f, 0x50, 0x73, 0x0f, 0xc1, 0xbb, 0xf1,
622 0x16, 0x48, 0xbc, 0x04, 0xf2, 0xda, 0x6d, 0x73, 0x07, 0x77, 0xf7, 0x6f, 0xe7, 0xfb, 0xf6, 0x9b,
623 0xf9, 0x66, 0x66, 0xb5, 0x30, 0xcd, 0x84, 0xc8, 0x0a, 0x3c, 0xcf, 0x44, 0xc1, 0xcb, 0xec, 0x5c,
624 0xc8, 0xec, 0x82, 0x57, 0x15, 0x96, 0x59, 0x5e, 0xe2, 0x45, 0x5e, 0x2a, 0x94, 0x25, 0x2f, 0x2e,
625 0x6e, 0x0b, 0x71, 0x5b, 0x2b, 0x21, 0xf1, 0xf9, 0xc4, 0x6a, 0x94, 0x7f, 0xe4, 0x2b, 0x3c, 0xaf,
626 0xa4, 0x50, 0x82, 0x58, 0x4f, 0x2a, 0xe7, 0x1f, 0x03, 0x86, 0xde, 0xe3, 0xb5, 0x45, 0x7b, 0x2b,
627 0x90, 0x52, 0x48, 0xe7, 0x2f, 0x03, 0x2c, 0x7d, 0xba, 0x12, 0x29, 0x92, 0x17, 0x60, 0xc6, 0xd7,
628 0xf6, 0x67, 0x84, 0xc0, 0xcb, 0x30, 0x4a, 0x02, 0x1a, 0xb9, 0x73, 0x16, 0x50, 0x1a, 0x53, 0xdb,
629 0x20, 0x36, 0x0c, 0x96, 0x74, 0xce, 0x92, 0x38, 0x66, 0xf3, 0x38, 0x9a, 0xd9, 0x26, 0x19, 0xc2,
630 0xd1, 0x4d, 0x40, 0x5f, 0x87, 0x8b, 0x45, 0x18, 0x47, 0xcc, 0x0f, 0xa2, 0x30, 0xf0, 0xed, 0x5e,
631 0x23, 0xf6, 0xe6, 0xb1, 0xc7, 0xa2, 0x38, 0x61, 0xd3, 0x78, 0x19, 0xf9, 0xf6, 0x1e, 0x39, 0x83,
632 0x13, 0xdf, 0x4d, 0x5c, 0x16, 0x46, 0x7e, 0xf0, 0x0b, 0x8b, 0x97, 0x09, 0x8b, 0xa7, 0x8c, 0xba,
633 0xd1, 0x2c, 0xb0, 0xf7, 0xc9, 0x57, 0x70, 0xaa, 0x05, 0xd3, 0x20, 0xb9, 0xfa, 0x89, 0x2d, 0xc2,
634 0x37, 0x41, 0x5b, 0xc5, 0xa5, 0xb3, 0xc0, 0x7e, 0x41, 0x4e, 0x61, 0xe8, 0xd2, 0xd9, 0xf2, 0x75,
635 0x10, 0x25, 0xef, 0x2a, 0xfb, 0xe4, 0x18, 0xec, 0x30, 0xfa, 0xd9, 0x9d, 0x87, 0x3e, 0xd3, 0x19,
636 0xae, 0x83, 0x5f, 0x6d, 0xcb, 0xf9, 0xd3, 0x84, 0x2f, 0xae, 0x24, 0x72, 0x85, 0xcb, 0xaa, 0x10,
637 0x3c, 0x5d, 0xd2, 0x39, 0xc5, 0xdf, 0x37, 0x58, 0x2b, 0xf2, 0x2d, 0x0c, 0xea, 0xcd, 0x6a, 0x85,
638 0x75, 0xcd, 0x2a, 0xae, 0xee, 0x46, 0xc6, 0xd8, 0x9c, 0x58, 0xf4, 0xb0, 0xc3, 0x6e, 0xb8, 0xba,
639 0x23, 0x97, 0x30, 0x5c, 0xf3, 0x07, 0xb6, 0xd1, 0x52, 0x56, 0xe7, 0x6f, 0x91, 0xdd, 0x6e, 0x15,
640 0xd6, 0x23, 0x73, 0x6c, 0x4c, 0x7a, 0x94, 0xac, 0xf9, 0x43, 0x9b, 0x76, 0x91, 0xbf, 0x45, 0xaf,
641 0x61, 0x88, 0x0b, 0x5f, 0xbf, 0x2f, 0xa9, 0x50, 0xb2, 0x66, 0x31, 0x9d, 0xb6, 0xa7, 0xb5, 0xa7,
642 0xef, 0x68, 0x6f, 0x50, 0x36, 0x3b, 0x69, 0x53, 0xbc, 0x82, 0x97, 0x59, 0xcd, 0x6e, 0x37, 0xab,
643 0x7b, 0x54, 0xac, 0xe4, 0x6b, 0x1c, 0xed, 0x8d, 0x8d, 0x89, 0x45, 0x07, 0x59, 0xed, 0x69, 0x30,
644 0xe2, 0x6b, 0x24, 0x3f, 0xc2, 0xc9, 0x46, 0x16, 0x0c, 0x1f, 0xaa, 0x5c, 0x6e, 0x99, 0xca, 0xd7,
645 0xcd, 0xce, 0x57, 0xa2, 0x4c, 0xeb, 0xd1, 0xfe, 0xd8, 0x98, 0xec, 0xd3, 0xe3, 0x8d, 0x2c, 0x02,
646 0xcd, 0x26, 0xf9, 0x1a, 0x17, 0x2d, 0xe7, 0x7c, 0x0f, 0x27, 0xff, 0x99, 0x47, 0x5d, 0x89, 0xb2,
647 0x46, 0x62, 0x43, 0x6f, 0x23, 0x8b, 0x6e, 0x0e, 0xcd, 0xd1, 0xf1, 0xe1, 0xc8, 0xc7, 0x02, 0x15,
648 0x36, 0xe6, 0x1e, 0xe7, 0x76, 0x0a, 0x7d, 0xdd, 0xcd, 0x3d, 0x6e, 0x47, 0xc6, 0xb8, 0x37, 0xb1,
649 0xe8, 0x41, 0x13, 0x5f, 0xe3, 0x96, 0x1c, 0xc3, 0xbe, 0x12, 0xf7, 0x58, 0xea, 0xf9, 0x58, 0xb4,
650 0x0d, 0x9c, 0x7b, 0xb0, 0xa7, 0xa8, 0x56, 0x77, 0x3e, 0x57, 0xfc, 0xff, 0x93, 0x98, 0xbb, 0x49,
651 0xbe, 0x81, 0xc3, 0x5a, 0x71, 0xa9, 0x58, 0x5e, 0xa6, 0xf8, 0x30, 0x32, 0xc7, 0xe6, 0xa4, 0x47,
652 0x41, 0x43, 0x61, 0x83, 0x90, 0x33, 0xb0, 0xb0, 0x4c, 0x3b, 0xba, 0xa7, 0xe9, 0x3e, 0x96, 0xa9,
653 0x26, 0x9d, 0x1f, 0xe0, 0x68, 0xa7, 0x58, 0xd7, 0xd9, 0x09, 0xec, 0xa5, 0x5c, 0xf1, 0xd1, 0xdf,
654 0x07, 0x63, 0x73, 0x32, 0xf0, 0xcc, 0xbe, 0x41, 0x35, 0xe0, 0x94, 0x60, 0x5f, 0x15, 0xa2, 0xfc,
655 0x48, 0x7f, 0xe6, 0x64, 0xf0, 0x6c, 0xed, 0x0c, 0xac, 0x75, 0x33, 0x68, 0xb5, 0xad, 0x50, 0x1b,
656 0x1b, 0xd0, 0x7e, 0x03, 0x24, 0xdb, 0x0a, 0x89, 0x03, 0x9f, 0x2b, 0x2e, 0x33, 0x54, 0x8c, 0x57,
657 0x15, 0xcb, 0x53, 0x6d, 0x6d, 0x40, 0x0f, 0x5b, 0xd0, 0xad, 0xaa, 0x30, 0x75, 0xce, 0xe1, 0x68,
658 0xa7, 0x5e, 0xe7, 0xee, 0xc3, 0x05, 0x9d, 0x4b, 0x38, 0xf6, 0x71, 0x25, 0x52, 0x2d, 0xb8, 0xc6,
659 0xed, 0xa7, 0x77, 0xe0, 0x5c, 0xc2, 0xf0, 0x3d, 0x49, 0x57, 0x66, 0x04, 0x07, 0xa9, 0x26, 0xd2,
660 0x47, 0x49, 0x17, 0x3a, 0x1e, 0xbc, 0x6a, 0xdf, 0x44, 0x50, 0x6a, 0x60, 0xa6, 0x3f, 0x9d, 0x85,
661 0x12, 0x92, 0x67, 0xb8, 0x53, 0xf5, 0x4b, 0xe8, 0xff, 0x96, 0x17, 0xa8, 0x9f, 0x64, 0xbb, 0xb4,
662 0xa7, 0xd8, 0xf1, 0xe0, 0xbb, 0x4f, 0xe4, 0xf8, 0x40, 0xb7, 0xcf, 0xd6, 0xbd, 0xc3, 0x37, 0xd6,
663 0xd3, 0x07, 0xf6, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc1, 0xfb, 0x81, 0x94, 0xfb, 0x04, 0x00,
664 0x00,
665 }
0 syntax = "proto2";
1 option go_package = "blobstore";
2
3 package appengine;
4
5 message BlobstoreServiceError {
6 enum ErrorCode {
7 OK = 0;
8 INTERNAL_ERROR = 1;
9 URL_TOO_LONG = 2;
10 PERMISSION_DENIED = 3;
11 BLOB_NOT_FOUND = 4;
12 DATA_INDEX_OUT_OF_RANGE = 5;
13 BLOB_FETCH_SIZE_TOO_LARGE = 6;
14 ARGUMENT_OUT_OF_RANGE = 8;
15 INVALID_BLOB_KEY = 9;
16 }
17 }
18
19 message CreateUploadURLRequest {
20 required string success_path = 1;
21 optional int64 max_upload_size_bytes = 2;
22 optional int64 max_upload_size_per_blob_bytes = 3;
23 optional string gs_bucket_name = 4;
24 optional int32 url_expiry_time_seconds = 5;
25 }
26
27 message CreateUploadURLResponse {
28 required string url = 1;
29 }
30
31 message DeleteBlobRequest {
32 repeated string blob_key = 1;
33 optional string token = 2;
34 }
35
36 message FetchDataRequest {
37 required string blob_key = 1;
38 required int64 start_index = 2;
39 required int64 end_index = 3;
40 }
41
42 message FetchDataResponse {
43 required bytes data = 1000 [ctype = CORD];
44 }
45
46 message CloneBlobRequest {
47 required bytes blob_key = 1;
48 required bytes mime_type = 2;
49 required bytes target_app_id = 3;
50 }
51
52 message CloneBlobResponse {
53 required bytes blob_key = 1;
54 }
55
56 message DecodeBlobKeyRequest {
57 repeated string blob_key = 1;
58 }
59
60 message DecodeBlobKeyResponse {
61 repeated string decoded = 1;
62 }
63
64 message CreateEncodedGoogleStorageKeyRequest {
65 required string filename = 1;
66 }
67
68 message CreateEncodedGoogleStorageKeyResponse {
69 required string blob_key = 1;
70 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/capability/capability_service.proto
2
3 package capability
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type IsEnabledResponse_SummaryStatus int32
21
22 const (
23 IsEnabledResponse_DEFAULT IsEnabledResponse_SummaryStatus = 0
24 IsEnabledResponse_ENABLED IsEnabledResponse_SummaryStatus = 1
25 IsEnabledResponse_SCHEDULED_FUTURE IsEnabledResponse_SummaryStatus = 2
26 IsEnabledResponse_SCHEDULED_NOW IsEnabledResponse_SummaryStatus = 3
27 IsEnabledResponse_DISABLED IsEnabledResponse_SummaryStatus = 4
28 IsEnabledResponse_UNKNOWN IsEnabledResponse_SummaryStatus = 5
29 )
30
31 var IsEnabledResponse_SummaryStatus_name = map[int32]string{
32 0: "DEFAULT",
33 1: "ENABLED",
34 2: "SCHEDULED_FUTURE",
35 3: "SCHEDULED_NOW",
36 4: "DISABLED",
37 5: "UNKNOWN",
38 }
39 var IsEnabledResponse_SummaryStatus_value = map[string]int32{
40 "DEFAULT": 0,
41 "ENABLED": 1,
42 "SCHEDULED_FUTURE": 2,
43 "SCHEDULED_NOW": 3,
44 "DISABLED": 4,
45 "UNKNOWN": 5,
46 }
47
48 func (x IsEnabledResponse_SummaryStatus) Enum() *IsEnabledResponse_SummaryStatus {
49 p := new(IsEnabledResponse_SummaryStatus)
50 *p = x
51 return p
52 }
53 func (x IsEnabledResponse_SummaryStatus) String() string {
54 return proto.EnumName(IsEnabledResponse_SummaryStatus_name, int32(x))
55 }
56 func (x *IsEnabledResponse_SummaryStatus) UnmarshalJSON(data []byte) error {
57 value, err := proto.UnmarshalJSONEnum(IsEnabledResponse_SummaryStatus_value, data, "IsEnabledResponse_SummaryStatus")
58 if err != nil {
59 return err
60 }
61 *x = IsEnabledResponse_SummaryStatus(value)
62 return nil
63 }
64 func (IsEnabledResponse_SummaryStatus) EnumDescriptor() ([]byte, []int) {
65 return fileDescriptor_capability_service_030277ff00db7e72, []int{1, 0}
66 }
67
68 type IsEnabledRequest struct {
69 Package *string `protobuf:"bytes,1,req,name=package" json:"package,omitempty"`
70 Capability []string `protobuf:"bytes,2,rep,name=capability" json:"capability,omitempty"`
71 Call []string `protobuf:"bytes,3,rep,name=call" json:"call,omitempty"`
72 XXX_NoUnkeyedLiteral struct{} `json:"-"`
73 XXX_unrecognized []byte `json:"-"`
74 XXX_sizecache int32 `json:"-"`
75 }
76
77 func (m *IsEnabledRequest) Reset() { *m = IsEnabledRequest{} }
78 func (m *IsEnabledRequest) String() string { return proto.CompactTextString(m) }
79 func (*IsEnabledRequest) ProtoMessage() {}
80 func (*IsEnabledRequest) Descriptor() ([]byte, []int) {
81 return fileDescriptor_capability_service_030277ff00db7e72, []int{0}
82 }
83 func (m *IsEnabledRequest) XXX_Unmarshal(b []byte) error {
84 return xxx_messageInfo_IsEnabledRequest.Unmarshal(m, b)
85 }
86 func (m *IsEnabledRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
87 return xxx_messageInfo_IsEnabledRequest.Marshal(b, m, deterministic)
88 }
89 func (dst *IsEnabledRequest) XXX_Merge(src proto.Message) {
90 xxx_messageInfo_IsEnabledRequest.Merge(dst, src)
91 }
92 func (m *IsEnabledRequest) XXX_Size() int {
93 return xxx_messageInfo_IsEnabledRequest.Size(m)
94 }
95 func (m *IsEnabledRequest) XXX_DiscardUnknown() {
96 xxx_messageInfo_IsEnabledRequest.DiscardUnknown(m)
97 }
98
99 var xxx_messageInfo_IsEnabledRequest proto.InternalMessageInfo
100
101 func (m *IsEnabledRequest) GetPackage() string {
102 if m != nil && m.Package != nil {
103 return *m.Package
104 }
105 return ""
106 }
107
108 func (m *IsEnabledRequest) GetCapability() []string {
109 if m != nil {
110 return m.Capability
111 }
112 return nil
113 }
114
115 func (m *IsEnabledRequest) GetCall() []string {
116 if m != nil {
117 return m.Call
118 }
119 return nil
120 }
121
122 type IsEnabledResponse struct {
123 SummaryStatus *IsEnabledResponse_SummaryStatus `protobuf:"varint,1,opt,name=summary_status,json=summaryStatus,enum=appengine.IsEnabledResponse_SummaryStatus" json:"summary_status,omitempty"`
124 TimeUntilScheduled *int64 `protobuf:"varint,2,opt,name=time_until_scheduled,json=timeUntilScheduled" json:"time_until_scheduled,omitempty"`
125 XXX_NoUnkeyedLiteral struct{} `json:"-"`
126 XXX_unrecognized []byte `json:"-"`
127 XXX_sizecache int32 `json:"-"`
128 }
129
130 func (m *IsEnabledResponse) Reset() { *m = IsEnabledResponse{} }
131 func (m *IsEnabledResponse) String() string { return proto.CompactTextString(m) }
132 func (*IsEnabledResponse) ProtoMessage() {}
133 func (*IsEnabledResponse) Descriptor() ([]byte, []int) {
134 return fileDescriptor_capability_service_030277ff00db7e72, []int{1}
135 }
136 func (m *IsEnabledResponse) XXX_Unmarshal(b []byte) error {
137 return xxx_messageInfo_IsEnabledResponse.Unmarshal(m, b)
138 }
139 func (m *IsEnabledResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
140 return xxx_messageInfo_IsEnabledResponse.Marshal(b, m, deterministic)
141 }
142 func (dst *IsEnabledResponse) XXX_Merge(src proto.Message) {
143 xxx_messageInfo_IsEnabledResponse.Merge(dst, src)
144 }
145 func (m *IsEnabledResponse) XXX_Size() int {
146 return xxx_messageInfo_IsEnabledResponse.Size(m)
147 }
148 func (m *IsEnabledResponse) XXX_DiscardUnknown() {
149 xxx_messageInfo_IsEnabledResponse.DiscardUnknown(m)
150 }
151
152 var xxx_messageInfo_IsEnabledResponse proto.InternalMessageInfo
153
154 func (m *IsEnabledResponse) GetSummaryStatus() IsEnabledResponse_SummaryStatus {
155 if m != nil && m.SummaryStatus != nil {
156 return *m.SummaryStatus
157 }
158 return IsEnabledResponse_DEFAULT
159 }
160
161 func (m *IsEnabledResponse) GetTimeUntilScheduled() int64 {
162 if m != nil && m.TimeUntilScheduled != nil {
163 return *m.TimeUntilScheduled
164 }
165 return 0
166 }
167
168 func init() {
169 proto.RegisterType((*IsEnabledRequest)(nil), "appengine.IsEnabledRequest")
170 proto.RegisterType((*IsEnabledResponse)(nil), "appengine.IsEnabledResponse")
171 }
172
173 func init() {
174 proto.RegisterFile("google.golang.org/appengine/v2/internal/capability/capability_service.proto", fileDescriptor_capability_service_030277ff00db7e72)
175 }
176
177 var fileDescriptor_capability_service_030277ff00db7e72 = []byte{
178 // 359 bytes of a gzipped FileDescriptorProto
179 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xd1, 0x8a, 0x9b, 0x40,
180 0x14, 0x86, 0xa3, 0xa6, 0xa4, 0x9e, 0x26, 0xc1, 0x0c, 0xb9, 0x90, 0xb6, 0x14, 0xf1, 0x4a, 0x7a,
181 0x61, 0x4a, 0xde, 0x20, 0x89, 0x86, 0x84, 0x06, 0x43, 0x35, 0x12, 0x28, 0x14, 0x3b, 0x31, 0x83,
182 0x95, 0x8e, 0xa3, 0xeb, 0x8c, 0x0b, 0x79, 0x82, 0x7d, 0xed, 0x45, 0x43, 0x8c, 0xcb, 0x2e, 0x7b,
183 0x77, 0xce, 0xf9, 0xf9, 0xfe, 0x99, 0x73, 0x7e, 0xd8, 0x24, 0x79, 0x9e, 0x50, 0x62, 0x27, 0x39,
184 0xc5, 0x2c, 0xb1, 0xf3, 0x32, 0x99, 0xe1, 0xa2, 0x20, 0x2c, 0x49, 0x19, 0x99, 0xa5, 0x4c, 0x90,
185 0x92, 0x61, 0x3a, 0x8b, 0x71, 0x81, 0x4f, 0x29, 0x4d, 0xc5, 0xa5, 0x53, 0x46, 0x9c, 0x94, 0x8f,
186 0x69, 0x4c, 0xec, 0xa2, 0xcc, 0x45, 0x8e, 0xd4, 0x96, 0x33, 0xff, 0x82, 0xb6, 0xe5, 0x2e, 0xc3,
187 0x27, 0x4a, 0xce, 0x3e, 0x79, 0xa8, 0x08, 0x17, 0x48, 0x87, 0x41, 0x81, 0xe3, 0xff, 0x38, 0x21,
188 0xba, 0x64, 0xc8, 0x96, 0xea, 0xdf, 0x5a, 0xf4, 0x0d, 0xe0, 0x6e, 0xaa, 0xcb, 0x86, 0x62, 0xa9,
189 0x7e, 0x67, 0x82, 0x10, 0xf4, 0x63, 0x4c, 0xa9, 0xae, 0x34, 0x4a, 0x53, 0x9b, 0x4f, 0x32, 0x4c,
190 0x3a, 0x4f, 0xf0, 0x22, 0x67, 0x9c, 0xa0, 0x5f, 0x30, 0xe6, 0x55, 0x96, 0xe1, 0xf2, 0x12, 0x71,
191 0x81, 0x45, 0xc5, 0x75, 0xc9, 0x90, 0xac, 0xf1, 0xfc, 0xbb, 0xdd, 0xfe, 0xcd, 0x7e, 0x45, 0xd9,
192 0xc1, 0x15, 0x09, 0x1a, 0xc2, 0x1f, 0xf1, 0x6e, 0x8b, 0x7e, 0xc0, 0x54, 0xa4, 0x19, 0x89, 0x2a,
193 0x26, 0x52, 0x1a, 0xf1, 0xf8, 0x1f, 0x39, 0x57, 0x94, 0x9c, 0x75, 0xd9, 0x90, 0x2c, 0xc5, 0x47,
194 0xb5, 0x16, 0xd6, 0x52, 0x70, 0x53, 0xcc, 0x0c, 0x46, 0x2f, 0x1c, 0xd1, 0x27, 0x18, 0x38, 0xee,
195 0x7a, 0x11, 0xee, 0x0e, 0x5a, 0xaf, 0x6e, 0x5c, 0x6f, 0xb1, 0xdc, 0xb9, 0x8e, 0x26, 0xa1, 0x29,
196 0x68, 0xc1, 0x6a, 0xe3, 0x3a, 0xe1, 0xce, 0x75, 0xa2, 0x75, 0x78, 0x08, 0x7d, 0x57, 0x93, 0xd1,
197 0x04, 0x46, 0xf7, 0xa9, 0xb7, 0x3f, 0x6a, 0x0a, 0x1a, 0xc2, 0x47, 0x67, 0x1b, 0x5c, 0xb1, 0x7e,
198 0xed, 0x11, 0x7a, 0x3f, 0xbd, 0xfd, 0xd1, 0xd3, 0x3e, 0xcc, 0xff, 0xc0, 0x64, 0xd5, 0xde, 0x2a,
199 0xb8, 0x26, 0x82, 0x36, 0xa0, 0xb6, 0x7b, 0xa2, 0x2f, 0x6f, 0x6f, 0xdf, 0xc4, 0xf2, 0xf9, 0xeb,
200 0x7b, 0xa7, 0x31, 0x7b, 0xcb, 0xe1, 0xef, 0x4e, 0x14, 0xcf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc0,
201 0x03, 0x26, 0x25, 0x2e, 0x02, 0x00, 0x00,
202 }
0 syntax = "proto2";
1 option go_package = "capability";
2
3 package appengine;
4
5 message IsEnabledRequest {
6 required string package = 1;
7 repeated string capability = 2;
8 repeated string call = 3;
9 }
10
11 message IsEnabledResponse {
12 enum SummaryStatus {
13 DEFAULT = 0;
14 ENABLED = 1;
15 SCHEDULED_FUTURE = 2;
16 SCHEDULED_NOW = 3;
17 DISABLED = 4;
18 UNKNOWN = 5;
19 }
20 optional SummaryStatus summary_status = 1;
21
22 optional int64 time_until_scheduled = 2;
23 }
24
25 service CapabilityService {
26 rpc IsEnabled(IsEnabledRequest) returns (IsEnabledResponse) {};
27 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/datastore/datastore_v3.proto
2
3 package datastore
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type Property_Meaning int32
21
22 const (
23 Property_NO_MEANING Property_Meaning = 0
24 Property_BLOB Property_Meaning = 14
25 Property_TEXT Property_Meaning = 15
26 Property_BYTESTRING Property_Meaning = 16
27 Property_ATOM_CATEGORY Property_Meaning = 1
28 Property_ATOM_LINK Property_Meaning = 2
29 Property_ATOM_TITLE Property_Meaning = 3
30 Property_ATOM_CONTENT Property_Meaning = 4
31 Property_ATOM_SUMMARY Property_Meaning = 5
32 Property_ATOM_AUTHOR Property_Meaning = 6
33 Property_GD_WHEN Property_Meaning = 7
34 Property_GD_EMAIL Property_Meaning = 8
35 Property_GEORSS_POINT Property_Meaning = 9
36 Property_GD_IM Property_Meaning = 10
37 Property_GD_PHONENUMBER Property_Meaning = 11
38 Property_GD_POSTALADDRESS Property_Meaning = 12
39 Property_GD_RATING Property_Meaning = 13
40 Property_BLOBKEY Property_Meaning = 17
41 Property_ENTITY_PROTO Property_Meaning = 19
42 Property_INDEX_VALUE Property_Meaning = 18
43 )
44
45 var Property_Meaning_name = map[int32]string{
46 0: "NO_MEANING",
47 14: "BLOB",
48 15: "TEXT",
49 16: "BYTESTRING",
50 1: "ATOM_CATEGORY",
51 2: "ATOM_LINK",
52 3: "ATOM_TITLE",
53 4: "ATOM_CONTENT",
54 5: "ATOM_SUMMARY",
55 6: "ATOM_AUTHOR",
56 7: "GD_WHEN",
57 8: "GD_EMAIL",
58 9: "GEORSS_POINT",
59 10: "GD_IM",
60 11: "GD_PHONENUMBER",
61 12: "GD_POSTALADDRESS",
62 13: "GD_RATING",
63 17: "BLOBKEY",
64 19: "ENTITY_PROTO",
65 18: "INDEX_VALUE",
66 }
67 var Property_Meaning_value = map[string]int32{
68 "NO_MEANING": 0,
69 "BLOB": 14,
70 "TEXT": 15,
71 "BYTESTRING": 16,
72 "ATOM_CATEGORY": 1,
73 "ATOM_LINK": 2,
74 "ATOM_TITLE": 3,
75 "ATOM_CONTENT": 4,
76 "ATOM_SUMMARY": 5,
77 "ATOM_AUTHOR": 6,
78 "GD_WHEN": 7,
79 "GD_EMAIL": 8,
80 "GEORSS_POINT": 9,
81 "GD_IM": 10,
82 "GD_PHONENUMBER": 11,
83 "GD_POSTALADDRESS": 12,
84 "GD_RATING": 13,
85 "BLOBKEY": 17,
86 "ENTITY_PROTO": 19,
87 "INDEX_VALUE": 18,
88 }
89
90 func (x Property_Meaning) Enum() *Property_Meaning {
91 p := new(Property_Meaning)
92 *p = x
93 return p
94 }
95 func (x Property_Meaning) String() string {
96 return proto.EnumName(Property_Meaning_name, int32(x))
97 }
98 func (x *Property_Meaning) UnmarshalJSON(data []byte) error {
99 value, err := proto.UnmarshalJSONEnum(Property_Meaning_value, data, "Property_Meaning")
100 if err != nil {
101 return err
102 }
103 *x = Property_Meaning(value)
104 return nil
105 }
106 func (Property_Meaning) EnumDescriptor() ([]byte, []int) {
107 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 0}
108 }
109
110 type Property_FtsTokenizationOption int32
111
112 const (
113 Property_HTML Property_FtsTokenizationOption = 1
114 Property_ATOM Property_FtsTokenizationOption = 2
115 )
116
117 var Property_FtsTokenizationOption_name = map[int32]string{
118 1: "HTML",
119 2: "ATOM",
120 }
121 var Property_FtsTokenizationOption_value = map[string]int32{
122 "HTML": 1,
123 "ATOM": 2,
124 }
125
126 func (x Property_FtsTokenizationOption) Enum() *Property_FtsTokenizationOption {
127 p := new(Property_FtsTokenizationOption)
128 *p = x
129 return p
130 }
131 func (x Property_FtsTokenizationOption) String() string {
132 return proto.EnumName(Property_FtsTokenizationOption_name, int32(x))
133 }
134 func (x *Property_FtsTokenizationOption) UnmarshalJSON(data []byte) error {
135 value, err := proto.UnmarshalJSONEnum(Property_FtsTokenizationOption_value, data, "Property_FtsTokenizationOption")
136 if err != nil {
137 return err
138 }
139 *x = Property_FtsTokenizationOption(value)
140 return nil
141 }
142 func (Property_FtsTokenizationOption) EnumDescriptor() ([]byte, []int) {
143 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2, 1}
144 }
145
146 type EntityProto_Kind int32
147
148 const (
149 EntityProto_GD_CONTACT EntityProto_Kind = 1
150 EntityProto_GD_EVENT EntityProto_Kind = 2
151 EntityProto_GD_MESSAGE EntityProto_Kind = 3
152 )
153
154 var EntityProto_Kind_name = map[int32]string{
155 1: "GD_CONTACT",
156 2: "GD_EVENT",
157 3: "GD_MESSAGE",
158 }
159 var EntityProto_Kind_value = map[string]int32{
160 "GD_CONTACT": 1,
161 "GD_EVENT": 2,
162 "GD_MESSAGE": 3,
163 }
164
165 func (x EntityProto_Kind) Enum() *EntityProto_Kind {
166 p := new(EntityProto_Kind)
167 *p = x
168 return p
169 }
170 func (x EntityProto_Kind) String() string {
171 return proto.EnumName(EntityProto_Kind_name, int32(x))
172 }
173 func (x *EntityProto_Kind) UnmarshalJSON(data []byte) error {
174 value, err := proto.UnmarshalJSONEnum(EntityProto_Kind_value, data, "EntityProto_Kind")
175 if err != nil {
176 return err
177 }
178 *x = EntityProto_Kind(value)
179 return nil
180 }
181 func (EntityProto_Kind) EnumDescriptor() ([]byte, []int) {
182 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6, 0}
183 }
184
185 type Index_Property_Direction int32
186
187 const (
188 Index_Property_ASCENDING Index_Property_Direction = 1
189 Index_Property_DESCENDING Index_Property_Direction = 2
190 )
191
192 var Index_Property_Direction_name = map[int32]string{
193 1: "ASCENDING",
194 2: "DESCENDING",
195 }
196 var Index_Property_Direction_value = map[string]int32{
197 "ASCENDING": 1,
198 "DESCENDING": 2,
199 }
200
201 func (x Index_Property_Direction) Enum() *Index_Property_Direction {
202 p := new(Index_Property_Direction)
203 *p = x
204 return p
205 }
206 func (x Index_Property_Direction) String() string {
207 return proto.EnumName(Index_Property_Direction_name, int32(x))
208 }
209 func (x *Index_Property_Direction) UnmarshalJSON(data []byte) error {
210 value, err := proto.UnmarshalJSONEnum(Index_Property_Direction_value, data, "Index_Property_Direction")
211 if err != nil {
212 return err
213 }
214 *x = Index_Property_Direction(value)
215 return nil
216 }
217 func (Index_Property_Direction) EnumDescriptor() ([]byte, []int) {
218 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0, 0}
219 }
220
221 type CompositeIndex_State int32
222
223 const (
224 CompositeIndex_WRITE_ONLY CompositeIndex_State = 1
225 CompositeIndex_READ_WRITE CompositeIndex_State = 2
226 CompositeIndex_DELETED CompositeIndex_State = 3
227 CompositeIndex_ERROR CompositeIndex_State = 4
228 )
229
230 var CompositeIndex_State_name = map[int32]string{
231 1: "WRITE_ONLY",
232 2: "READ_WRITE",
233 3: "DELETED",
234 4: "ERROR",
235 }
236 var CompositeIndex_State_value = map[string]int32{
237 "WRITE_ONLY": 1,
238 "READ_WRITE": 2,
239 "DELETED": 3,
240 "ERROR": 4,
241 }
242
243 func (x CompositeIndex_State) Enum() *CompositeIndex_State {
244 p := new(CompositeIndex_State)
245 *p = x
246 return p
247 }
248 func (x CompositeIndex_State) String() string {
249 return proto.EnumName(CompositeIndex_State_name, int32(x))
250 }
251 func (x *CompositeIndex_State) UnmarshalJSON(data []byte) error {
252 value, err := proto.UnmarshalJSONEnum(CompositeIndex_State_value, data, "CompositeIndex_State")
253 if err != nil {
254 return err
255 }
256 *x = CompositeIndex_State(value)
257 return nil
258 }
259 func (CompositeIndex_State) EnumDescriptor() ([]byte, []int) {
260 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9, 0}
261 }
262
263 type Snapshot_Status int32
264
265 const (
266 Snapshot_INACTIVE Snapshot_Status = 0
267 Snapshot_ACTIVE Snapshot_Status = 1
268 )
269
270 var Snapshot_Status_name = map[int32]string{
271 0: "INACTIVE",
272 1: "ACTIVE",
273 }
274 var Snapshot_Status_value = map[string]int32{
275 "INACTIVE": 0,
276 "ACTIVE": 1,
277 }
278
279 func (x Snapshot_Status) Enum() *Snapshot_Status {
280 p := new(Snapshot_Status)
281 *p = x
282 return p
283 }
284 func (x Snapshot_Status) String() string {
285 return proto.EnumName(Snapshot_Status_name, int32(x))
286 }
287 func (x *Snapshot_Status) UnmarshalJSON(data []byte) error {
288 value, err := proto.UnmarshalJSONEnum(Snapshot_Status_value, data, "Snapshot_Status")
289 if err != nil {
290 return err
291 }
292 *x = Snapshot_Status(value)
293 return nil
294 }
295 func (Snapshot_Status) EnumDescriptor() ([]byte, []int) {
296 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12, 0}
297 }
298
299 type Query_Hint int32
300
301 const (
302 Query_ORDER_FIRST Query_Hint = 1
303 Query_ANCESTOR_FIRST Query_Hint = 2
304 Query_FILTER_FIRST Query_Hint = 3
305 )
306
307 var Query_Hint_name = map[int32]string{
308 1: "ORDER_FIRST",
309 2: "ANCESTOR_FIRST",
310 3: "FILTER_FIRST",
311 }
312 var Query_Hint_value = map[string]int32{
313 "ORDER_FIRST": 1,
314 "ANCESTOR_FIRST": 2,
315 "FILTER_FIRST": 3,
316 }
317
318 func (x Query_Hint) Enum() *Query_Hint {
319 p := new(Query_Hint)
320 *p = x
321 return p
322 }
323 func (x Query_Hint) String() string {
324 return proto.EnumName(Query_Hint_name, int32(x))
325 }
326 func (x *Query_Hint) UnmarshalJSON(data []byte) error {
327 value, err := proto.UnmarshalJSONEnum(Query_Hint_value, data, "Query_Hint")
328 if err != nil {
329 return err
330 }
331 *x = Query_Hint(value)
332 return nil
333 }
334 func (Query_Hint) EnumDescriptor() ([]byte, []int) {
335 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0}
336 }
337
338 type Query_Filter_Operator int32
339
340 const (
341 Query_Filter_LESS_THAN Query_Filter_Operator = 1
342 Query_Filter_LESS_THAN_OR_EQUAL Query_Filter_Operator = 2
343 Query_Filter_GREATER_THAN Query_Filter_Operator = 3
344 Query_Filter_GREATER_THAN_OR_EQUAL Query_Filter_Operator = 4
345 Query_Filter_EQUAL Query_Filter_Operator = 5
346 Query_Filter_IN Query_Filter_Operator = 6
347 Query_Filter_EXISTS Query_Filter_Operator = 7
348 )
349
350 var Query_Filter_Operator_name = map[int32]string{
351 1: "LESS_THAN",
352 2: "LESS_THAN_OR_EQUAL",
353 3: "GREATER_THAN",
354 4: "GREATER_THAN_OR_EQUAL",
355 5: "EQUAL",
356 6: "IN",
357 7: "EXISTS",
358 }
359 var Query_Filter_Operator_value = map[string]int32{
360 "LESS_THAN": 1,
361 "LESS_THAN_OR_EQUAL": 2,
362 "GREATER_THAN": 3,
363 "GREATER_THAN_OR_EQUAL": 4,
364 "EQUAL": 5,
365 "IN": 6,
366 "EXISTS": 7,
367 }
368
369 func (x Query_Filter_Operator) Enum() *Query_Filter_Operator {
370 p := new(Query_Filter_Operator)
371 *p = x
372 return p
373 }
374 func (x Query_Filter_Operator) String() string {
375 return proto.EnumName(Query_Filter_Operator_name, int32(x))
376 }
377 func (x *Query_Filter_Operator) UnmarshalJSON(data []byte) error {
378 value, err := proto.UnmarshalJSONEnum(Query_Filter_Operator_value, data, "Query_Filter_Operator")
379 if err != nil {
380 return err
381 }
382 *x = Query_Filter_Operator(value)
383 return nil
384 }
385 func (Query_Filter_Operator) EnumDescriptor() ([]byte, []int) {
386 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0, 0}
387 }
388
389 type Query_Order_Direction int32
390
391 const (
392 Query_Order_ASCENDING Query_Order_Direction = 1
393 Query_Order_DESCENDING Query_Order_Direction = 2
394 )
395
396 var Query_Order_Direction_name = map[int32]string{
397 1: "ASCENDING",
398 2: "DESCENDING",
399 }
400 var Query_Order_Direction_value = map[string]int32{
401 "ASCENDING": 1,
402 "DESCENDING": 2,
403 }
404
405 func (x Query_Order_Direction) Enum() *Query_Order_Direction {
406 p := new(Query_Order_Direction)
407 *p = x
408 return p
409 }
410 func (x Query_Order_Direction) String() string {
411 return proto.EnumName(Query_Order_Direction_name, int32(x))
412 }
413 func (x *Query_Order_Direction) UnmarshalJSON(data []byte) error {
414 value, err := proto.UnmarshalJSONEnum(Query_Order_Direction_value, data, "Query_Order_Direction")
415 if err != nil {
416 return err
417 }
418 *x = Query_Order_Direction(value)
419 return nil
420 }
421 func (Query_Order_Direction) EnumDescriptor() ([]byte, []int) {
422 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1, 0}
423 }
424
425 type Error_ErrorCode int32
426
427 const (
428 Error_BAD_REQUEST Error_ErrorCode = 1
429 Error_CONCURRENT_TRANSACTION Error_ErrorCode = 2
430 Error_INTERNAL_ERROR Error_ErrorCode = 3
431 Error_NEED_INDEX Error_ErrorCode = 4
432 Error_TIMEOUT Error_ErrorCode = 5
433 Error_PERMISSION_DENIED Error_ErrorCode = 6
434 Error_BIGTABLE_ERROR Error_ErrorCode = 7
435 Error_COMMITTED_BUT_STILL_APPLYING Error_ErrorCode = 8
436 Error_CAPABILITY_DISABLED Error_ErrorCode = 9
437 Error_TRY_ALTERNATE_BACKEND Error_ErrorCode = 10
438 Error_SAFE_TIME_TOO_OLD Error_ErrorCode = 11
439 )
440
441 var Error_ErrorCode_name = map[int32]string{
442 1: "BAD_REQUEST",
443 2: "CONCURRENT_TRANSACTION",
444 3: "INTERNAL_ERROR",
445 4: "NEED_INDEX",
446 5: "TIMEOUT",
447 6: "PERMISSION_DENIED",
448 7: "BIGTABLE_ERROR",
449 8: "COMMITTED_BUT_STILL_APPLYING",
450 9: "CAPABILITY_DISABLED",
451 10: "TRY_ALTERNATE_BACKEND",
452 11: "SAFE_TIME_TOO_OLD",
453 }
454 var Error_ErrorCode_value = map[string]int32{
455 "BAD_REQUEST": 1,
456 "CONCURRENT_TRANSACTION": 2,
457 "INTERNAL_ERROR": 3,
458 "NEED_INDEX": 4,
459 "TIMEOUT": 5,
460 "PERMISSION_DENIED": 6,
461 "BIGTABLE_ERROR": 7,
462 "COMMITTED_BUT_STILL_APPLYING": 8,
463 "CAPABILITY_DISABLED": 9,
464 "TRY_ALTERNATE_BACKEND": 10,
465 "SAFE_TIME_TOO_OLD": 11,
466 }
467
468 func (x Error_ErrorCode) Enum() *Error_ErrorCode {
469 p := new(Error_ErrorCode)
470 *p = x
471 return p
472 }
473 func (x Error_ErrorCode) String() string {
474 return proto.EnumName(Error_ErrorCode_name, int32(x))
475 }
476 func (x *Error_ErrorCode) UnmarshalJSON(data []byte) error {
477 value, err := proto.UnmarshalJSONEnum(Error_ErrorCode_value, data, "Error_ErrorCode")
478 if err != nil {
479 return err
480 }
481 *x = Error_ErrorCode(value)
482 return nil
483 }
484 func (Error_ErrorCode) EnumDescriptor() ([]byte, []int) {
485 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19, 0}
486 }
487
488 type PutRequest_AutoIdPolicy int32
489
490 const (
491 PutRequest_CURRENT PutRequest_AutoIdPolicy = 0
492 PutRequest_SEQUENTIAL PutRequest_AutoIdPolicy = 1
493 )
494
495 var PutRequest_AutoIdPolicy_name = map[int32]string{
496 0: "CURRENT",
497 1: "SEQUENTIAL",
498 }
499 var PutRequest_AutoIdPolicy_value = map[string]int32{
500 "CURRENT": 0,
501 "SEQUENTIAL": 1,
502 }
503
504 func (x PutRequest_AutoIdPolicy) Enum() *PutRequest_AutoIdPolicy {
505 p := new(PutRequest_AutoIdPolicy)
506 *p = x
507 return p
508 }
509 func (x PutRequest_AutoIdPolicy) String() string {
510 return proto.EnumName(PutRequest_AutoIdPolicy_name, int32(x))
511 }
512 func (x *PutRequest_AutoIdPolicy) UnmarshalJSON(data []byte) error {
513 value, err := proto.UnmarshalJSONEnum(PutRequest_AutoIdPolicy_value, data, "PutRequest_AutoIdPolicy")
514 if err != nil {
515 return err
516 }
517 *x = PutRequest_AutoIdPolicy(value)
518 return nil
519 }
520 func (PutRequest_AutoIdPolicy) EnumDescriptor() ([]byte, []int) {
521 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23, 0}
522 }
523
524 type BeginTransactionRequest_TransactionMode int32
525
526 const (
527 BeginTransactionRequest_UNKNOWN BeginTransactionRequest_TransactionMode = 0
528 BeginTransactionRequest_READ_ONLY BeginTransactionRequest_TransactionMode = 1
529 BeginTransactionRequest_READ_WRITE BeginTransactionRequest_TransactionMode = 2
530 )
531
532 var BeginTransactionRequest_TransactionMode_name = map[int32]string{
533 0: "UNKNOWN",
534 1: "READ_ONLY",
535 2: "READ_WRITE",
536 }
537 var BeginTransactionRequest_TransactionMode_value = map[string]int32{
538 "UNKNOWN": 0,
539 "READ_ONLY": 1,
540 "READ_WRITE": 2,
541 }
542
543 func (x BeginTransactionRequest_TransactionMode) Enum() *BeginTransactionRequest_TransactionMode {
544 p := new(BeginTransactionRequest_TransactionMode)
545 *p = x
546 return p
547 }
548 func (x BeginTransactionRequest_TransactionMode) String() string {
549 return proto.EnumName(BeginTransactionRequest_TransactionMode_name, int32(x))
550 }
551 func (x *BeginTransactionRequest_TransactionMode) UnmarshalJSON(data []byte) error {
552 value, err := proto.UnmarshalJSONEnum(BeginTransactionRequest_TransactionMode_value, data, "BeginTransactionRequest_TransactionMode")
553 if err != nil {
554 return err
555 }
556 *x = BeginTransactionRequest_TransactionMode(value)
557 return nil
558 }
559 func (BeginTransactionRequest_TransactionMode) EnumDescriptor() ([]byte, []int) {
560 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36, 0}
561 }
562
563 type Action struct {
564 XXX_NoUnkeyedLiteral struct{} `json:"-"`
565 XXX_unrecognized []byte `json:"-"`
566 XXX_sizecache int32 `json:"-"`
567 }
568
569 func (m *Action) Reset() { *m = Action{} }
570 func (m *Action) String() string { return proto.CompactTextString(m) }
571 func (*Action) ProtoMessage() {}
572 func (*Action) Descriptor() ([]byte, []int) {
573 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{0}
574 }
575 func (m *Action) XXX_Unmarshal(b []byte) error {
576 return xxx_messageInfo_Action.Unmarshal(m, b)
577 }
578 func (m *Action) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
579 return xxx_messageInfo_Action.Marshal(b, m, deterministic)
580 }
581 func (dst *Action) XXX_Merge(src proto.Message) {
582 xxx_messageInfo_Action.Merge(dst, src)
583 }
584 func (m *Action) XXX_Size() int {
585 return xxx_messageInfo_Action.Size(m)
586 }
587 func (m *Action) XXX_DiscardUnknown() {
588 xxx_messageInfo_Action.DiscardUnknown(m)
589 }
590
591 var xxx_messageInfo_Action proto.InternalMessageInfo
592
593 type PropertyValue struct {
594 Int64Value *int64 `protobuf:"varint,1,opt,name=int64Value" json:"int64Value,omitempty"`
595 BooleanValue *bool `protobuf:"varint,2,opt,name=booleanValue" json:"booleanValue,omitempty"`
596 StringValue *string `protobuf:"bytes,3,opt,name=stringValue" json:"stringValue,omitempty"`
597 DoubleValue *float64 `protobuf:"fixed64,4,opt,name=doubleValue" json:"doubleValue,omitempty"`
598 Pointvalue *PropertyValue_PointValue `protobuf:"group,5,opt,name=PointValue,json=pointvalue" json:"pointvalue,omitempty"`
599 Uservalue *PropertyValue_UserValue `protobuf:"group,8,opt,name=UserValue,json=uservalue" json:"uservalue,omitempty"`
600 Referencevalue *PropertyValue_ReferenceValue `protobuf:"group,12,opt,name=ReferenceValue,json=referencevalue" json:"referencevalue,omitempty"`
601 XXX_NoUnkeyedLiteral struct{} `json:"-"`
602 XXX_unrecognized []byte `json:"-"`
603 XXX_sizecache int32 `json:"-"`
604 }
605
606 func (m *PropertyValue) Reset() { *m = PropertyValue{} }
607 func (m *PropertyValue) String() string { return proto.CompactTextString(m) }
608 func (*PropertyValue) ProtoMessage() {}
609 func (*PropertyValue) Descriptor() ([]byte, []int) {
610 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1}
611 }
612 func (m *PropertyValue) XXX_Unmarshal(b []byte) error {
613 return xxx_messageInfo_PropertyValue.Unmarshal(m, b)
614 }
615 func (m *PropertyValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
616 return xxx_messageInfo_PropertyValue.Marshal(b, m, deterministic)
617 }
618 func (dst *PropertyValue) XXX_Merge(src proto.Message) {
619 xxx_messageInfo_PropertyValue.Merge(dst, src)
620 }
621 func (m *PropertyValue) XXX_Size() int {
622 return xxx_messageInfo_PropertyValue.Size(m)
623 }
624 func (m *PropertyValue) XXX_DiscardUnknown() {
625 xxx_messageInfo_PropertyValue.DiscardUnknown(m)
626 }
627
628 var xxx_messageInfo_PropertyValue proto.InternalMessageInfo
629
630 func (m *PropertyValue) GetInt64Value() int64 {
631 if m != nil && m.Int64Value != nil {
632 return *m.Int64Value
633 }
634 return 0
635 }
636
637 func (m *PropertyValue) GetBooleanValue() bool {
638 if m != nil && m.BooleanValue != nil {
639 return *m.BooleanValue
640 }
641 return false
642 }
643
644 func (m *PropertyValue) GetStringValue() string {
645 if m != nil && m.StringValue != nil {
646 return *m.StringValue
647 }
648 return ""
649 }
650
651 func (m *PropertyValue) GetDoubleValue() float64 {
652 if m != nil && m.DoubleValue != nil {
653 return *m.DoubleValue
654 }
655 return 0
656 }
657
658 func (m *PropertyValue) GetPointvalue() *PropertyValue_PointValue {
659 if m != nil {
660 return m.Pointvalue
661 }
662 return nil
663 }
664
665 func (m *PropertyValue) GetUservalue() *PropertyValue_UserValue {
666 if m != nil {
667 return m.Uservalue
668 }
669 return nil
670 }
671
672 func (m *PropertyValue) GetReferencevalue() *PropertyValue_ReferenceValue {
673 if m != nil {
674 return m.Referencevalue
675 }
676 return nil
677 }
678
679 type PropertyValue_PointValue struct {
680 X *float64 `protobuf:"fixed64,6,req,name=x" json:"x,omitempty"`
681 Y *float64 `protobuf:"fixed64,7,req,name=y" json:"y,omitempty"`
682 XXX_NoUnkeyedLiteral struct{} `json:"-"`
683 XXX_unrecognized []byte `json:"-"`
684 XXX_sizecache int32 `json:"-"`
685 }
686
687 func (m *PropertyValue_PointValue) Reset() { *m = PropertyValue_PointValue{} }
688 func (m *PropertyValue_PointValue) String() string { return proto.CompactTextString(m) }
689 func (*PropertyValue_PointValue) ProtoMessage() {}
690 func (*PropertyValue_PointValue) Descriptor() ([]byte, []int) {
691 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 0}
692 }
693 func (m *PropertyValue_PointValue) XXX_Unmarshal(b []byte) error {
694 return xxx_messageInfo_PropertyValue_PointValue.Unmarshal(m, b)
695 }
696 func (m *PropertyValue_PointValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
697 return xxx_messageInfo_PropertyValue_PointValue.Marshal(b, m, deterministic)
698 }
699 func (dst *PropertyValue_PointValue) XXX_Merge(src proto.Message) {
700 xxx_messageInfo_PropertyValue_PointValue.Merge(dst, src)
701 }
702 func (m *PropertyValue_PointValue) XXX_Size() int {
703 return xxx_messageInfo_PropertyValue_PointValue.Size(m)
704 }
705 func (m *PropertyValue_PointValue) XXX_DiscardUnknown() {
706 xxx_messageInfo_PropertyValue_PointValue.DiscardUnknown(m)
707 }
708
709 var xxx_messageInfo_PropertyValue_PointValue proto.InternalMessageInfo
710
711 func (m *PropertyValue_PointValue) GetX() float64 {
712 if m != nil && m.X != nil {
713 return *m.X
714 }
715 return 0
716 }
717
718 func (m *PropertyValue_PointValue) GetY() float64 {
719 if m != nil && m.Y != nil {
720 return *m.Y
721 }
722 return 0
723 }
724
725 type PropertyValue_UserValue struct {
726 Email *string `protobuf:"bytes,9,req,name=email" json:"email,omitempty"`
727 AuthDomain *string `protobuf:"bytes,10,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"`
728 Nickname *string `protobuf:"bytes,11,opt,name=nickname" json:"nickname,omitempty"`
729 FederatedIdentity *string `protobuf:"bytes,21,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"`
730 FederatedProvider *string `protobuf:"bytes,22,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"`
731 XXX_NoUnkeyedLiteral struct{} `json:"-"`
732 XXX_unrecognized []byte `json:"-"`
733 XXX_sizecache int32 `json:"-"`
734 }
735
736 func (m *PropertyValue_UserValue) Reset() { *m = PropertyValue_UserValue{} }
737 func (m *PropertyValue_UserValue) String() string { return proto.CompactTextString(m) }
738 func (*PropertyValue_UserValue) ProtoMessage() {}
739 func (*PropertyValue_UserValue) Descriptor() ([]byte, []int) {
740 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 1}
741 }
742 func (m *PropertyValue_UserValue) XXX_Unmarshal(b []byte) error {
743 return xxx_messageInfo_PropertyValue_UserValue.Unmarshal(m, b)
744 }
745 func (m *PropertyValue_UserValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
746 return xxx_messageInfo_PropertyValue_UserValue.Marshal(b, m, deterministic)
747 }
748 func (dst *PropertyValue_UserValue) XXX_Merge(src proto.Message) {
749 xxx_messageInfo_PropertyValue_UserValue.Merge(dst, src)
750 }
751 func (m *PropertyValue_UserValue) XXX_Size() int {
752 return xxx_messageInfo_PropertyValue_UserValue.Size(m)
753 }
754 func (m *PropertyValue_UserValue) XXX_DiscardUnknown() {
755 xxx_messageInfo_PropertyValue_UserValue.DiscardUnknown(m)
756 }
757
758 var xxx_messageInfo_PropertyValue_UserValue proto.InternalMessageInfo
759
760 func (m *PropertyValue_UserValue) GetEmail() string {
761 if m != nil && m.Email != nil {
762 return *m.Email
763 }
764 return ""
765 }
766
767 func (m *PropertyValue_UserValue) GetAuthDomain() string {
768 if m != nil && m.AuthDomain != nil {
769 return *m.AuthDomain
770 }
771 return ""
772 }
773
774 func (m *PropertyValue_UserValue) GetNickname() string {
775 if m != nil && m.Nickname != nil {
776 return *m.Nickname
777 }
778 return ""
779 }
780
781 func (m *PropertyValue_UserValue) GetFederatedIdentity() string {
782 if m != nil && m.FederatedIdentity != nil {
783 return *m.FederatedIdentity
784 }
785 return ""
786 }
787
788 func (m *PropertyValue_UserValue) GetFederatedProvider() string {
789 if m != nil && m.FederatedProvider != nil {
790 return *m.FederatedProvider
791 }
792 return ""
793 }
794
795 type PropertyValue_ReferenceValue struct {
796 App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"`
797 NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"`
798 Pathelement []*PropertyValue_ReferenceValue_PathElement `protobuf:"group,14,rep,name=PathElement,json=pathelement" json:"pathelement,omitempty"`
799 XXX_NoUnkeyedLiteral struct{} `json:"-"`
800 XXX_unrecognized []byte `json:"-"`
801 XXX_sizecache int32 `json:"-"`
802 }
803
804 func (m *PropertyValue_ReferenceValue) Reset() { *m = PropertyValue_ReferenceValue{} }
805 func (m *PropertyValue_ReferenceValue) String() string { return proto.CompactTextString(m) }
806 func (*PropertyValue_ReferenceValue) ProtoMessage() {}
807 func (*PropertyValue_ReferenceValue) Descriptor() ([]byte, []int) {
808 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2}
809 }
810 func (m *PropertyValue_ReferenceValue) XXX_Unmarshal(b []byte) error {
811 return xxx_messageInfo_PropertyValue_ReferenceValue.Unmarshal(m, b)
812 }
813 func (m *PropertyValue_ReferenceValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
814 return xxx_messageInfo_PropertyValue_ReferenceValue.Marshal(b, m, deterministic)
815 }
816 func (dst *PropertyValue_ReferenceValue) XXX_Merge(src proto.Message) {
817 xxx_messageInfo_PropertyValue_ReferenceValue.Merge(dst, src)
818 }
819 func (m *PropertyValue_ReferenceValue) XXX_Size() int {
820 return xxx_messageInfo_PropertyValue_ReferenceValue.Size(m)
821 }
822 func (m *PropertyValue_ReferenceValue) XXX_DiscardUnknown() {
823 xxx_messageInfo_PropertyValue_ReferenceValue.DiscardUnknown(m)
824 }
825
826 var xxx_messageInfo_PropertyValue_ReferenceValue proto.InternalMessageInfo
827
828 func (m *PropertyValue_ReferenceValue) GetApp() string {
829 if m != nil && m.App != nil {
830 return *m.App
831 }
832 return ""
833 }
834
835 func (m *PropertyValue_ReferenceValue) GetNameSpace() string {
836 if m != nil && m.NameSpace != nil {
837 return *m.NameSpace
838 }
839 return ""
840 }
841
842 func (m *PropertyValue_ReferenceValue) GetPathelement() []*PropertyValue_ReferenceValue_PathElement {
843 if m != nil {
844 return m.Pathelement
845 }
846 return nil
847 }
848
849 type PropertyValue_ReferenceValue_PathElement struct {
850 Type *string `protobuf:"bytes,15,req,name=type" json:"type,omitempty"`
851 Id *int64 `protobuf:"varint,16,opt,name=id" json:"id,omitempty"`
852 Name *string `protobuf:"bytes,17,opt,name=name" json:"name,omitempty"`
853 XXX_NoUnkeyedLiteral struct{} `json:"-"`
854 XXX_unrecognized []byte `json:"-"`
855 XXX_sizecache int32 `json:"-"`
856 }
857
858 func (m *PropertyValue_ReferenceValue_PathElement) Reset() {
859 *m = PropertyValue_ReferenceValue_PathElement{}
860 }
861 func (m *PropertyValue_ReferenceValue_PathElement) String() string { return proto.CompactTextString(m) }
862 func (*PropertyValue_ReferenceValue_PathElement) ProtoMessage() {}
863 func (*PropertyValue_ReferenceValue_PathElement) Descriptor() ([]byte, []int) {
864 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{1, 2, 0}
865 }
866 func (m *PropertyValue_ReferenceValue_PathElement) XXX_Unmarshal(b []byte) error {
867 return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Unmarshal(m, b)
868 }
869 func (m *PropertyValue_ReferenceValue_PathElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
870 return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Marshal(b, m, deterministic)
871 }
872 func (dst *PropertyValue_ReferenceValue_PathElement) XXX_Merge(src proto.Message) {
873 xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Merge(dst, src)
874 }
875 func (m *PropertyValue_ReferenceValue_PathElement) XXX_Size() int {
876 return xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.Size(m)
877 }
878 func (m *PropertyValue_ReferenceValue_PathElement) XXX_DiscardUnknown() {
879 xxx_messageInfo_PropertyValue_ReferenceValue_PathElement.DiscardUnknown(m)
880 }
881
882 var xxx_messageInfo_PropertyValue_ReferenceValue_PathElement proto.InternalMessageInfo
883
884 func (m *PropertyValue_ReferenceValue_PathElement) GetType() string {
885 if m != nil && m.Type != nil {
886 return *m.Type
887 }
888 return ""
889 }
890
891 func (m *PropertyValue_ReferenceValue_PathElement) GetId() int64 {
892 if m != nil && m.Id != nil {
893 return *m.Id
894 }
895 return 0
896 }
897
898 func (m *PropertyValue_ReferenceValue_PathElement) GetName() string {
899 if m != nil && m.Name != nil {
900 return *m.Name
901 }
902 return ""
903 }
904
905 type Property struct {
906 Meaning *Property_Meaning `protobuf:"varint,1,opt,name=meaning,enum=appengine.Property_Meaning,def=0" json:"meaning,omitempty"`
907 MeaningUri *string `protobuf:"bytes,2,opt,name=meaning_uri,json=meaningUri" json:"meaning_uri,omitempty"`
908 Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"`
909 Value *PropertyValue `protobuf:"bytes,5,req,name=value" json:"value,omitempty"`
910 Multiple *bool `protobuf:"varint,4,req,name=multiple" json:"multiple,omitempty"`
911 Searchable *bool `protobuf:"varint,6,opt,name=searchable,def=0" json:"searchable,omitempty"`
912 FtsTokenizationOption *Property_FtsTokenizationOption `protobuf:"varint,8,opt,name=fts_tokenization_option,json=ftsTokenizationOption,enum=appengine.Property_FtsTokenizationOption" json:"fts_tokenization_option,omitempty"`
913 Locale *string `protobuf:"bytes,9,opt,name=locale,def=en" json:"locale,omitempty"`
914 XXX_NoUnkeyedLiteral struct{} `json:"-"`
915 XXX_unrecognized []byte `json:"-"`
916 XXX_sizecache int32 `json:"-"`
917 }
918
919 func (m *Property) Reset() { *m = Property{} }
920 func (m *Property) String() string { return proto.CompactTextString(m) }
921 func (*Property) ProtoMessage() {}
922 func (*Property) Descriptor() ([]byte, []int) {
923 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{2}
924 }
925 func (m *Property) XXX_Unmarshal(b []byte) error {
926 return xxx_messageInfo_Property.Unmarshal(m, b)
927 }
928 func (m *Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
929 return xxx_messageInfo_Property.Marshal(b, m, deterministic)
930 }
931 func (dst *Property) XXX_Merge(src proto.Message) {
932 xxx_messageInfo_Property.Merge(dst, src)
933 }
934 func (m *Property) XXX_Size() int {
935 return xxx_messageInfo_Property.Size(m)
936 }
937 func (m *Property) XXX_DiscardUnknown() {
938 xxx_messageInfo_Property.DiscardUnknown(m)
939 }
940
941 var xxx_messageInfo_Property proto.InternalMessageInfo
942
943 const Default_Property_Meaning Property_Meaning = Property_NO_MEANING
944 const Default_Property_Searchable bool = false
945 const Default_Property_Locale string = "en"
946
947 func (m *Property) GetMeaning() Property_Meaning {
948 if m != nil && m.Meaning != nil {
949 return *m.Meaning
950 }
951 return Default_Property_Meaning
952 }
953
954 func (m *Property) GetMeaningUri() string {
955 if m != nil && m.MeaningUri != nil {
956 return *m.MeaningUri
957 }
958 return ""
959 }
960
961 func (m *Property) GetName() string {
962 if m != nil && m.Name != nil {
963 return *m.Name
964 }
965 return ""
966 }
967
968 func (m *Property) GetValue() *PropertyValue {
969 if m != nil {
970 return m.Value
971 }
972 return nil
973 }
974
975 func (m *Property) GetMultiple() bool {
976 if m != nil && m.Multiple != nil {
977 return *m.Multiple
978 }
979 return false
980 }
981
982 func (m *Property) GetSearchable() bool {
983 if m != nil && m.Searchable != nil {
984 return *m.Searchable
985 }
986 return Default_Property_Searchable
987 }
988
989 func (m *Property) GetFtsTokenizationOption() Property_FtsTokenizationOption {
990 if m != nil && m.FtsTokenizationOption != nil {
991 return *m.FtsTokenizationOption
992 }
993 return Property_HTML
994 }
995
996 func (m *Property) GetLocale() string {
997 if m != nil && m.Locale != nil {
998 return *m.Locale
999 }
1000 return Default_Property_Locale
1001 }
1002
1003 type Path struct {
1004 Element []*Path_Element `protobuf:"group,1,rep,name=Element,json=element" json:"element,omitempty"`
1005 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1006 XXX_unrecognized []byte `json:"-"`
1007 XXX_sizecache int32 `json:"-"`
1008 }
1009
1010 func (m *Path) Reset() { *m = Path{} }
1011 func (m *Path) String() string { return proto.CompactTextString(m) }
1012 func (*Path) ProtoMessage() {}
1013 func (*Path) Descriptor() ([]byte, []int) {
1014 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3}
1015 }
1016 func (m *Path) XXX_Unmarshal(b []byte) error {
1017 return xxx_messageInfo_Path.Unmarshal(m, b)
1018 }
1019 func (m *Path) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1020 return xxx_messageInfo_Path.Marshal(b, m, deterministic)
1021 }
1022 func (dst *Path) XXX_Merge(src proto.Message) {
1023 xxx_messageInfo_Path.Merge(dst, src)
1024 }
1025 func (m *Path) XXX_Size() int {
1026 return xxx_messageInfo_Path.Size(m)
1027 }
1028 func (m *Path) XXX_DiscardUnknown() {
1029 xxx_messageInfo_Path.DiscardUnknown(m)
1030 }
1031
1032 var xxx_messageInfo_Path proto.InternalMessageInfo
1033
1034 func (m *Path) GetElement() []*Path_Element {
1035 if m != nil {
1036 return m.Element
1037 }
1038 return nil
1039 }
1040
1041 type Path_Element struct {
1042 Type *string `protobuf:"bytes,2,req,name=type" json:"type,omitempty"`
1043 Id *int64 `protobuf:"varint,3,opt,name=id" json:"id,omitempty"`
1044 Name *string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"`
1045 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1046 XXX_unrecognized []byte `json:"-"`
1047 XXX_sizecache int32 `json:"-"`
1048 }
1049
1050 func (m *Path_Element) Reset() { *m = Path_Element{} }
1051 func (m *Path_Element) String() string { return proto.CompactTextString(m) }
1052 func (*Path_Element) ProtoMessage() {}
1053 func (*Path_Element) Descriptor() ([]byte, []int) {
1054 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{3, 0}
1055 }
1056 func (m *Path_Element) XXX_Unmarshal(b []byte) error {
1057 return xxx_messageInfo_Path_Element.Unmarshal(m, b)
1058 }
1059 func (m *Path_Element) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1060 return xxx_messageInfo_Path_Element.Marshal(b, m, deterministic)
1061 }
1062 func (dst *Path_Element) XXX_Merge(src proto.Message) {
1063 xxx_messageInfo_Path_Element.Merge(dst, src)
1064 }
1065 func (m *Path_Element) XXX_Size() int {
1066 return xxx_messageInfo_Path_Element.Size(m)
1067 }
1068 func (m *Path_Element) XXX_DiscardUnknown() {
1069 xxx_messageInfo_Path_Element.DiscardUnknown(m)
1070 }
1071
1072 var xxx_messageInfo_Path_Element proto.InternalMessageInfo
1073
1074 func (m *Path_Element) GetType() string {
1075 if m != nil && m.Type != nil {
1076 return *m.Type
1077 }
1078 return ""
1079 }
1080
1081 func (m *Path_Element) GetId() int64 {
1082 if m != nil && m.Id != nil {
1083 return *m.Id
1084 }
1085 return 0
1086 }
1087
1088 func (m *Path_Element) GetName() string {
1089 if m != nil && m.Name != nil {
1090 return *m.Name
1091 }
1092 return ""
1093 }
1094
1095 type Reference struct {
1096 App *string `protobuf:"bytes,13,req,name=app" json:"app,omitempty"`
1097 NameSpace *string `protobuf:"bytes,20,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"`
1098 Path *Path `protobuf:"bytes,14,req,name=path" json:"path,omitempty"`
1099 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1100 XXX_unrecognized []byte `json:"-"`
1101 XXX_sizecache int32 `json:"-"`
1102 }
1103
1104 func (m *Reference) Reset() { *m = Reference{} }
1105 func (m *Reference) String() string { return proto.CompactTextString(m) }
1106 func (*Reference) ProtoMessage() {}
1107 func (*Reference) Descriptor() ([]byte, []int) {
1108 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{4}
1109 }
1110 func (m *Reference) XXX_Unmarshal(b []byte) error {
1111 return xxx_messageInfo_Reference.Unmarshal(m, b)
1112 }
1113 func (m *Reference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1114 return xxx_messageInfo_Reference.Marshal(b, m, deterministic)
1115 }
1116 func (dst *Reference) XXX_Merge(src proto.Message) {
1117 xxx_messageInfo_Reference.Merge(dst, src)
1118 }
1119 func (m *Reference) XXX_Size() int {
1120 return xxx_messageInfo_Reference.Size(m)
1121 }
1122 func (m *Reference) XXX_DiscardUnknown() {
1123 xxx_messageInfo_Reference.DiscardUnknown(m)
1124 }
1125
1126 var xxx_messageInfo_Reference proto.InternalMessageInfo
1127
1128 func (m *Reference) GetApp() string {
1129 if m != nil && m.App != nil {
1130 return *m.App
1131 }
1132 return ""
1133 }
1134
1135 func (m *Reference) GetNameSpace() string {
1136 if m != nil && m.NameSpace != nil {
1137 return *m.NameSpace
1138 }
1139 return ""
1140 }
1141
1142 func (m *Reference) GetPath() *Path {
1143 if m != nil {
1144 return m.Path
1145 }
1146 return nil
1147 }
1148
1149 type User struct {
1150 Email *string `protobuf:"bytes,1,req,name=email" json:"email,omitempty"`
1151 AuthDomain *string `protobuf:"bytes,2,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"`
1152 Nickname *string `protobuf:"bytes,3,opt,name=nickname" json:"nickname,omitempty"`
1153 FederatedIdentity *string `protobuf:"bytes,6,opt,name=federated_identity,json=federatedIdentity" json:"federated_identity,omitempty"`
1154 FederatedProvider *string `protobuf:"bytes,7,opt,name=federated_provider,json=federatedProvider" json:"federated_provider,omitempty"`
1155 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1156 XXX_unrecognized []byte `json:"-"`
1157 XXX_sizecache int32 `json:"-"`
1158 }
1159
1160 func (m *User) Reset() { *m = User{} }
1161 func (m *User) String() string { return proto.CompactTextString(m) }
1162 func (*User) ProtoMessage() {}
1163 func (*User) Descriptor() ([]byte, []int) {
1164 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{5}
1165 }
1166 func (m *User) XXX_Unmarshal(b []byte) error {
1167 return xxx_messageInfo_User.Unmarshal(m, b)
1168 }
1169 func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1170 return xxx_messageInfo_User.Marshal(b, m, deterministic)
1171 }
1172 func (dst *User) XXX_Merge(src proto.Message) {
1173 xxx_messageInfo_User.Merge(dst, src)
1174 }
1175 func (m *User) XXX_Size() int {
1176 return xxx_messageInfo_User.Size(m)
1177 }
1178 func (m *User) XXX_DiscardUnknown() {
1179 xxx_messageInfo_User.DiscardUnknown(m)
1180 }
1181
1182 var xxx_messageInfo_User proto.InternalMessageInfo
1183
1184 func (m *User) GetEmail() string {
1185 if m != nil && m.Email != nil {
1186 return *m.Email
1187 }
1188 return ""
1189 }
1190
1191 func (m *User) GetAuthDomain() string {
1192 if m != nil && m.AuthDomain != nil {
1193 return *m.AuthDomain
1194 }
1195 return ""
1196 }
1197
1198 func (m *User) GetNickname() string {
1199 if m != nil && m.Nickname != nil {
1200 return *m.Nickname
1201 }
1202 return ""
1203 }
1204
1205 func (m *User) GetFederatedIdentity() string {
1206 if m != nil && m.FederatedIdentity != nil {
1207 return *m.FederatedIdentity
1208 }
1209 return ""
1210 }
1211
1212 func (m *User) GetFederatedProvider() string {
1213 if m != nil && m.FederatedProvider != nil {
1214 return *m.FederatedProvider
1215 }
1216 return ""
1217 }
1218
1219 type EntityProto struct {
1220 Key *Reference `protobuf:"bytes,13,req,name=key" json:"key,omitempty"`
1221 EntityGroup *Path `protobuf:"bytes,16,req,name=entity_group,json=entityGroup" json:"entity_group,omitempty"`
1222 Owner *User `protobuf:"bytes,17,opt,name=owner" json:"owner,omitempty"`
1223 Kind *EntityProto_Kind `protobuf:"varint,4,opt,name=kind,enum=appengine.EntityProto_Kind" json:"kind,omitempty"`
1224 KindUri *string `protobuf:"bytes,5,opt,name=kind_uri,json=kindUri" json:"kind_uri,omitempty"`
1225 Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"`
1226 RawProperty []*Property `protobuf:"bytes,15,rep,name=raw_property,json=rawProperty" json:"raw_property,omitempty"`
1227 Rank *int32 `protobuf:"varint,18,opt,name=rank" json:"rank,omitempty"`
1228 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1229 XXX_unrecognized []byte `json:"-"`
1230 XXX_sizecache int32 `json:"-"`
1231 }
1232
1233 func (m *EntityProto) Reset() { *m = EntityProto{} }
1234 func (m *EntityProto) String() string { return proto.CompactTextString(m) }
1235 func (*EntityProto) ProtoMessage() {}
1236 func (*EntityProto) Descriptor() ([]byte, []int) {
1237 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{6}
1238 }
1239 func (m *EntityProto) XXX_Unmarshal(b []byte) error {
1240 return xxx_messageInfo_EntityProto.Unmarshal(m, b)
1241 }
1242 func (m *EntityProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1243 return xxx_messageInfo_EntityProto.Marshal(b, m, deterministic)
1244 }
1245 func (dst *EntityProto) XXX_Merge(src proto.Message) {
1246 xxx_messageInfo_EntityProto.Merge(dst, src)
1247 }
1248 func (m *EntityProto) XXX_Size() int {
1249 return xxx_messageInfo_EntityProto.Size(m)
1250 }
1251 func (m *EntityProto) XXX_DiscardUnknown() {
1252 xxx_messageInfo_EntityProto.DiscardUnknown(m)
1253 }
1254
1255 var xxx_messageInfo_EntityProto proto.InternalMessageInfo
1256
1257 func (m *EntityProto) GetKey() *Reference {
1258 if m != nil {
1259 return m.Key
1260 }
1261 return nil
1262 }
1263
1264 func (m *EntityProto) GetEntityGroup() *Path {
1265 if m != nil {
1266 return m.EntityGroup
1267 }
1268 return nil
1269 }
1270
1271 func (m *EntityProto) GetOwner() *User {
1272 if m != nil {
1273 return m.Owner
1274 }
1275 return nil
1276 }
1277
1278 func (m *EntityProto) GetKind() EntityProto_Kind {
1279 if m != nil && m.Kind != nil {
1280 return *m.Kind
1281 }
1282 return EntityProto_GD_CONTACT
1283 }
1284
1285 func (m *EntityProto) GetKindUri() string {
1286 if m != nil && m.KindUri != nil {
1287 return *m.KindUri
1288 }
1289 return ""
1290 }
1291
1292 func (m *EntityProto) GetProperty() []*Property {
1293 if m != nil {
1294 return m.Property
1295 }
1296 return nil
1297 }
1298
1299 func (m *EntityProto) GetRawProperty() []*Property {
1300 if m != nil {
1301 return m.RawProperty
1302 }
1303 return nil
1304 }
1305
1306 func (m *EntityProto) GetRank() int32 {
1307 if m != nil && m.Rank != nil {
1308 return *m.Rank
1309 }
1310 return 0
1311 }
1312
1313 type CompositeProperty struct {
1314 IndexId *int64 `protobuf:"varint,1,req,name=index_id,json=indexId" json:"index_id,omitempty"`
1315 Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"`
1316 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1317 XXX_unrecognized []byte `json:"-"`
1318 XXX_sizecache int32 `json:"-"`
1319 }
1320
1321 func (m *CompositeProperty) Reset() { *m = CompositeProperty{} }
1322 func (m *CompositeProperty) String() string { return proto.CompactTextString(m) }
1323 func (*CompositeProperty) ProtoMessage() {}
1324 func (*CompositeProperty) Descriptor() ([]byte, []int) {
1325 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{7}
1326 }
1327 func (m *CompositeProperty) XXX_Unmarshal(b []byte) error {
1328 return xxx_messageInfo_CompositeProperty.Unmarshal(m, b)
1329 }
1330 func (m *CompositeProperty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1331 return xxx_messageInfo_CompositeProperty.Marshal(b, m, deterministic)
1332 }
1333 func (dst *CompositeProperty) XXX_Merge(src proto.Message) {
1334 xxx_messageInfo_CompositeProperty.Merge(dst, src)
1335 }
1336 func (m *CompositeProperty) XXX_Size() int {
1337 return xxx_messageInfo_CompositeProperty.Size(m)
1338 }
1339 func (m *CompositeProperty) XXX_DiscardUnknown() {
1340 xxx_messageInfo_CompositeProperty.DiscardUnknown(m)
1341 }
1342
1343 var xxx_messageInfo_CompositeProperty proto.InternalMessageInfo
1344
1345 func (m *CompositeProperty) GetIndexId() int64 {
1346 if m != nil && m.IndexId != nil {
1347 return *m.IndexId
1348 }
1349 return 0
1350 }
1351
1352 func (m *CompositeProperty) GetValue() []string {
1353 if m != nil {
1354 return m.Value
1355 }
1356 return nil
1357 }
1358
1359 type Index struct {
1360 EntityType *string `protobuf:"bytes,1,req,name=entity_type,json=entityType" json:"entity_type,omitempty"`
1361 Ancestor *bool `protobuf:"varint,5,req,name=ancestor" json:"ancestor,omitempty"`
1362 Property []*Index_Property `protobuf:"group,2,rep,name=Property,json=property" json:"property,omitempty"`
1363 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1364 XXX_unrecognized []byte `json:"-"`
1365 XXX_sizecache int32 `json:"-"`
1366 }
1367
1368 func (m *Index) Reset() { *m = Index{} }
1369 func (m *Index) String() string { return proto.CompactTextString(m) }
1370 func (*Index) ProtoMessage() {}
1371 func (*Index) Descriptor() ([]byte, []int) {
1372 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8}
1373 }
1374 func (m *Index) XXX_Unmarshal(b []byte) error {
1375 return xxx_messageInfo_Index.Unmarshal(m, b)
1376 }
1377 func (m *Index) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1378 return xxx_messageInfo_Index.Marshal(b, m, deterministic)
1379 }
1380 func (dst *Index) XXX_Merge(src proto.Message) {
1381 xxx_messageInfo_Index.Merge(dst, src)
1382 }
1383 func (m *Index) XXX_Size() int {
1384 return xxx_messageInfo_Index.Size(m)
1385 }
1386 func (m *Index) XXX_DiscardUnknown() {
1387 xxx_messageInfo_Index.DiscardUnknown(m)
1388 }
1389
1390 var xxx_messageInfo_Index proto.InternalMessageInfo
1391
1392 func (m *Index) GetEntityType() string {
1393 if m != nil && m.EntityType != nil {
1394 return *m.EntityType
1395 }
1396 return ""
1397 }
1398
1399 func (m *Index) GetAncestor() bool {
1400 if m != nil && m.Ancestor != nil {
1401 return *m.Ancestor
1402 }
1403 return false
1404 }
1405
1406 func (m *Index) GetProperty() []*Index_Property {
1407 if m != nil {
1408 return m.Property
1409 }
1410 return nil
1411 }
1412
1413 type Index_Property struct {
1414 Name *string `protobuf:"bytes,3,req,name=name" json:"name,omitempty"`
1415 Direction *Index_Property_Direction `protobuf:"varint,4,opt,name=direction,enum=appengine.Index_Property_Direction,def=1" json:"direction,omitempty"`
1416 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1417 XXX_unrecognized []byte `json:"-"`
1418 XXX_sizecache int32 `json:"-"`
1419 }
1420
1421 func (m *Index_Property) Reset() { *m = Index_Property{} }
1422 func (m *Index_Property) String() string { return proto.CompactTextString(m) }
1423 func (*Index_Property) ProtoMessage() {}
1424 func (*Index_Property) Descriptor() ([]byte, []int) {
1425 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{8, 0}
1426 }
1427 func (m *Index_Property) XXX_Unmarshal(b []byte) error {
1428 return xxx_messageInfo_Index_Property.Unmarshal(m, b)
1429 }
1430 func (m *Index_Property) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1431 return xxx_messageInfo_Index_Property.Marshal(b, m, deterministic)
1432 }
1433 func (dst *Index_Property) XXX_Merge(src proto.Message) {
1434 xxx_messageInfo_Index_Property.Merge(dst, src)
1435 }
1436 func (m *Index_Property) XXX_Size() int {
1437 return xxx_messageInfo_Index_Property.Size(m)
1438 }
1439 func (m *Index_Property) XXX_DiscardUnknown() {
1440 xxx_messageInfo_Index_Property.DiscardUnknown(m)
1441 }
1442
1443 var xxx_messageInfo_Index_Property proto.InternalMessageInfo
1444
1445 const Default_Index_Property_Direction Index_Property_Direction = Index_Property_ASCENDING
1446
1447 func (m *Index_Property) GetName() string {
1448 if m != nil && m.Name != nil {
1449 return *m.Name
1450 }
1451 return ""
1452 }
1453
1454 func (m *Index_Property) GetDirection() Index_Property_Direction {
1455 if m != nil && m.Direction != nil {
1456 return *m.Direction
1457 }
1458 return Default_Index_Property_Direction
1459 }
1460
1461 type CompositeIndex struct {
1462 AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
1463 Id *int64 `protobuf:"varint,2,req,name=id" json:"id,omitempty"`
1464 Definition *Index `protobuf:"bytes,3,req,name=definition" json:"definition,omitempty"`
1465 State *CompositeIndex_State `protobuf:"varint,4,req,name=state,enum=appengine.CompositeIndex_State" json:"state,omitempty"`
1466 OnlyUseIfRequired *bool `protobuf:"varint,6,opt,name=only_use_if_required,json=onlyUseIfRequired,def=0" json:"only_use_if_required,omitempty"`
1467 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1468 XXX_unrecognized []byte `json:"-"`
1469 XXX_sizecache int32 `json:"-"`
1470 }
1471
1472 func (m *CompositeIndex) Reset() { *m = CompositeIndex{} }
1473 func (m *CompositeIndex) String() string { return proto.CompactTextString(m) }
1474 func (*CompositeIndex) ProtoMessage() {}
1475 func (*CompositeIndex) Descriptor() ([]byte, []int) {
1476 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{9}
1477 }
1478 func (m *CompositeIndex) XXX_Unmarshal(b []byte) error {
1479 return xxx_messageInfo_CompositeIndex.Unmarshal(m, b)
1480 }
1481 func (m *CompositeIndex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1482 return xxx_messageInfo_CompositeIndex.Marshal(b, m, deterministic)
1483 }
1484 func (dst *CompositeIndex) XXX_Merge(src proto.Message) {
1485 xxx_messageInfo_CompositeIndex.Merge(dst, src)
1486 }
1487 func (m *CompositeIndex) XXX_Size() int {
1488 return xxx_messageInfo_CompositeIndex.Size(m)
1489 }
1490 func (m *CompositeIndex) XXX_DiscardUnknown() {
1491 xxx_messageInfo_CompositeIndex.DiscardUnknown(m)
1492 }
1493
1494 var xxx_messageInfo_CompositeIndex proto.InternalMessageInfo
1495
1496 const Default_CompositeIndex_OnlyUseIfRequired bool = false
1497
1498 func (m *CompositeIndex) GetAppId() string {
1499 if m != nil && m.AppId != nil {
1500 return *m.AppId
1501 }
1502 return ""
1503 }
1504
1505 func (m *CompositeIndex) GetId() int64 {
1506 if m != nil && m.Id != nil {
1507 return *m.Id
1508 }
1509 return 0
1510 }
1511
1512 func (m *CompositeIndex) GetDefinition() *Index {
1513 if m != nil {
1514 return m.Definition
1515 }
1516 return nil
1517 }
1518
1519 func (m *CompositeIndex) GetState() CompositeIndex_State {
1520 if m != nil && m.State != nil {
1521 return *m.State
1522 }
1523 return CompositeIndex_WRITE_ONLY
1524 }
1525
1526 func (m *CompositeIndex) GetOnlyUseIfRequired() bool {
1527 if m != nil && m.OnlyUseIfRequired != nil {
1528 return *m.OnlyUseIfRequired
1529 }
1530 return Default_CompositeIndex_OnlyUseIfRequired
1531 }
1532
1533 type IndexPostfix struct {
1534 IndexValue []*IndexPostfix_IndexValue `protobuf:"bytes,1,rep,name=index_value,json=indexValue" json:"index_value,omitempty"`
1535 Key *Reference `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"`
1536 Before *bool `protobuf:"varint,3,opt,name=before,def=1" json:"before,omitempty"`
1537 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1538 XXX_unrecognized []byte `json:"-"`
1539 XXX_sizecache int32 `json:"-"`
1540 }
1541
1542 func (m *IndexPostfix) Reset() { *m = IndexPostfix{} }
1543 func (m *IndexPostfix) String() string { return proto.CompactTextString(m) }
1544 func (*IndexPostfix) ProtoMessage() {}
1545 func (*IndexPostfix) Descriptor() ([]byte, []int) {
1546 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10}
1547 }
1548 func (m *IndexPostfix) XXX_Unmarshal(b []byte) error {
1549 return xxx_messageInfo_IndexPostfix.Unmarshal(m, b)
1550 }
1551 func (m *IndexPostfix) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1552 return xxx_messageInfo_IndexPostfix.Marshal(b, m, deterministic)
1553 }
1554 func (dst *IndexPostfix) XXX_Merge(src proto.Message) {
1555 xxx_messageInfo_IndexPostfix.Merge(dst, src)
1556 }
1557 func (m *IndexPostfix) XXX_Size() int {
1558 return xxx_messageInfo_IndexPostfix.Size(m)
1559 }
1560 func (m *IndexPostfix) XXX_DiscardUnknown() {
1561 xxx_messageInfo_IndexPostfix.DiscardUnknown(m)
1562 }
1563
1564 var xxx_messageInfo_IndexPostfix proto.InternalMessageInfo
1565
1566 const Default_IndexPostfix_Before bool = true
1567
1568 func (m *IndexPostfix) GetIndexValue() []*IndexPostfix_IndexValue {
1569 if m != nil {
1570 return m.IndexValue
1571 }
1572 return nil
1573 }
1574
1575 func (m *IndexPostfix) GetKey() *Reference {
1576 if m != nil {
1577 return m.Key
1578 }
1579 return nil
1580 }
1581
1582 func (m *IndexPostfix) GetBefore() bool {
1583 if m != nil && m.Before != nil {
1584 return *m.Before
1585 }
1586 return Default_IndexPostfix_Before
1587 }
1588
1589 type IndexPostfix_IndexValue struct {
1590 PropertyName *string `protobuf:"bytes,1,req,name=property_name,json=propertyName" json:"property_name,omitempty"`
1591 Value *PropertyValue `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
1592 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1593 XXX_unrecognized []byte `json:"-"`
1594 XXX_sizecache int32 `json:"-"`
1595 }
1596
1597 func (m *IndexPostfix_IndexValue) Reset() { *m = IndexPostfix_IndexValue{} }
1598 func (m *IndexPostfix_IndexValue) String() string { return proto.CompactTextString(m) }
1599 func (*IndexPostfix_IndexValue) ProtoMessage() {}
1600 func (*IndexPostfix_IndexValue) Descriptor() ([]byte, []int) {
1601 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{10, 0}
1602 }
1603 func (m *IndexPostfix_IndexValue) XXX_Unmarshal(b []byte) error {
1604 return xxx_messageInfo_IndexPostfix_IndexValue.Unmarshal(m, b)
1605 }
1606 func (m *IndexPostfix_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1607 return xxx_messageInfo_IndexPostfix_IndexValue.Marshal(b, m, deterministic)
1608 }
1609 func (dst *IndexPostfix_IndexValue) XXX_Merge(src proto.Message) {
1610 xxx_messageInfo_IndexPostfix_IndexValue.Merge(dst, src)
1611 }
1612 func (m *IndexPostfix_IndexValue) XXX_Size() int {
1613 return xxx_messageInfo_IndexPostfix_IndexValue.Size(m)
1614 }
1615 func (m *IndexPostfix_IndexValue) XXX_DiscardUnknown() {
1616 xxx_messageInfo_IndexPostfix_IndexValue.DiscardUnknown(m)
1617 }
1618
1619 var xxx_messageInfo_IndexPostfix_IndexValue proto.InternalMessageInfo
1620
1621 func (m *IndexPostfix_IndexValue) GetPropertyName() string {
1622 if m != nil && m.PropertyName != nil {
1623 return *m.PropertyName
1624 }
1625 return ""
1626 }
1627
1628 func (m *IndexPostfix_IndexValue) GetValue() *PropertyValue {
1629 if m != nil {
1630 return m.Value
1631 }
1632 return nil
1633 }
1634
1635 type IndexPosition struct {
1636 Key *string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"`
1637 Before *bool `protobuf:"varint,2,opt,name=before,def=1" json:"before,omitempty"`
1638 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1639 XXX_unrecognized []byte `json:"-"`
1640 XXX_sizecache int32 `json:"-"`
1641 }
1642
1643 func (m *IndexPosition) Reset() { *m = IndexPosition{} }
1644 func (m *IndexPosition) String() string { return proto.CompactTextString(m) }
1645 func (*IndexPosition) ProtoMessage() {}
1646 func (*IndexPosition) Descriptor() ([]byte, []int) {
1647 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{11}
1648 }
1649 func (m *IndexPosition) XXX_Unmarshal(b []byte) error {
1650 return xxx_messageInfo_IndexPosition.Unmarshal(m, b)
1651 }
1652 func (m *IndexPosition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1653 return xxx_messageInfo_IndexPosition.Marshal(b, m, deterministic)
1654 }
1655 func (dst *IndexPosition) XXX_Merge(src proto.Message) {
1656 xxx_messageInfo_IndexPosition.Merge(dst, src)
1657 }
1658 func (m *IndexPosition) XXX_Size() int {
1659 return xxx_messageInfo_IndexPosition.Size(m)
1660 }
1661 func (m *IndexPosition) XXX_DiscardUnknown() {
1662 xxx_messageInfo_IndexPosition.DiscardUnknown(m)
1663 }
1664
1665 var xxx_messageInfo_IndexPosition proto.InternalMessageInfo
1666
1667 const Default_IndexPosition_Before bool = true
1668
1669 func (m *IndexPosition) GetKey() string {
1670 if m != nil && m.Key != nil {
1671 return *m.Key
1672 }
1673 return ""
1674 }
1675
1676 func (m *IndexPosition) GetBefore() bool {
1677 if m != nil && m.Before != nil {
1678 return *m.Before
1679 }
1680 return Default_IndexPosition_Before
1681 }
1682
1683 type Snapshot struct {
1684 Ts *int64 `protobuf:"varint,1,req,name=ts" json:"ts,omitempty"`
1685 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1686 XXX_unrecognized []byte `json:"-"`
1687 XXX_sizecache int32 `json:"-"`
1688 }
1689
1690 func (m *Snapshot) Reset() { *m = Snapshot{} }
1691 func (m *Snapshot) String() string { return proto.CompactTextString(m) }
1692 func (*Snapshot) ProtoMessage() {}
1693 func (*Snapshot) Descriptor() ([]byte, []int) {
1694 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{12}
1695 }
1696 func (m *Snapshot) XXX_Unmarshal(b []byte) error {
1697 return xxx_messageInfo_Snapshot.Unmarshal(m, b)
1698 }
1699 func (m *Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1700 return xxx_messageInfo_Snapshot.Marshal(b, m, deterministic)
1701 }
1702 func (dst *Snapshot) XXX_Merge(src proto.Message) {
1703 xxx_messageInfo_Snapshot.Merge(dst, src)
1704 }
1705 func (m *Snapshot) XXX_Size() int {
1706 return xxx_messageInfo_Snapshot.Size(m)
1707 }
1708 func (m *Snapshot) XXX_DiscardUnknown() {
1709 xxx_messageInfo_Snapshot.DiscardUnknown(m)
1710 }
1711
1712 var xxx_messageInfo_Snapshot proto.InternalMessageInfo
1713
1714 func (m *Snapshot) GetTs() int64 {
1715 if m != nil && m.Ts != nil {
1716 return *m.Ts
1717 }
1718 return 0
1719 }
1720
1721 type InternalHeader struct {
1722 Qos *string `protobuf:"bytes,1,opt,name=qos" json:"qos,omitempty"`
1723 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1724 XXX_unrecognized []byte `json:"-"`
1725 XXX_sizecache int32 `json:"-"`
1726 }
1727
1728 func (m *InternalHeader) Reset() { *m = InternalHeader{} }
1729 func (m *InternalHeader) String() string { return proto.CompactTextString(m) }
1730 func (*InternalHeader) ProtoMessage() {}
1731 func (*InternalHeader) Descriptor() ([]byte, []int) {
1732 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{13}
1733 }
1734 func (m *InternalHeader) XXX_Unmarshal(b []byte) error {
1735 return xxx_messageInfo_InternalHeader.Unmarshal(m, b)
1736 }
1737 func (m *InternalHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1738 return xxx_messageInfo_InternalHeader.Marshal(b, m, deterministic)
1739 }
1740 func (dst *InternalHeader) XXX_Merge(src proto.Message) {
1741 xxx_messageInfo_InternalHeader.Merge(dst, src)
1742 }
1743 func (m *InternalHeader) XXX_Size() int {
1744 return xxx_messageInfo_InternalHeader.Size(m)
1745 }
1746 func (m *InternalHeader) XXX_DiscardUnknown() {
1747 xxx_messageInfo_InternalHeader.DiscardUnknown(m)
1748 }
1749
1750 var xxx_messageInfo_InternalHeader proto.InternalMessageInfo
1751
1752 func (m *InternalHeader) GetQos() string {
1753 if m != nil && m.Qos != nil {
1754 return *m.Qos
1755 }
1756 return ""
1757 }
1758
1759 type Transaction struct {
1760 Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"`
1761 Handle *uint64 `protobuf:"fixed64,1,req,name=handle" json:"handle,omitempty"`
1762 App *string `protobuf:"bytes,2,req,name=app" json:"app,omitempty"`
1763 MarkChanges *bool `protobuf:"varint,3,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"`
1764 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1765 XXX_unrecognized []byte `json:"-"`
1766 XXX_sizecache int32 `json:"-"`
1767 }
1768
1769 func (m *Transaction) Reset() { *m = Transaction{} }
1770 func (m *Transaction) String() string { return proto.CompactTextString(m) }
1771 func (*Transaction) ProtoMessage() {}
1772 func (*Transaction) Descriptor() ([]byte, []int) {
1773 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{14}
1774 }
1775 func (m *Transaction) XXX_Unmarshal(b []byte) error {
1776 return xxx_messageInfo_Transaction.Unmarshal(m, b)
1777 }
1778 func (m *Transaction) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1779 return xxx_messageInfo_Transaction.Marshal(b, m, deterministic)
1780 }
1781 func (dst *Transaction) XXX_Merge(src proto.Message) {
1782 xxx_messageInfo_Transaction.Merge(dst, src)
1783 }
1784 func (m *Transaction) XXX_Size() int {
1785 return xxx_messageInfo_Transaction.Size(m)
1786 }
1787 func (m *Transaction) XXX_DiscardUnknown() {
1788 xxx_messageInfo_Transaction.DiscardUnknown(m)
1789 }
1790
1791 var xxx_messageInfo_Transaction proto.InternalMessageInfo
1792
1793 const Default_Transaction_MarkChanges bool = false
1794
1795 func (m *Transaction) GetHeader() *InternalHeader {
1796 if m != nil {
1797 return m.Header
1798 }
1799 return nil
1800 }
1801
1802 func (m *Transaction) GetHandle() uint64 {
1803 if m != nil && m.Handle != nil {
1804 return *m.Handle
1805 }
1806 return 0
1807 }
1808
1809 func (m *Transaction) GetApp() string {
1810 if m != nil && m.App != nil {
1811 return *m.App
1812 }
1813 return ""
1814 }
1815
1816 func (m *Transaction) GetMarkChanges() bool {
1817 if m != nil && m.MarkChanges != nil {
1818 return *m.MarkChanges
1819 }
1820 return Default_Transaction_MarkChanges
1821 }
1822
1823 type Query struct {
1824 Header *InternalHeader `protobuf:"bytes,39,opt,name=header" json:"header,omitempty"`
1825 App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"`
1826 NameSpace *string `protobuf:"bytes,29,opt,name=name_space,json=nameSpace" json:"name_space,omitempty"`
1827 Kind *string `protobuf:"bytes,3,opt,name=kind" json:"kind,omitempty"`
1828 Ancestor *Reference `protobuf:"bytes,17,opt,name=ancestor" json:"ancestor,omitempty"`
1829 Filter []*Query_Filter `protobuf:"group,4,rep,name=Filter,json=filter" json:"filter,omitempty"`
1830 SearchQuery *string `protobuf:"bytes,8,opt,name=search_query,json=searchQuery" json:"search_query,omitempty"`
1831 Order []*Query_Order `protobuf:"group,9,rep,name=Order,json=order" json:"order,omitempty"`
1832 Hint *Query_Hint `protobuf:"varint,18,opt,name=hint,enum=appengine.Query_Hint" json:"hint,omitempty"`
1833 Count *int32 `protobuf:"varint,23,opt,name=count" json:"count,omitempty"`
1834 Offset *int32 `protobuf:"varint,12,opt,name=offset,def=0" json:"offset,omitempty"`
1835 Limit *int32 `protobuf:"varint,16,opt,name=limit" json:"limit,omitempty"`
1836 CompiledCursor *CompiledCursor `protobuf:"bytes,30,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"`
1837 EndCompiledCursor *CompiledCursor `protobuf:"bytes,31,opt,name=end_compiled_cursor,json=endCompiledCursor" json:"end_compiled_cursor,omitempty"`
1838 CompositeIndex []*CompositeIndex `protobuf:"bytes,19,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"`
1839 RequirePerfectPlan *bool `protobuf:"varint,20,opt,name=require_perfect_plan,json=requirePerfectPlan,def=0" json:"require_perfect_plan,omitempty"`
1840 KeysOnly *bool `protobuf:"varint,21,opt,name=keys_only,json=keysOnly,def=0" json:"keys_only,omitempty"`
1841 Transaction *Transaction `protobuf:"bytes,22,opt,name=transaction" json:"transaction,omitempty"`
1842 Compile *bool `protobuf:"varint,25,opt,name=compile,def=0" json:"compile,omitempty"`
1843 FailoverMs *int64 `protobuf:"varint,26,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"`
1844 Strong *bool `protobuf:"varint,32,opt,name=strong" json:"strong,omitempty"`
1845 PropertyName []string `protobuf:"bytes,33,rep,name=property_name,json=propertyName" json:"property_name,omitempty"`
1846 GroupByPropertyName []string `protobuf:"bytes,34,rep,name=group_by_property_name,json=groupByPropertyName" json:"group_by_property_name,omitempty"`
1847 Distinct *bool `protobuf:"varint,24,opt,name=distinct" json:"distinct,omitempty"`
1848 MinSafeTimeSeconds *int64 `protobuf:"varint,35,opt,name=min_safe_time_seconds,json=minSafeTimeSeconds" json:"min_safe_time_seconds,omitempty"`
1849 SafeReplicaName []string `protobuf:"bytes,36,rep,name=safe_replica_name,json=safeReplicaName" json:"safe_replica_name,omitempty"`
1850 PersistOffset *bool `protobuf:"varint,37,opt,name=persist_offset,json=persistOffset,def=0" json:"persist_offset,omitempty"`
1851 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1852 XXX_unrecognized []byte `json:"-"`
1853 XXX_sizecache int32 `json:"-"`
1854 }
1855
1856 func (m *Query) Reset() { *m = Query{} }
1857 func (m *Query) String() string { return proto.CompactTextString(m) }
1858 func (*Query) ProtoMessage() {}
1859 func (*Query) Descriptor() ([]byte, []int) {
1860 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15}
1861 }
1862 func (m *Query) XXX_Unmarshal(b []byte) error {
1863 return xxx_messageInfo_Query.Unmarshal(m, b)
1864 }
1865 func (m *Query) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1866 return xxx_messageInfo_Query.Marshal(b, m, deterministic)
1867 }
1868 func (dst *Query) XXX_Merge(src proto.Message) {
1869 xxx_messageInfo_Query.Merge(dst, src)
1870 }
1871 func (m *Query) XXX_Size() int {
1872 return xxx_messageInfo_Query.Size(m)
1873 }
1874 func (m *Query) XXX_DiscardUnknown() {
1875 xxx_messageInfo_Query.DiscardUnknown(m)
1876 }
1877
1878 var xxx_messageInfo_Query proto.InternalMessageInfo
1879
1880 const Default_Query_Offset int32 = 0
1881 const Default_Query_RequirePerfectPlan bool = false
1882 const Default_Query_KeysOnly bool = false
1883 const Default_Query_Compile bool = false
1884 const Default_Query_PersistOffset bool = false
1885
1886 func (m *Query) GetHeader() *InternalHeader {
1887 if m != nil {
1888 return m.Header
1889 }
1890 return nil
1891 }
1892
1893 func (m *Query) GetApp() string {
1894 if m != nil && m.App != nil {
1895 return *m.App
1896 }
1897 return ""
1898 }
1899
1900 func (m *Query) GetNameSpace() string {
1901 if m != nil && m.NameSpace != nil {
1902 return *m.NameSpace
1903 }
1904 return ""
1905 }
1906
1907 func (m *Query) GetKind() string {
1908 if m != nil && m.Kind != nil {
1909 return *m.Kind
1910 }
1911 return ""
1912 }
1913
1914 func (m *Query) GetAncestor() *Reference {
1915 if m != nil {
1916 return m.Ancestor
1917 }
1918 return nil
1919 }
1920
1921 func (m *Query) GetFilter() []*Query_Filter {
1922 if m != nil {
1923 return m.Filter
1924 }
1925 return nil
1926 }
1927
1928 func (m *Query) GetSearchQuery() string {
1929 if m != nil && m.SearchQuery != nil {
1930 return *m.SearchQuery
1931 }
1932 return ""
1933 }
1934
1935 func (m *Query) GetOrder() []*Query_Order {
1936 if m != nil {
1937 return m.Order
1938 }
1939 return nil
1940 }
1941
1942 func (m *Query) GetHint() Query_Hint {
1943 if m != nil && m.Hint != nil {
1944 return *m.Hint
1945 }
1946 return Query_ORDER_FIRST
1947 }
1948
1949 func (m *Query) GetCount() int32 {
1950 if m != nil && m.Count != nil {
1951 return *m.Count
1952 }
1953 return 0
1954 }
1955
1956 func (m *Query) GetOffset() int32 {
1957 if m != nil && m.Offset != nil {
1958 return *m.Offset
1959 }
1960 return Default_Query_Offset
1961 }
1962
1963 func (m *Query) GetLimit() int32 {
1964 if m != nil && m.Limit != nil {
1965 return *m.Limit
1966 }
1967 return 0
1968 }
1969
1970 func (m *Query) GetCompiledCursor() *CompiledCursor {
1971 if m != nil {
1972 return m.CompiledCursor
1973 }
1974 return nil
1975 }
1976
1977 func (m *Query) GetEndCompiledCursor() *CompiledCursor {
1978 if m != nil {
1979 return m.EndCompiledCursor
1980 }
1981 return nil
1982 }
1983
1984 func (m *Query) GetCompositeIndex() []*CompositeIndex {
1985 if m != nil {
1986 return m.CompositeIndex
1987 }
1988 return nil
1989 }
1990
1991 func (m *Query) GetRequirePerfectPlan() bool {
1992 if m != nil && m.RequirePerfectPlan != nil {
1993 return *m.RequirePerfectPlan
1994 }
1995 return Default_Query_RequirePerfectPlan
1996 }
1997
1998 func (m *Query) GetKeysOnly() bool {
1999 if m != nil && m.KeysOnly != nil {
2000 return *m.KeysOnly
2001 }
2002 return Default_Query_KeysOnly
2003 }
2004
2005 func (m *Query) GetTransaction() *Transaction {
2006 if m != nil {
2007 return m.Transaction
2008 }
2009 return nil
2010 }
2011
2012 func (m *Query) GetCompile() bool {
2013 if m != nil && m.Compile != nil {
2014 return *m.Compile
2015 }
2016 return Default_Query_Compile
2017 }
2018
2019 func (m *Query) GetFailoverMs() int64 {
2020 if m != nil && m.FailoverMs != nil {
2021 return *m.FailoverMs
2022 }
2023 return 0
2024 }
2025
2026 func (m *Query) GetStrong() bool {
2027 if m != nil && m.Strong != nil {
2028 return *m.Strong
2029 }
2030 return false
2031 }
2032
2033 func (m *Query) GetPropertyName() []string {
2034 if m != nil {
2035 return m.PropertyName
2036 }
2037 return nil
2038 }
2039
2040 func (m *Query) GetGroupByPropertyName() []string {
2041 if m != nil {
2042 return m.GroupByPropertyName
2043 }
2044 return nil
2045 }
2046
2047 func (m *Query) GetDistinct() bool {
2048 if m != nil && m.Distinct != nil {
2049 return *m.Distinct
2050 }
2051 return false
2052 }
2053
2054 func (m *Query) GetMinSafeTimeSeconds() int64 {
2055 if m != nil && m.MinSafeTimeSeconds != nil {
2056 return *m.MinSafeTimeSeconds
2057 }
2058 return 0
2059 }
2060
2061 func (m *Query) GetSafeReplicaName() []string {
2062 if m != nil {
2063 return m.SafeReplicaName
2064 }
2065 return nil
2066 }
2067
2068 func (m *Query) GetPersistOffset() bool {
2069 if m != nil && m.PersistOffset != nil {
2070 return *m.PersistOffset
2071 }
2072 return Default_Query_PersistOffset
2073 }
2074
2075 type Query_Filter struct {
2076 Op *Query_Filter_Operator `protobuf:"varint,6,req,name=op,enum=appengine.Query_Filter_Operator" json:"op,omitempty"`
2077 Property []*Property `protobuf:"bytes,14,rep,name=property" json:"property,omitempty"`
2078 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2079 XXX_unrecognized []byte `json:"-"`
2080 XXX_sizecache int32 `json:"-"`
2081 }
2082
2083 func (m *Query_Filter) Reset() { *m = Query_Filter{} }
2084 func (m *Query_Filter) String() string { return proto.CompactTextString(m) }
2085 func (*Query_Filter) ProtoMessage() {}
2086 func (*Query_Filter) Descriptor() ([]byte, []int) {
2087 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 0}
2088 }
2089 func (m *Query_Filter) XXX_Unmarshal(b []byte) error {
2090 return xxx_messageInfo_Query_Filter.Unmarshal(m, b)
2091 }
2092 func (m *Query_Filter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2093 return xxx_messageInfo_Query_Filter.Marshal(b, m, deterministic)
2094 }
2095 func (dst *Query_Filter) XXX_Merge(src proto.Message) {
2096 xxx_messageInfo_Query_Filter.Merge(dst, src)
2097 }
2098 func (m *Query_Filter) XXX_Size() int {
2099 return xxx_messageInfo_Query_Filter.Size(m)
2100 }
2101 func (m *Query_Filter) XXX_DiscardUnknown() {
2102 xxx_messageInfo_Query_Filter.DiscardUnknown(m)
2103 }
2104
2105 var xxx_messageInfo_Query_Filter proto.InternalMessageInfo
2106
2107 func (m *Query_Filter) GetOp() Query_Filter_Operator {
2108 if m != nil && m.Op != nil {
2109 return *m.Op
2110 }
2111 return Query_Filter_LESS_THAN
2112 }
2113
2114 func (m *Query_Filter) GetProperty() []*Property {
2115 if m != nil {
2116 return m.Property
2117 }
2118 return nil
2119 }
2120
2121 type Query_Order struct {
2122 Property *string `protobuf:"bytes,10,req,name=property" json:"property,omitempty"`
2123 Direction *Query_Order_Direction `protobuf:"varint,11,opt,name=direction,enum=appengine.Query_Order_Direction,def=1" json:"direction,omitempty"`
2124 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2125 XXX_unrecognized []byte `json:"-"`
2126 XXX_sizecache int32 `json:"-"`
2127 }
2128
2129 func (m *Query_Order) Reset() { *m = Query_Order{} }
2130 func (m *Query_Order) String() string { return proto.CompactTextString(m) }
2131 func (*Query_Order) ProtoMessage() {}
2132 func (*Query_Order) Descriptor() ([]byte, []int) {
2133 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{15, 1}
2134 }
2135 func (m *Query_Order) XXX_Unmarshal(b []byte) error {
2136 return xxx_messageInfo_Query_Order.Unmarshal(m, b)
2137 }
2138 func (m *Query_Order) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2139 return xxx_messageInfo_Query_Order.Marshal(b, m, deterministic)
2140 }
2141 func (dst *Query_Order) XXX_Merge(src proto.Message) {
2142 xxx_messageInfo_Query_Order.Merge(dst, src)
2143 }
2144 func (m *Query_Order) XXX_Size() int {
2145 return xxx_messageInfo_Query_Order.Size(m)
2146 }
2147 func (m *Query_Order) XXX_DiscardUnknown() {
2148 xxx_messageInfo_Query_Order.DiscardUnknown(m)
2149 }
2150
2151 var xxx_messageInfo_Query_Order proto.InternalMessageInfo
2152
2153 const Default_Query_Order_Direction Query_Order_Direction = Query_Order_ASCENDING
2154
2155 func (m *Query_Order) GetProperty() string {
2156 if m != nil && m.Property != nil {
2157 return *m.Property
2158 }
2159 return ""
2160 }
2161
2162 func (m *Query_Order) GetDirection() Query_Order_Direction {
2163 if m != nil && m.Direction != nil {
2164 return *m.Direction
2165 }
2166 return Default_Query_Order_Direction
2167 }
2168
2169 type CompiledQuery struct {
2170 Primaryscan *CompiledQuery_PrimaryScan `protobuf:"group,1,req,name=PrimaryScan,json=primaryscan" json:"primaryscan,omitempty"`
2171 Mergejoinscan []*CompiledQuery_MergeJoinScan `protobuf:"group,7,rep,name=MergeJoinScan,json=mergejoinscan" json:"mergejoinscan,omitempty"`
2172 IndexDef *Index `protobuf:"bytes,21,opt,name=index_def,json=indexDef" json:"index_def,omitempty"`
2173 Offset *int32 `protobuf:"varint,10,opt,name=offset,def=0" json:"offset,omitempty"`
2174 Limit *int32 `protobuf:"varint,11,opt,name=limit" json:"limit,omitempty"`
2175 KeysOnly *bool `protobuf:"varint,12,req,name=keys_only,json=keysOnly" json:"keys_only,omitempty"`
2176 PropertyName []string `protobuf:"bytes,24,rep,name=property_name,json=propertyName" json:"property_name,omitempty"`
2177 DistinctInfixSize *int32 `protobuf:"varint,25,opt,name=distinct_infix_size,json=distinctInfixSize" json:"distinct_infix_size,omitempty"`
2178 Entityfilter *CompiledQuery_EntityFilter `protobuf:"group,13,opt,name=EntityFilter,json=entityfilter" json:"entityfilter,omitempty"`
2179 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2180 XXX_unrecognized []byte `json:"-"`
2181 XXX_sizecache int32 `json:"-"`
2182 }
2183
2184 func (m *CompiledQuery) Reset() { *m = CompiledQuery{} }
2185 func (m *CompiledQuery) String() string { return proto.CompactTextString(m) }
2186 func (*CompiledQuery) ProtoMessage() {}
2187 func (*CompiledQuery) Descriptor() ([]byte, []int) {
2188 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16}
2189 }
2190 func (m *CompiledQuery) XXX_Unmarshal(b []byte) error {
2191 return xxx_messageInfo_CompiledQuery.Unmarshal(m, b)
2192 }
2193 func (m *CompiledQuery) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2194 return xxx_messageInfo_CompiledQuery.Marshal(b, m, deterministic)
2195 }
2196 func (dst *CompiledQuery) XXX_Merge(src proto.Message) {
2197 xxx_messageInfo_CompiledQuery.Merge(dst, src)
2198 }
2199 func (m *CompiledQuery) XXX_Size() int {
2200 return xxx_messageInfo_CompiledQuery.Size(m)
2201 }
2202 func (m *CompiledQuery) XXX_DiscardUnknown() {
2203 xxx_messageInfo_CompiledQuery.DiscardUnknown(m)
2204 }
2205
2206 var xxx_messageInfo_CompiledQuery proto.InternalMessageInfo
2207
2208 const Default_CompiledQuery_Offset int32 = 0
2209
2210 func (m *CompiledQuery) GetPrimaryscan() *CompiledQuery_PrimaryScan {
2211 if m != nil {
2212 return m.Primaryscan
2213 }
2214 return nil
2215 }
2216
2217 func (m *CompiledQuery) GetMergejoinscan() []*CompiledQuery_MergeJoinScan {
2218 if m != nil {
2219 return m.Mergejoinscan
2220 }
2221 return nil
2222 }
2223
2224 func (m *CompiledQuery) GetIndexDef() *Index {
2225 if m != nil {
2226 return m.IndexDef
2227 }
2228 return nil
2229 }
2230
2231 func (m *CompiledQuery) GetOffset() int32 {
2232 if m != nil && m.Offset != nil {
2233 return *m.Offset
2234 }
2235 return Default_CompiledQuery_Offset
2236 }
2237
2238 func (m *CompiledQuery) GetLimit() int32 {
2239 if m != nil && m.Limit != nil {
2240 return *m.Limit
2241 }
2242 return 0
2243 }
2244
2245 func (m *CompiledQuery) GetKeysOnly() bool {
2246 if m != nil && m.KeysOnly != nil {
2247 return *m.KeysOnly
2248 }
2249 return false
2250 }
2251
2252 func (m *CompiledQuery) GetPropertyName() []string {
2253 if m != nil {
2254 return m.PropertyName
2255 }
2256 return nil
2257 }
2258
2259 func (m *CompiledQuery) GetDistinctInfixSize() int32 {
2260 if m != nil && m.DistinctInfixSize != nil {
2261 return *m.DistinctInfixSize
2262 }
2263 return 0
2264 }
2265
2266 func (m *CompiledQuery) GetEntityfilter() *CompiledQuery_EntityFilter {
2267 if m != nil {
2268 return m.Entityfilter
2269 }
2270 return nil
2271 }
2272
2273 type CompiledQuery_PrimaryScan struct {
2274 IndexName *string `protobuf:"bytes,2,opt,name=index_name,json=indexName" json:"index_name,omitempty"`
2275 StartKey *string `protobuf:"bytes,3,opt,name=start_key,json=startKey" json:"start_key,omitempty"`
2276 StartInclusive *bool `protobuf:"varint,4,opt,name=start_inclusive,json=startInclusive" json:"start_inclusive,omitempty"`
2277 EndKey *string `protobuf:"bytes,5,opt,name=end_key,json=endKey" json:"end_key,omitempty"`
2278 EndInclusive *bool `protobuf:"varint,6,opt,name=end_inclusive,json=endInclusive" json:"end_inclusive,omitempty"`
2279 StartPostfixValue []string `protobuf:"bytes,22,rep,name=start_postfix_value,json=startPostfixValue" json:"start_postfix_value,omitempty"`
2280 EndPostfixValue []string `protobuf:"bytes,23,rep,name=end_postfix_value,json=endPostfixValue" json:"end_postfix_value,omitempty"`
2281 EndUnappliedLogTimestampUs *int64 `protobuf:"varint,19,opt,name=end_unapplied_log_timestamp_us,json=endUnappliedLogTimestampUs" json:"end_unapplied_log_timestamp_us,omitempty"`
2282 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2283 XXX_unrecognized []byte `json:"-"`
2284 XXX_sizecache int32 `json:"-"`
2285 }
2286
2287 func (m *CompiledQuery_PrimaryScan) Reset() { *m = CompiledQuery_PrimaryScan{} }
2288 func (m *CompiledQuery_PrimaryScan) String() string { return proto.CompactTextString(m) }
2289 func (*CompiledQuery_PrimaryScan) ProtoMessage() {}
2290 func (*CompiledQuery_PrimaryScan) Descriptor() ([]byte, []int) {
2291 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 0}
2292 }
2293 func (m *CompiledQuery_PrimaryScan) XXX_Unmarshal(b []byte) error {
2294 return xxx_messageInfo_CompiledQuery_PrimaryScan.Unmarshal(m, b)
2295 }
2296 func (m *CompiledQuery_PrimaryScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2297 return xxx_messageInfo_CompiledQuery_PrimaryScan.Marshal(b, m, deterministic)
2298 }
2299 func (dst *CompiledQuery_PrimaryScan) XXX_Merge(src proto.Message) {
2300 xxx_messageInfo_CompiledQuery_PrimaryScan.Merge(dst, src)
2301 }
2302 func (m *CompiledQuery_PrimaryScan) XXX_Size() int {
2303 return xxx_messageInfo_CompiledQuery_PrimaryScan.Size(m)
2304 }
2305 func (m *CompiledQuery_PrimaryScan) XXX_DiscardUnknown() {
2306 xxx_messageInfo_CompiledQuery_PrimaryScan.DiscardUnknown(m)
2307 }
2308
2309 var xxx_messageInfo_CompiledQuery_PrimaryScan proto.InternalMessageInfo
2310
2311 func (m *CompiledQuery_PrimaryScan) GetIndexName() string {
2312 if m != nil && m.IndexName != nil {
2313 return *m.IndexName
2314 }
2315 return ""
2316 }
2317
2318 func (m *CompiledQuery_PrimaryScan) GetStartKey() string {
2319 if m != nil && m.StartKey != nil {
2320 return *m.StartKey
2321 }
2322 return ""
2323 }
2324
2325 func (m *CompiledQuery_PrimaryScan) GetStartInclusive() bool {
2326 if m != nil && m.StartInclusive != nil {
2327 return *m.StartInclusive
2328 }
2329 return false
2330 }
2331
2332 func (m *CompiledQuery_PrimaryScan) GetEndKey() string {
2333 if m != nil && m.EndKey != nil {
2334 return *m.EndKey
2335 }
2336 return ""
2337 }
2338
2339 func (m *CompiledQuery_PrimaryScan) GetEndInclusive() bool {
2340 if m != nil && m.EndInclusive != nil {
2341 return *m.EndInclusive
2342 }
2343 return false
2344 }
2345
2346 func (m *CompiledQuery_PrimaryScan) GetStartPostfixValue() []string {
2347 if m != nil {
2348 return m.StartPostfixValue
2349 }
2350 return nil
2351 }
2352
2353 func (m *CompiledQuery_PrimaryScan) GetEndPostfixValue() []string {
2354 if m != nil {
2355 return m.EndPostfixValue
2356 }
2357 return nil
2358 }
2359
2360 func (m *CompiledQuery_PrimaryScan) GetEndUnappliedLogTimestampUs() int64 {
2361 if m != nil && m.EndUnappliedLogTimestampUs != nil {
2362 return *m.EndUnappliedLogTimestampUs
2363 }
2364 return 0
2365 }
2366
2367 type CompiledQuery_MergeJoinScan struct {
2368 IndexName *string `protobuf:"bytes,8,req,name=index_name,json=indexName" json:"index_name,omitempty"`
2369 PrefixValue []string `protobuf:"bytes,9,rep,name=prefix_value,json=prefixValue" json:"prefix_value,omitempty"`
2370 ValuePrefix *bool `protobuf:"varint,20,opt,name=value_prefix,json=valuePrefix,def=0" json:"value_prefix,omitempty"`
2371 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2372 XXX_unrecognized []byte `json:"-"`
2373 XXX_sizecache int32 `json:"-"`
2374 }
2375
2376 func (m *CompiledQuery_MergeJoinScan) Reset() { *m = CompiledQuery_MergeJoinScan{} }
2377 func (m *CompiledQuery_MergeJoinScan) String() string { return proto.CompactTextString(m) }
2378 func (*CompiledQuery_MergeJoinScan) ProtoMessage() {}
2379 func (*CompiledQuery_MergeJoinScan) Descriptor() ([]byte, []int) {
2380 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 1}
2381 }
2382 func (m *CompiledQuery_MergeJoinScan) XXX_Unmarshal(b []byte) error {
2383 return xxx_messageInfo_CompiledQuery_MergeJoinScan.Unmarshal(m, b)
2384 }
2385 func (m *CompiledQuery_MergeJoinScan) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2386 return xxx_messageInfo_CompiledQuery_MergeJoinScan.Marshal(b, m, deterministic)
2387 }
2388 func (dst *CompiledQuery_MergeJoinScan) XXX_Merge(src proto.Message) {
2389 xxx_messageInfo_CompiledQuery_MergeJoinScan.Merge(dst, src)
2390 }
2391 func (m *CompiledQuery_MergeJoinScan) XXX_Size() int {
2392 return xxx_messageInfo_CompiledQuery_MergeJoinScan.Size(m)
2393 }
2394 func (m *CompiledQuery_MergeJoinScan) XXX_DiscardUnknown() {
2395 xxx_messageInfo_CompiledQuery_MergeJoinScan.DiscardUnknown(m)
2396 }
2397
2398 var xxx_messageInfo_CompiledQuery_MergeJoinScan proto.InternalMessageInfo
2399
2400 const Default_CompiledQuery_MergeJoinScan_ValuePrefix bool = false
2401
2402 func (m *CompiledQuery_MergeJoinScan) GetIndexName() string {
2403 if m != nil && m.IndexName != nil {
2404 return *m.IndexName
2405 }
2406 return ""
2407 }
2408
2409 func (m *CompiledQuery_MergeJoinScan) GetPrefixValue() []string {
2410 if m != nil {
2411 return m.PrefixValue
2412 }
2413 return nil
2414 }
2415
2416 func (m *CompiledQuery_MergeJoinScan) GetValuePrefix() bool {
2417 if m != nil && m.ValuePrefix != nil {
2418 return *m.ValuePrefix
2419 }
2420 return Default_CompiledQuery_MergeJoinScan_ValuePrefix
2421 }
2422
2423 type CompiledQuery_EntityFilter struct {
2424 Distinct *bool `protobuf:"varint,14,opt,name=distinct,def=0" json:"distinct,omitempty"`
2425 Kind *string `protobuf:"bytes,17,opt,name=kind" json:"kind,omitempty"`
2426 Ancestor *Reference `protobuf:"bytes,18,opt,name=ancestor" json:"ancestor,omitempty"`
2427 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2428 XXX_unrecognized []byte `json:"-"`
2429 XXX_sizecache int32 `json:"-"`
2430 }
2431
2432 func (m *CompiledQuery_EntityFilter) Reset() { *m = CompiledQuery_EntityFilter{} }
2433 func (m *CompiledQuery_EntityFilter) String() string { return proto.CompactTextString(m) }
2434 func (*CompiledQuery_EntityFilter) ProtoMessage() {}
2435 func (*CompiledQuery_EntityFilter) Descriptor() ([]byte, []int) {
2436 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{16, 2}
2437 }
2438 func (m *CompiledQuery_EntityFilter) XXX_Unmarshal(b []byte) error {
2439 return xxx_messageInfo_CompiledQuery_EntityFilter.Unmarshal(m, b)
2440 }
2441 func (m *CompiledQuery_EntityFilter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2442 return xxx_messageInfo_CompiledQuery_EntityFilter.Marshal(b, m, deterministic)
2443 }
2444 func (dst *CompiledQuery_EntityFilter) XXX_Merge(src proto.Message) {
2445 xxx_messageInfo_CompiledQuery_EntityFilter.Merge(dst, src)
2446 }
2447 func (m *CompiledQuery_EntityFilter) XXX_Size() int {
2448 return xxx_messageInfo_CompiledQuery_EntityFilter.Size(m)
2449 }
2450 func (m *CompiledQuery_EntityFilter) XXX_DiscardUnknown() {
2451 xxx_messageInfo_CompiledQuery_EntityFilter.DiscardUnknown(m)
2452 }
2453
2454 var xxx_messageInfo_CompiledQuery_EntityFilter proto.InternalMessageInfo
2455
2456 const Default_CompiledQuery_EntityFilter_Distinct bool = false
2457
2458 func (m *CompiledQuery_EntityFilter) GetDistinct() bool {
2459 if m != nil && m.Distinct != nil {
2460 return *m.Distinct
2461 }
2462 return Default_CompiledQuery_EntityFilter_Distinct
2463 }
2464
2465 func (m *CompiledQuery_EntityFilter) GetKind() string {
2466 if m != nil && m.Kind != nil {
2467 return *m.Kind
2468 }
2469 return ""
2470 }
2471
2472 func (m *CompiledQuery_EntityFilter) GetAncestor() *Reference {
2473 if m != nil {
2474 return m.Ancestor
2475 }
2476 return nil
2477 }
2478
2479 type CompiledCursor struct {
2480 Position *CompiledCursor_Position `protobuf:"group,2,opt,name=Position,json=position" json:"position,omitempty"`
2481 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2482 XXX_unrecognized []byte `json:"-"`
2483 XXX_sizecache int32 `json:"-"`
2484 }
2485
2486 func (m *CompiledCursor) Reset() { *m = CompiledCursor{} }
2487 func (m *CompiledCursor) String() string { return proto.CompactTextString(m) }
2488 func (*CompiledCursor) ProtoMessage() {}
2489 func (*CompiledCursor) Descriptor() ([]byte, []int) {
2490 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17}
2491 }
2492 func (m *CompiledCursor) XXX_Unmarshal(b []byte) error {
2493 return xxx_messageInfo_CompiledCursor.Unmarshal(m, b)
2494 }
2495 func (m *CompiledCursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2496 return xxx_messageInfo_CompiledCursor.Marshal(b, m, deterministic)
2497 }
2498 func (dst *CompiledCursor) XXX_Merge(src proto.Message) {
2499 xxx_messageInfo_CompiledCursor.Merge(dst, src)
2500 }
2501 func (m *CompiledCursor) XXX_Size() int {
2502 return xxx_messageInfo_CompiledCursor.Size(m)
2503 }
2504 func (m *CompiledCursor) XXX_DiscardUnknown() {
2505 xxx_messageInfo_CompiledCursor.DiscardUnknown(m)
2506 }
2507
2508 var xxx_messageInfo_CompiledCursor proto.InternalMessageInfo
2509
2510 func (m *CompiledCursor) GetPosition() *CompiledCursor_Position {
2511 if m != nil {
2512 return m.Position
2513 }
2514 return nil
2515 }
2516
2517 type CompiledCursor_Position struct {
2518 StartKey *string `protobuf:"bytes,27,opt,name=start_key,json=startKey" json:"start_key,omitempty"`
2519 Indexvalue []*CompiledCursor_Position_IndexValue `protobuf:"group,29,rep,name=IndexValue,json=indexvalue" json:"indexvalue,omitempty"`
2520 Key *Reference `protobuf:"bytes,32,opt,name=key" json:"key,omitempty"`
2521 StartInclusive *bool `protobuf:"varint,28,opt,name=start_inclusive,json=startInclusive,def=1" json:"start_inclusive,omitempty"`
2522 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2523 XXX_unrecognized []byte `json:"-"`
2524 XXX_sizecache int32 `json:"-"`
2525 }
2526
2527 func (m *CompiledCursor_Position) Reset() { *m = CompiledCursor_Position{} }
2528 func (m *CompiledCursor_Position) String() string { return proto.CompactTextString(m) }
2529 func (*CompiledCursor_Position) ProtoMessage() {}
2530 func (*CompiledCursor_Position) Descriptor() ([]byte, []int) {
2531 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0}
2532 }
2533 func (m *CompiledCursor_Position) XXX_Unmarshal(b []byte) error {
2534 return xxx_messageInfo_CompiledCursor_Position.Unmarshal(m, b)
2535 }
2536 func (m *CompiledCursor_Position) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2537 return xxx_messageInfo_CompiledCursor_Position.Marshal(b, m, deterministic)
2538 }
2539 func (dst *CompiledCursor_Position) XXX_Merge(src proto.Message) {
2540 xxx_messageInfo_CompiledCursor_Position.Merge(dst, src)
2541 }
2542 func (m *CompiledCursor_Position) XXX_Size() int {
2543 return xxx_messageInfo_CompiledCursor_Position.Size(m)
2544 }
2545 func (m *CompiledCursor_Position) XXX_DiscardUnknown() {
2546 xxx_messageInfo_CompiledCursor_Position.DiscardUnknown(m)
2547 }
2548
2549 var xxx_messageInfo_CompiledCursor_Position proto.InternalMessageInfo
2550
2551 const Default_CompiledCursor_Position_StartInclusive bool = true
2552
2553 func (m *CompiledCursor_Position) GetStartKey() string {
2554 if m != nil && m.StartKey != nil {
2555 return *m.StartKey
2556 }
2557 return ""
2558 }
2559
2560 func (m *CompiledCursor_Position) GetIndexvalue() []*CompiledCursor_Position_IndexValue {
2561 if m != nil {
2562 return m.Indexvalue
2563 }
2564 return nil
2565 }
2566
2567 func (m *CompiledCursor_Position) GetKey() *Reference {
2568 if m != nil {
2569 return m.Key
2570 }
2571 return nil
2572 }
2573
2574 func (m *CompiledCursor_Position) GetStartInclusive() bool {
2575 if m != nil && m.StartInclusive != nil {
2576 return *m.StartInclusive
2577 }
2578 return Default_CompiledCursor_Position_StartInclusive
2579 }
2580
2581 type CompiledCursor_Position_IndexValue struct {
2582 Property *string `protobuf:"bytes,30,opt,name=property" json:"property,omitempty"`
2583 Value *PropertyValue `protobuf:"bytes,31,req,name=value" json:"value,omitempty"`
2584 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2585 XXX_unrecognized []byte `json:"-"`
2586 XXX_sizecache int32 `json:"-"`
2587 }
2588
2589 func (m *CompiledCursor_Position_IndexValue) Reset() { *m = CompiledCursor_Position_IndexValue{} }
2590 func (m *CompiledCursor_Position_IndexValue) String() string { return proto.CompactTextString(m) }
2591 func (*CompiledCursor_Position_IndexValue) ProtoMessage() {}
2592 func (*CompiledCursor_Position_IndexValue) Descriptor() ([]byte, []int) {
2593 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{17, 0, 0}
2594 }
2595 func (m *CompiledCursor_Position_IndexValue) XXX_Unmarshal(b []byte) error {
2596 return xxx_messageInfo_CompiledCursor_Position_IndexValue.Unmarshal(m, b)
2597 }
2598 func (m *CompiledCursor_Position_IndexValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2599 return xxx_messageInfo_CompiledCursor_Position_IndexValue.Marshal(b, m, deterministic)
2600 }
2601 func (dst *CompiledCursor_Position_IndexValue) XXX_Merge(src proto.Message) {
2602 xxx_messageInfo_CompiledCursor_Position_IndexValue.Merge(dst, src)
2603 }
2604 func (m *CompiledCursor_Position_IndexValue) XXX_Size() int {
2605 return xxx_messageInfo_CompiledCursor_Position_IndexValue.Size(m)
2606 }
2607 func (m *CompiledCursor_Position_IndexValue) XXX_DiscardUnknown() {
2608 xxx_messageInfo_CompiledCursor_Position_IndexValue.DiscardUnknown(m)
2609 }
2610
2611 var xxx_messageInfo_CompiledCursor_Position_IndexValue proto.InternalMessageInfo
2612
2613 func (m *CompiledCursor_Position_IndexValue) GetProperty() string {
2614 if m != nil && m.Property != nil {
2615 return *m.Property
2616 }
2617 return ""
2618 }
2619
2620 func (m *CompiledCursor_Position_IndexValue) GetValue() *PropertyValue {
2621 if m != nil {
2622 return m.Value
2623 }
2624 return nil
2625 }
2626
2627 type Cursor struct {
2628 Cursor *uint64 `protobuf:"fixed64,1,req,name=cursor" json:"cursor,omitempty"`
2629 App *string `protobuf:"bytes,2,opt,name=app" json:"app,omitempty"`
2630 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2631 XXX_unrecognized []byte `json:"-"`
2632 XXX_sizecache int32 `json:"-"`
2633 }
2634
2635 func (m *Cursor) Reset() { *m = Cursor{} }
2636 func (m *Cursor) String() string { return proto.CompactTextString(m) }
2637 func (*Cursor) ProtoMessage() {}
2638 func (*Cursor) Descriptor() ([]byte, []int) {
2639 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{18}
2640 }
2641 func (m *Cursor) XXX_Unmarshal(b []byte) error {
2642 return xxx_messageInfo_Cursor.Unmarshal(m, b)
2643 }
2644 func (m *Cursor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2645 return xxx_messageInfo_Cursor.Marshal(b, m, deterministic)
2646 }
2647 func (dst *Cursor) XXX_Merge(src proto.Message) {
2648 xxx_messageInfo_Cursor.Merge(dst, src)
2649 }
2650 func (m *Cursor) XXX_Size() int {
2651 return xxx_messageInfo_Cursor.Size(m)
2652 }
2653 func (m *Cursor) XXX_DiscardUnknown() {
2654 xxx_messageInfo_Cursor.DiscardUnknown(m)
2655 }
2656
2657 var xxx_messageInfo_Cursor proto.InternalMessageInfo
2658
2659 func (m *Cursor) GetCursor() uint64 {
2660 if m != nil && m.Cursor != nil {
2661 return *m.Cursor
2662 }
2663 return 0
2664 }
2665
2666 func (m *Cursor) GetApp() string {
2667 if m != nil && m.App != nil {
2668 return *m.App
2669 }
2670 return ""
2671 }
2672
2673 type Error struct {
2674 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2675 XXX_unrecognized []byte `json:"-"`
2676 XXX_sizecache int32 `json:"-"`
2677 }
2678
2679 func (m *Error) Reset() { *m = Error{} }
2680 func (m *Error) String() string { return proto.CompactTextString(m) }
2681 func (*Error) ProtoMessage() {}
2682 func (*Error) Descriptor() ([]byte, []int) {
2683 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{19}
2684 }
2685 func (m *Error) XXX_Unmarshal(b []byte) error {
2686 return xxx_messageInfo_Error.Unmarshal(m, b)
2687 }
2688 func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2689 return xxx_messageInfo_Error.Marshal(b, m, deterministic)
2690 }
2691 func (dst *Error) XXX_Merge(src proto.Message) {
2692 xxx_messageInfo_Error.Merge(dst, src)
2693 }
2694 func (m *Error) XXX_Size() int {
2695 return xxx_messageInfo_Error.Size(m)
2696 }
2697 func (m *Error) XXX_DiscardUnknown() {
2698 xxx_messageInfo_Error.DiscardUnknown(m)
2699 }
2700
2701 var xxx_messageInfo_Error proto.InternalMessageInfo
2702
2703 type Cost struct {
2704 IndexWrites *int32 `protobuf:"varint,1,opt,name=index_writes,json=indexWrites" json:"index_writes,omitempty"`
2705 IndexWriteBytes *int32 `protobuf:"varint,2,opt,name=index_write_bytes,json=indexWriteBytes" json:"index_write_bytes,omitempty"`
2706 EntityWrites *int32 `protobuf:"varint,3,opt,name=entity_writes,json=entityWrites" json:"entity_writes,omitempty"`
2707 EntityWriteBytes *int32 `protobuf:"varint,4,opt,name=entity_write_bytes,json=entityWriteBytes" json:"entity_write_bytes,omitempty"`
2708 Commitcost *Cost_CommitCost `protobuf:"group,5,opt,name=CommitCost,json=commitcost" json:"commitcost,omitempty"`
2709 ApproximateStorageDelta *int32 `protobuf:"varint,8,opt,name=approximate_storage_delta,json=approximateStorageDelta" json:"approximate_storage_delta,omitempty"`
2710 IdSequenceUpdates *int32 `protobuf:"varint,9,opt,name=id_sequence_updates,json=idSequenceUpdates" json:"id_sequence_updates,omitempty"`
2711 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2712 XXX_unrecognized []byte `json:"-"`
2713 XXX_sizecache int32 `json:"-"`
2714 }
2715
2716 func (m *Cost) Reset() { *m = Cost{} }
2717 func (m *Cost) String() string { return proto.CompactTextString(m) }
2718 func (*Cost) ProtoMessage() {}
2719 func (*Cost) Descriptor() ([]byte, []int) {
2720 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20}
2721 }
2722 func (m *Cost) XXX_Unmarshal(b []byte) error {
2723 return xxx_messageInfo_Cost.Unmarshal(m, b)
2724 }
2725 func (m *Cost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2726 return xxx_messageInfo_Cost.Marshal(b, m, deterministic)
2727 }
2728 func (dst *Cost) XXX_Merge(src proto.Message) {
2729 xxx_messageInfo_Cost.Merge(dst, src)
2730 }
2731 func (m *Cost) XXX_Size() int {
2732 return xxx_messageInfo_Cost.Size(m)
2733 }
2734 func (m *Cost) XXX_DiscardUnknown() {
2735 xxx_messageInfo_Cost.DiscardUnknown(m)
2736 }
2737
2738 var xxx_messageInfo_Cost proto.InternalMessageInfo
2739
2740 func (m *Cost) GetIndexWrites() int32 {
2741 if m != nil && m.IndexWrites != nil {
2742 return *m.IndexWrites
2743 }
2744 return 0
2745 }
2746
2747 func (m *Cost) GetIndexWriteBytes() int32 {
2748 if m != nil && m.IndexWriteBytes != nil {
2749 return *m.IndexWriteBytes
2750 }
2751 return 0
2752 }
2753
2754 func (m *Cost) GetEntityWrites() int32 {
2755 if m != nil && m.EntityWrites != nil {
2756 return *m.EntityWrites
2757 }
2758 return 0
2759 }
2760
2761 func (m *Cost) GetEntityWriteBytes() int32 {
2762 if m != nil && m.EntityWriteBytes != nil {
2763 return *m.EntityWriteBytes
2764 }
2765 return 0
2766 }
2767
2768 func (m *Cost) GetCommitcost() *Cost_CommitCost {
2769 if m != nil {
2770 return m.Commitcost
2771 }
2772 return nil
2773 }
2774
2775 func (m *Cost) GetApproximateStorageDelta() int32 {
2776 if m != nil && m.ApproximateStorageDelta != nil {
2777 return *m.ApproximateStorageDelta
2778 }
2779 return 0
2780 }
2781
2782 func (m *Cost) GetIdSequenceUpdates() int32 {
2783 if m != nil && m.IdSequenceUpdates != nil {
2784 return *m.IdSequenceUpdates
2785 }
2786 return 0
2787 }
2788
2789 type Cost_CommitCost struct {
2790 RequestedEntityPuts *int32 `protobuf:"varint,6,opt,name=requested_entity_puts,json=requestedEntityPuts" json:"requested_entity_puts,omitempty"`
2791 RequestedEntityDeletes *int32 `protobuf:"varint,7,opt,name=requested_entity_deletes,json=requestedEntityDeletes" json:"requested_entity_deletes,omitempty"`
2792 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2793 XXX_unrecognized []byte `json:"-"`
2794 XXX_sizecache int32 `json:"-"`
2795 }
2796
2797 func (m *Cost_CommitCost) Reset() { *m = Cost_CommitCost{} }
2798 func (m *Cost_CommitCost) String() string { return proto.CompactTextString(m) }
2799 func (*Cost_CommitCost) ProtoMessage() {}
2800 func (*Cost_CommitCost) Descriptor() ([]byte, []int) {
2801 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{20, 0}
2802 }
2803 func (m *Cost_CommitCost) XXX_Unmarshal(b []byte) error {
2804 return xxx_messageInfo_Cost_CommitCost.Unmarshal(m, b)
2805 }
2806 func (m *Cost_CommitCost) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2807 return xxx_messageInfo_Cost_CommitCost.Marshal(b, m, deterministic)
2808 }
2809 func (dst *Cost_CommitCost) XXX_Merge(src proto.Message) {
2810 xxx_messageInfo_Cost_CommitCost.Merge(dst, src)
2811 }
2812 func (m *Cost_CommitCost) XXX_Size() int {
2813 return xxx_messageInfo_Cost_CommitCost.Size(m)
2814 }
2815 func (m *Cost_CommitCost) XXX_DiscardUnknown() {
2816 xxx_messageInfo_Cost_CommitCost.DiscardUnknown(m)
2817 }
2818
2819 var xxx_messageInfo_Cost_CommitCost proto.InternalMessageInfo
2820
2821 func (m *Cost_CommitCost) GetRequestedEntityPuts() int32 {
2822 if m != nil && m.RequestedEntityPuts != nil {
2823 return *m.RequestedEntityPuts
2824 }
2825 return 0
2826 }
2827
2828 func (m *Cost_CommitCost) GetRequestedEntityDeletes() int32 {
2829 if m != nil && m.RequestedEntityDeletes != nil {
2830 return *m.RequestedEntityDeletes
2831 }
2832 return 0
2833 }
2834
2835 type GetRequest struct {
2836 Header *InternalHeader `protobuf:"bytes,6,opt,name=header" json:"header,omitempty"`
2837 Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
2838 Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"`
2839 FailoverMs *int64 `protobuf:"varint,3,opt,name=failover_ms,json=failoverMs" json:"failover_ms,omitempty"`
2840 Strong *bool `protobuf:"varint,4,opt,name=strong" json:"strong,omitempty"`
2841 AllowDeferred *bool `protobuf:"varint,5,opt,name=allow_deferred,json=allowDeferred,def=0" json:"allow_deferred,omitempty"`
2842 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2843 XXX_unrecognized []byte `json:"-"`
2844 XXX_sizecache int32 `json:"-"`
2845 }
2846
2847 func (m *GetRequest) Reset() { *m = GetRequest{} }
2848 func (m *GetRequest) String() string { return proto.CompactTextString(m) }
2849 func (*GetRequest) ProtoMessage() {}
2850 func (*GetRequest) Descriptor() ([]byte, []int) {
2851 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{21}
2852 }
2853 func (m *GetRequest) XXX_Unmarshal(b []byte) error {
2854 return xxx_messageInfo_GetRequest.Unmarshal(m, b)
2855 }
2856 func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2857 return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic)
2858 }
2859 func (dst *GetRequest) XXX_Merge(src proto.Message) {
2860 xxx_messageInfo_GetRequest.Merge(dst, src)
2861 }
2862 func (m *GetRequest) XXX_Size() int {
2863 return xxx_messageInfo_GetRequest.Size(m)
2864 }
2865 func (m *GetRequest) XXX_DiscardUnknown() {
2866 xxx_messageInfo_GetRequest.DiscardUnknown(m)
2867 }
2868
2869 var xxx_messageInfo_GetRequest proto.InternalMessageInfo
2870
2871 const Default_GetRequest_AllowDeferred bool = false
2872
2873 func (m *GetRequest) GetHeader() *InternalHeader {
2874 if m != nil {
2875 return m.Header
2876 }
2877 return nil
2878 }
2879
2880 func (m *GetRequest) GetKey() []*Reference {
2881 if m != nil {
2882 return m.Key
2883 }
2884 return nil
2885 }
2886
2887 func (m *GetRequest) GetTransaction() *Transaction {
2888 if m != nil {
2889 return m.Transaction
2890 }
2891 return nil
2892 }
2893
2894 func (m *GetRequest) GetFailoverMs() int64 {
2895 if m != nil && m.FailoverMs != nil {
2896 return *m.FailoverMs
2897 }
2898 return 0
2899 }
2900
2901 func (m *GetRequest) GetStrong() bool {
2902 if m != nil && m.Strong != nil {
2903 return *m.Strong
2904 }
2905 return false
2906 }
2907
2908 func (m *GetRequest) GetAllowDeferred() bool {
2909 if m != nil && m.AllowDeferred != nil {
2910 return *m.AllowDeferred
2911 }
2912 return Default_GetRequest_AllowDeferred
2913 }
2914
2915 type GetResponse struct {
2916 Entity []*GetResponse_Entity `protobuf:"group,1,rep,name=Entity,json=entity" json:"entity,omitempty"`
2917 Deferred []*Reference `protobuf:"bytes,5,rep,name=deferred" json:"deferred,omitempty"`
2918 InOrder *bool `protobuf:"varint,6,opt,name=in_order,json=inOrder,def=1" json:"in_order,omitempty"`
2919 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2920 XXX_unrecognized []byte `json:"-"`
2921 XXX_sizecache int32 `json:"-"`
2922 }
2923
2924 func (m *GetResponse) Reset() { *m = GetResponse{} }
2925 func (m *GetResponse) String() string { return proto.CompactTextString(m) }
2926 func (*GetResponse) ProtoMessage() {}
2927 func (*GetResponse) Descriptor() ([]byte, []int) {
2928 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22}
2929 }
2930 func (m *GetResponse) XXX_Unmarshal(b []byte) error {
2931 return xxx_messageInfo_GetResponse.Unmarshal(m, b)
2932 }
2933 func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2934 return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic)
2935 }
2936 func (dst *GetResponse) XXX_Merge(src proto.Message) {
2937 xxx_messageInfo_GetResponse.Merge(dst, src)
2938 }
2939 func (m *GetResponse) XXX_Size() int {
2940 return xxx_messageInfo_GetResponse.Size(m)
2941 }
2942 func (m *GetResponse) XXX_DiscardUnknown() {
2943 xxx_messageInfo_GetResponse.DiscardUnknown(m)
2944 }
2945
2946 var xxx_messageInfo_GetResponse proto.InternalMessageInfo
2947
2948 const Default_GetResponse_InOrder bool = true
2949
2950 func (m *GetResponse) GetEntity() []*GetResponse_Entity {
2951 if m != nil {
2952 return m.Entity
2953 }
2954 return nil
2955 }
2956
2957 func (m *GetResponse) GetDeferred() []*Reference {
2958 if m != nil {
2959 return m.Deferred
2960 }
2961 return nil
2962 }
2963
2964 func (m *GetResponse) GetInOrder() bool {
2965 if m != nil && m.InOrder != nil {
2966 return *m.InOrder
2967 }
2968 return Default_GetResponse_InOrder
2969 }
2970
2971 type GetResponse_Entity struct {
2972 Entity *EntityProto `protobuf:"bytes,2,opt,name=entity" json:"entity,omitempty"`
2973 Key *Reference `protobuf:"bytes,4,opt,name=key" json:"key,omitempty"`
2974 Version *int64 `protobuf:"varint,3,opt,name=version" json:"version,omitempty"`
2975 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2976 XXX_unrecognized []byte `json:"-"`
2977 XXX_sizecache int32 `json:"-"`
2978 }
2979
2980 func (m *GetResponse_Entity) Reset() { *m = GetResponse_Entity{} }
2981 func (m *GetResponse_Entity) String() string { return proto.CompactTextString(m) }
2982 func (*GetResponse_Entity) ProtoMessage() {}
2983 func (*GetResponse_Entity) Descriptor() ([]byte, []int) {
2984 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{22, 0}
2985 }
2986 func (m *GetResponse_Entity) XXX_Unmarshal(b []byte) error {
2987 return xxx_messageInfo_GetResponse_Entity.Unmarshal(m, b)
2988 }
2989 func (m *GetResponse_Entity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2990 return xxx_messageInfo_GetResponse_Entity.Marshal(b, m, deterministic)
2991 }
2992 func (dst *GetResponse_Entity) XXX_Merge(src proto.Message) {
2993 xxx_messageInfo_GetResponse_Entity.Merge(dst, src)
2994 }
2995 func (m *GetResponse_Entity) XXX_Size() int {
2996 return xxx_messageInfo_GetResponse_Entity.Size(m)
2997 }
2998 func (m *GetResponse_Entity) XXX_DiscardUnknown() {
2999 xxx_messageInfo_GetResponse_Entity.DiscardUnknown(m)
3000 }
3001
3002 var xxx_messageInfo_GetResponse_Entity proto.InternalMessageInfo
3003
3004 func (m *GetResponse_Entity) GetEntity() *EntityProto {
3005 if m != nil {
3006 return m.Entity
3007 }
3008 return nil
3009 }
3010
3011 func (m *GetResponse_Entity) GetKey() *Reference {
3012 if m != nil {
3013 return m.Key
3014 }
3015 return nil
3016 }
3017
3018 func (m *GetResponse_Entity) GetVersion() int64 {
3019 if m != nil && m.Version != nil {
3020 return *m.Version
3021 }
3022 return 0
3023 }
3024
3025 type PutRequest struct {
3026 Header *InternalHeader `protobuf:"bytes,11,opt,name=header" json:"header,omitempty"`
3027 Entity []*EntityProto `protobuf:"bytes,1,rep,name=entity" json:"entity,omitempty"`
3028 Transaction *Transaction `protobuf:"bytes,2,opt,name=transaction" json:"transaction,omitempty"`
3029 CompositeIndex []*CompositeIndex `protobuf:"bytes,3,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"`
3030 Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"`
3031 Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"`
3032 MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"`
3033 Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"`
3034 AutoIdPolicy *PutRequest_AutoIdPolicy `protobuf:"varint,10,opt,name=auto_id_policy,json=autoIdPolicy,enum=appengine.PutRequest_AutoIdPolicy,def=0" json:"auto_id_policy,omitempty"`
3035 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3036 XXX_unrecognized []byte `json:"-"`
3037 XXX_sizecache int32 `json:"-"`
3038 }
3039
3040 func (m *PutRequest) Reset() { *m = PutRequest{} }
3041 func (m *PutRequest) String() string { return proto.CompactTextString(m) }
3042 func (*PutRequest) ProtoMessage() {}
3043 func (*PutRequest) Descriptor() ([]byte, []int) {
3044 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{23}
3045 }
3046 func (m *PutRequest) XXX_Unmarshal(b []byte) error {
3047 return xxx_messageInfo_PutRequest.Unmarshal(m, b)
3048 }
3049 func (m *PutRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3050 return xxx_messageInfo_PutRequest.Marshal(b, m, deterministic)
3051 }
3052 func (dst *PutRequest) XXX_Merge(src proto.Message) {
3053 xxx_messageInfo_PutRequest.Merge(dst, src)
3054 }
3055 func (m *PutRequest) XXX_Size() int {
3056 return xxx_messageInfo_PutRequest.Size(m)
3057 }
3058 func (m *PutRequest) XXX_DiscardUnknown() {
3059 xxx_messageInfo_PutRequest.DiscardUnknown(m)
3060 }
3061
3062 var xxx_messageInfo_PutRequest proto.InternalMessageInfo
3063
3064 const Default_PutRequest_Trusted bool = false
3065 const Default_PutRequest_Force bool = false
3066 const Default_PutRequest_MarkChanges bool = false
3067 const Default_PutRequest_AutoIdPolicy PutRequest_AutoIdPolicy = PutRequest_CURRENT
3068
3069 func (m *PutRequest) GetHeader() *InternalHeader {
3070 if m != nil {
3071 return m.Header
3072 }
3073 return nil
3074 }
3075
3076 func (m *PutRequest) GetEntity() []*EntityProto {
3077 if m != nil {
3078 return m.Entity
3079 }
3080 return nil
3081 }
3082
3083 func (m *PutRequest) GetTransaction() *Transaction {
3084 if m != nil {
3085 return m.Transaction
3086 }
3087 return nil
3088 }
3089
3090 func (m *PutRequest) GetCompositeIndex() []*CompositeIndex {
3091 if m != nil {
3092 return m.CompositeIndex
3093 }
3094 return nil
3095 }
3096
3097 func (m *PutRequest) GetTrusted() bool {
3098 if m != nil && m.Trusted != nil {
3099 return *m.Trusted
3100 }
3101 return Default_PutRequest_Trusted
3102 }
3103
3104 func (m *PutRequest) GetForce() bool {
3105 if m != nil && m.Force != nil {
3106 return *m.Force
3107 }
3108 return Default_PutRequest_Force
3109 }
3110
3111 func (m *PutRequest) GetMarkChanges() bool {
3112 if m != nil && m.MarkChanges != nil {
3113 return *m.MarkChanges
3114 }
3115 return Default_PutRequest_MarkChanges
3116 }
3117
3118 func (m *PutRequest) GetSnapshot() []*Snapshot {
3119 if m != nil {
3120 return m.Snapshot
3121 }
3122 return nil
3123 }
3124
3125 func (m *PutRequest) GetAutoIdPolicy() PutRequest_AutoIdPolicy {
3126 if m != nil && m.AutoIdPolicy != nil {
3127 return *m.AutoIdPolicy
3128 }
3129 return Default_PutRequest_AutoIdPolicy
3130 }
3131
3132 type PutResponse struct {
3133 Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
3134 Cost *Cost `protobuf:"bytes,2,opt,name=cost" json:"cost,omitempty"`
3135 Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"`
3136 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3137 XXX_unrecognized []byte `json:"-"`
3138 XXX_sizecache int32 `json:"-"`
3139 }
3140
3141 func (m *PutResponse) Reset() { *m = PutResponse{} }
3142 func (m *PutResponse) String() string { return proto.CompactTextString(m) }
3143 func (*PutResponse) ProtoMessage() {}
3144 func (*PutResponse) Descriptor() ([]byte, []int) {
3145 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{24}
3146 }
3147 func (m *PutResponse) XXX_Unmarshal(b []byte) error {
3148 return xxx_messageInfo_PutResponse.Unmarshal(m, b)
3149 }
3150 func (m *PutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3151 return xxx_messageInfo_PutResponse.Marshal(b, m, deterministic)
3152 }
3153 func (dst *PutResponse) XXX_Merge(src proto.Message) {
3154 xxx_messageInfo_PutResponse.Merge(dst, src)
3155 }
3156 func (m *PutResponse) XXX_Size() int {
3157 return xxx_messageInfo_PutResponse.Size(m)
3158 }
3159 func (m *PutResponse) XXX_DiscardUnknown() {
3160 xxx_messageInfo_PutResponse.DiscardUnknown(m)
3161 }
3162
3163 var xxx_messageInfo_PutResponse proto.InternalMessageInfo
3164
3165 func (m *PutResponse) GetKey() []*Reference {
3166 if m != nil {
3167 return m.Key
3168 }
3169 return nil
3170 }
3171
3172 func (m *PutResponse) GetCost() *Cost {
3173 if m != nil {
3174 return m.Cost
3175 }
3176 return nil
3177 }
3178
3179 func (m *PutResponse) GetVersion() []int64 {
3180 if m != nil {
3181 return m.Version
3182 }
3183 return nil
3184 }
3185
3186 type TouchRequest struct {
3187 Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"`
3188 Key []*Reference `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
3189 CompositeIndex []*CompositeIndex `protobuf:"bytes,2,rep,name=composite_index,json=compositeIndex" json:"composite_index,omitempty"`
3190 Force *bool `protobuf:"varint,3,opt,name=force,def=0" json:"force,omitempty"`
3191 Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"`
3192 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3193 XXX_unrecognized []byte `json:"-"`
3194 XXX_sizecache int32 `json:"-"`
3195 }
3196
3197 func (m *TouchRequest) Reset() { *m = TouchRequest{} }
3198 func (m *TouchRequest) String() string { return proto.CompactTextString(m) }
3199 func (*TouchRequest) ProtoMessage() {}
3200 func (*TouchRequest) Descriptor() ([]byte, []int) {
3201 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{25}
3202 }
3203 func (m *TouchRequest) XXX_Unmarshal(b []byte) error {
3204 return xxx_messageInfo_TouchRequest.Unmarshal(m, b)
3205 }
3206 func (m *TouchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3207 return xxx_messageInfo_TouchRequest.Marshal(b, m, deterministic)
3208 }
3209 func (dst *TouchRequest) XXX_Merge(src proto.Message) {
3210 xxx_messageInfo_TouchRequest.Merge(dst, src)
3211 }
3212 func (m *TouchRequest) XXX_Size() int {
3213 return xxx_messageInfo_TouchRequest.Size(m)
3214 }
3215 func (m *TouchRequest) XXX_DiscardUnknown() {
3216 xxx_messageInfo_TouchRequest.DiscardUnknown(m)
3217 }
3218
3219 var xxx_messageInfo_TouchRequest proto.InternalMessageInfo
3220
3221 const Default_TouchRequest_Force bool = false
3222
3223 func (m *TouchRequest) GetHeader() *InternalHeader {
3224 if m != nil {
3225 return m.Header
3226 }
3227 return nil
3228 }
3229
3230 func (m *TouchRequest) GetKey() []*Reference {
3231 if m != nil {
3232 return m.Key
3233 }
3234 return nil
3235 }
3236
3237 func (m *TouchRequest) GetCompositeIndex() []*CompositeIndex {
3238 if m != nil {
3239 return m.CompositeIndex
3240 }
3241 return nil
3242 }
3243
3244 func (m *TouchRequest) GetForce() bool {
3245 if m != nil && m.Force != nil {
3246 return *m.Force
3247 }
3248 return Default_TouchRequest_Force
3249 }
3250
3251 func (m *TouchRequest) GetSnapshot() []*Snapshot {
3252 if m != nil {
3253 return m.Snapshot
3254 }
3255 return nil
3256 }
3257
3258 type TouchResponse struct {
3259 Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"`
3260 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3261 XXX_unrecognized []byte `json:"-"`
3262 XXX_sizecache int32 `json:"-"`
3263 }
3264
3265 func (m *TouchResponse) Reset() { *m = TouchResponse{} }
3266 func (m *TouchResponse) String() string { return proto.CompactTextString(m) }
3267 func (*TouchResponse) ProtoMessage() {}
3268 func (*TouchResponse) Descriptor() ([]byte, []int) {
3269 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{26}
3270 }
3271 func (m *TouchResponse) XXX_Unmarshal(b []byte) error {
3272 return xxx_messageInfo_TouchResponse.Unmarshal(m, b)
3273 }
3274 func (m *TouchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3275 return xxx_messageInfo_TouchResponse.Marshal(b, m, deterministic)
3276 }
3277 func (dst *TouchResponse) XXX_Merge(src proto.Message) {
3278 xxx_messageInfo_TouchResponse.Merge(dst, src)
3279 }
3280 func (m *TouchResponse) XXX_Size() int {
3281 return xxx_messageInfo_TouchResponse.Size(m)
3282 }
3283 func (m *TouchResponse) XXX_DiscardUnknown() {
3284 xxx_messageInfo_TouchResponse.DiscardUnknown(m)
3285 }
3286
3287 var xxx_messageInfo_TouchResponse proto.InternalMessageInfo
3288
3289 func (m *TouchResponse) GetCost() *Cost {
3290 if m != nil {
3291 return m.Cost
3292 }
3293 return nil
3294 }
3295
3296 type DeleteRequest struct {
3297 Header *InternalHeader `protobuf:"bytes,10,opt,name=header" json:"header,omitempty"`
3298 Key []*Reference `protobuf:"bytes,6,rep,name=key" json:"key,omitempty"`
3299 Transaction *Transaction `protobuf:"bytes,5,opt,name=transaction" json:"transaction,omitempty"`
3300 Trusted *bool `protobuf:"varint,4,opt,name=trusted,def=0" json:"trusted,omitempty"`
3301 Force *bool `protobuf:"varint,7,opt,name=force,def=0" json:"force,omitempty"`
3302 MarkChanges *bool `protobuf:"varint,8,opt,name=mark_changes,json=markChanges,def=0" json:"mark_changes,omitempty"`
3303 Snapshot []*Snapshot `protobuf:"bytes,9,rep,name=snapshot" json:"snapshot,omitempty"`
3304 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3305 XXX_unrecognized []byte `json:"-"`
3306 XXX_sizecache int32 `json:"-"`
3307 }
3308
3309 func (m *DeleteRequest) Reset() { *m = DeleteRequest{} }
3310 func (m *DeleteRequest) String() string { return proto.CompactTextString(m) }
3311 func (*DeleteRequest) ProtoMessage() {}
3312 func (*DeleteRequest) Descriptor() ([]byte, []int) {
3313 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{27}
3314 }
3315 func (m *DeleteRequest) XXX_Unmarshal(b []byte) error {
3316 return xxx_messageInfo_DeleteRequest.Unmarshal(m, b)
3317 }
3318 func (m *DeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3319 return xxx_messageInfo_DeleteRequest.Marshal(b, m, deterministic)
3320 }
3321 func (dst *DeleteRequest) XXX_Merge(src proto.Message) {
3322 xxx_messageInfo_DeleteRequest.Merge(dst, src)
3323 }
3324 func (m *DeleteRequest) XXX_Size() int {
3325 return xxx_messageInfo_DeleteRequest.Size(m)
3326 }
3327 func (m *DeleteRequest) XXX_DiscardUnknown() {
3328 xxx_messageInfo_DeleteRequest.DiscardUnknown(m)
3329 }
3330
3331 var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo
3332
3333 const Default_DeleteRequest_Trusted bool = false
3334 const Default_DeleteRequest_Force bool = false
3335 const Default_DeleteRequest_MarkChanges bool = false
3336
3337 func (m *DeleteRequest) GetHeader() *InternalHeader {
3338 if m != nil {
3339 return m.Header
3340 }
3341 return nil
3342 }
3343
3344 func (m *DeleteRequest) GetKey() []*Reference {
3345 if m != nil {
3346 return m.Key
3347 }
3348 return nil
3349 }
3350
3351 func (m *DeleteRequest) GetTransaction() *Transaction {
3352 if m != nil {
3353 return m.Transaction
3354 }
3355 return nil
3356 }
3357
3358 func (m *DeleteRequest) GetTrusted() bool {
3359 if m != nil && m.Trusted != nil {
3360 return *m.Trusted
3361 }
3362 return Default_DeleteRequest_Trusted
3363 }
3364
3365 func (m *DeleteRequest) GetForce() bool {
3366 if m != nil && m.Force != nil {
3367 return *m.Force
3368 }
3369 return Default_DeleteRequest_Force
3370 }
3371
3372 func (m *DeleteRequest) GetMarkChanges() bool {
3373 if m != nil && m.MarkChanges != nil {
3374 return *m.MarkChanges
3375 }
3376 return Default_DeleteRequest_MarkChanges
3377 }
3378
3379 func (m *DeleteRequest) GetSnapshot() []*Snapshot {
3380 if m != nil {
3381 return m.Snapshot
3382 }
3383 return nil
3384 }
3385
3386 type DeleteResponse struct {
3387 Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"`
3388 Version []int64 `protobuf:"varint,3,rep,name=version" json:"version,omitempty"`
3389 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3390 XXX_unrecognized []byte `json:"-"`
3391 XXX_sizecache int32 `json:"-"`
3392 }
3393
3394 func (m *DeleteResponse) Reset() { *m = DeleteResponse{} }
3395 func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
3396 func (*DeleteResponse) ProtoMessage() {}
3397 func (*DeleteResponse) Descriptor() ([]byte, []int) {
3398 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{28}
3399 }
3400 func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
3401 return xxx_messageInfo_DeleteResponse.Unmarshal(m, b)
3402 }
3403 func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3404 return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic)
3405 }
3406 func (dst *DeleteResponse) XXX_Merge(src proto.Message) {
3407 xxx_messageInfo_DeleteResponse.Merge(dst, src)
3408 }
3409 func (m *DeleteResponse) XXX_Size() int {
3410 return xxx_messageInfo_DeleteResponse.Size(m)
3411 }
3412 func (m *DeleteResponse) XXX_DiscardUnknown() {
3413 xxx_messageInfo_DeleteResponse.DiscardUnknown(m)
3414 }
3415
3416 var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo
3417
3418 func (m *DeleteResponse) GetCost() *Cost {
3419 if m != nil {
3420 return m.Cost
3421 }
3422 return nil
3423 }
3424
3425 func (m *DeleteResponse) GetVersion() []int64 {
3426 if m != nil {
3427 return m.Version
3428 }
3429 return nil
3430 }
3431
3432 type NextRequest struct {
3433 Header *InternalHeader `protobuf:"bytes,5,opt,name=header" json:"header,omitempty"`
3434 Cursor *Cursor `protobuf:"bytes,1,req,name=cursor" json:"cursor,omitempty"`
3435 Count *int32 `protobuf:"varint,2,opt,name=count" json:"count,omitempty"`
3436 Offset *int32 `protobuf:"varint,4,opt,name=offset,def=0" json:"offset,omitempty"`
3437 Compile *bool `protobuf:"varint,3,opt,name=compile,def=0" json:"compile,omitempty"`
3438 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3439 XXX_unrecognized []byte `json:"-"`
3440 XXX_sizecache int32 `json:"-"`
3441 }
3442
3443 func (m *NextRequest) Reset() { *m = NextRequest{} }
3444 func (m *NextRequest) String() string { return proto.CompactTextString(m) }
3445 func (*NextRequest) ProtoMessage() {}
3446 func (*NextRequest) Descriptor() ([]byte, []int) {
3447 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{29}
3448 }
3449 func (m *NextRequest) XXX_Unmarshal(b []byte) error {
3450 return xxx_messageInfo_NextRequest.Unmarshal(m, b)
3451 }
3452 func (m *NextRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3453 return xxx_messageInfo_NextRequest.Marshal(b, m, deterministic)
3454 }
3455 func (dst *NextRequest) XXX_Merge(src proto.Message) {
3456 xxx_messageInfo_NextRequest.Merge(dst, src)
3457 }
3458 func (m *NextRequest) XXX_Size() int {
3459 return xxx_messageInfo_NextRequest.Size(m)
3460 }
3461 func (m *NextRequest) XXX_DiscardUnknown() {
3462 xxx_messageInfo_NextRequest.DiscardUnknown(m)
3463 }
3464
3465 var xxx_messageInfo_NextRequest proto.InternalMessageInfo
3466
3467 const Default_NextRequest_Offset int32 = 0
3468 const Default_NextRequest_Compile bool = false
3469
3470 func (m *NextRequest) GetHeader() *InternalHeader {
3471 if m != nil {
3472 return m.Header
3473 }
3474 return nil
3475 }
3476
3477 func (m *NextRequest) GetCursor() *Cursor {
3478 if m != nil {
3479 return m.Cursor
3480 }
3481 return nil
3482 }
3483
3484 func (m *NextRequest) GetCount() int32 {
3485 if m != nil && m.Count != nil {
3486 return *m.Count
3487 }
3488 return 0
3489 }
3490
3491 func (m *NextRequest) GetOffset() int32 {
3492 if m != nil && m.Offset != nil {
3493 return *m.Offset
3494 }
3495 return Default_NextRequest_Offset
3496 }
3497
3498 func (m *NextRequest) GetCompile() bool {
3499 if m != nil && m.Compile != nil {
3500 return *m.Compile
3501 }
3502 return Default_NextRequest_Compile
3503 }
3504
3505 type QueryResult struct {
3506 Cursor *Cursor `protobuf:"bytes,1,opt,name=cursor" json:"cursor,omitempty"`
3507 Result []*EntityProto `protobuf:"bytes,2,rep,name=result" json:"result,omitempty"`
3508 SkippedResults *int32 `protobuf:"varint,7,opt,name=skipped_results,json=skippedResults" json:"skipped_results,omitempty"`
3509 MoreResults *bool `protobuf:"varint,3,req,name=more_results,json=moreResults" json:"more_results,omitempty"`
3510 KeysOnly *bool `protobuf:"varint,4,opt,name=keys_only,json=keysOnly" json:"keys_only,omitempty"`
3511 IndexOnly *bool `protobuf:"varint,9,opt,name=index_only,json=indexOnly" json:"index_only,omitempty"`
3512 SmallOps *bool `protobuf:"varint,10,opt,name=small_ops,json=smallOps" json:"small_ops,omitempty"`
3513 CompiledQuery *CompiledQuery `protobuf:"bytes,5,opt,name=compiled_query,json=compiledQuery" json:"compiled_query,omitempty"`
3514 CompiledCursor *CompiledCursor `protobuf:"bytes,6,opt,name=compiled_cursor,json=compiledCursor" json:"compiled_cursor,omitempty"`
3515 Index []*CompositeIndex `protobuf:"bytes,8,rep,name=index" json:"index,omitempty"`
3516 Version []int64 `protobuf:"varint,11,rep,name=version" json:"version,omitempty"`
3517 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3518 XXX_unrecognized []byte `json:"-"`
3519 XXX_sizecache int32 `json:"-"`
3520 }
3521
3522 func (m *QueryResult) Reset() { *m = QueryResult{} }
3523 func (m *QueryResult) String() string { return proto.CompactTextString(m) }
3524 func (*QueryResult) ProtoMessage() {}
3525 func (*QueryResult) Descriptor() ([]byte, []int) {
3526 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{30}
3527 }
3528 func (m *QueryResult) XXX_Unmarshal(b []byte) error {
3529 return xxx_messageInfo_QueryResult.Unmarshal(m, b)
3530 }
3531 func (m *QueryResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3532 return xxx_messageInfo_QueryResult.Marshal(b, m, deterministic)
3533 }
3534 func (dst *QueryResult) XXX_Merge(src proto.Message) {
3535 xxx_messageInfo_QueryResult.Merge(dst, src)
3536 }
3537 func (m *QueryResult) XXX_Size() int {
3538 return xxx_messageInfo_QueryResult.Size(m)
3539 }
3540 func (m *QueryResult) XXX_DiscardUnknown() {
3541 xxx_messageInfo_QueryResult.DiscardUnknown(m)
3542 }
3543
3544 var xxx_messageInfo_QueryResult proto.InternalMessageInfo
3545
3546 func (m *QueryResult) GetCursor() *Cursor {
3547 if m != nil {
3548 return m.Cursor
3549 }
3550 return nil
3551 }
3552
3553 func (m *QueryResult) GetResult() []*EntityProto {
3554 if m != nil {
3555 return m.Result
3556 }
3557 return nil
3558 }
3559
3560 func (m *QueryResult) GetSkippedResults() int32 {
3561 if m != nil && m.SkippedResults != nil {
3562 return *m.SkippedResults
3563 }
3564 return 0
3565 }
3566
3567 func (m *QueryResult) GetMoreResults() bool {
3568 if m != nil && m.MoreResults != nil {
3569 return *m.MoreResults
3570 }
3571 return false
3572 }
3573
3574 func (m *QueryResult) GetKeysOnly() bool {
3575 if m != nil && m.KeysOnly != nil {
3576 return *m.KeysOnly
3577 }
3578 return false
3579 }
3580
3581 func (m *QueryResult) GetIndexOnly() bool {
3582 if m != nil && m.IndexOnly != nil {
3583 return *m.IndexOnly
3584 }
3585 return false
3586 }
3587
3588 func (m *QueryResult) GetSmallOps() bool {
3589 if m != nil && m.SmallOps != nil {
3590 return *m.SmallOps
3591 }
3592 return false
3593 }
3594
3595 func (m *QueryResult) GetCompiledQuery() *CompiledQuery {
3596 if m != nil {
3597 return m.CompiledQuery
3598 }
3599 return nil
3600 }
3601
3602 func (m *QueryResult) GetCompiledCursor() *CompiledCursor {
3603 if m != nil {
3604 return m.CompiledCursor
3605 }
3606 return nil
3607 }
3608
3609 func (m *QueryResult) GetIndex() []*CompositeIndex {
3610 if m != nil {
3611 return m.Index
3612 }
3613 return nil
3614 }
3615
3616 func (m *QueryResult) GetVersion() []int64 {
3617 if m != nil {
3618 return m.Version
3619 }
3620 return nil
3621 }
3622
3623 type AllocateIdsRequest struct {
3624 Header *InternalHeader `protobuf:"bytes,4,opt,name=header" json:"header,omitempty"`
3625 ModelKey *Reference `protobuf:"bytes,1,opt,name=model_key,json=modelKey" json:"model_key,omitempty"`
3626 Size *int64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"`
3627 Max *int64 `protobuf:"varint,3,opt,name=max" json:"max,omitempty"`
3628 Reserve []*Reference `protobuf:"bytes,5,rep,name=reserve" json:"reserve,omitempty"`
3629 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3630 XXX_unrecognized []byte `json:"-"`
3631 XXX_sizecache int32 `json:"-"`
3632 }
3633
3634 func (m *AllocateIdsRequest) Reset() { *m = AllocateIdsRequest{} }
3635 func (m *AllocateIdsRequest) String() string { return proto.CompactTextString(m) }
3636 func (*AllocateIdsRequest) ProtoMessage() {}
3637 func (*AllocateIdsRequest) Descriptor() ([]byte, []int) {
3638 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{31}
3639 }
3640 func (m *AllocateIdsRequest) XXX_Unmarshal(b []byte) error {
3641 return xxx_messageInfo_AllocateIdsRequest.Unmarshal(m, b)
3642 }
3643 func (m *AllocateIdsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3644 return xxx_messageInfo_AllocateIdsRequest.Marshal(b, m, deterministic)
3645 }
3646 func (dst *AllocateIdsRequest) XXX_Merge(src proto.Message) {
3647 xxx_messageInfo_AllocateIdsRequest.Merge(dst, src)
3648 }
3649 func (m *AllocateIdsRequest) XXX_Size() int {
3650 return xxx_messageInfo_AllocateIdsRequest.Size(m)
3651 }
3652 func (m *AllocateIdsRequest) XXX_DiscardUnknown() {
3653 xxx_messageInfo_AllocateIdsRequest.DiscardUnknown(m)
3654 }
3655
3656 var xxx_messageInfo_AllocateIdsRequest proto.InternalMessageInfo
3657
3658 func (m *AllocateIdsRequest) GetHeader() *InternalHeader {
3659 if m != nil {
3660 return m.Header
3661 }
3662 return nil
3663 }
3664
3665 func (m *AllocateIdsRequest) GetModelKey() *Reference {
3666 if m != nil {
3667 return m.ModelKey
3668 }
3669 return nil
3670 }
3671
3672 func (m *AllocateIdsRequest) GetSize() int64 {
3673 if m != nil && m.Size != nil {
3674 return *m.Size
3675 }
3676 return 0
3677 }
3678
3679 func (m *AllocateIdsRequest) GetMax() int64 {
3680 if m != nil && m.Max != nil {
3681 return *m.Max
3682 }
3683 return 0
3684 }
3685
3686 func (m *AllocateIdsRequest) GetReserve() []*Reference {
3687 if m != nil {
3688 return m.Reserve
3689 }
3690 return nil
3691 }
3692
3693 type AllocateIdsResponse struct {
3694 Start *int64 `protobuf:"varint,1,req,name=start" json:"start,omitempty"`
3695 End *int64 `protobuf:"varint,2,req,name=end" json:"end,omitempty"`
3696 Cost *Cost `protobuf:"bytes,3,opt,name=cost" json:"cost,omitempty"`
3697 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3698 XXX_unrecognized []byte `json:"-"`
3699 XXX_sizecache int32 `json:"-"`
3700 }
3701
3702 func (m *AllocateIdsResponse) Reset() { *m = AllocateIdsResponse{} }
3703 func (m *AllocateIdsResponse) String() string { return proto.CompactTextString(m) }
3704 func (*AllocateIdsResponse) ProtoMessage() {}
3705 func (*AllocateIdsResponse) Descriptor() ([]byte, []int) {
3706 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{32}
3707 }
3708 func (m *AllocateIdsResponse) XXX_Unmarshal(b []byte) error {
3709 return xxx_messageInfo_AllocateIdsResponse.Unmarshal(m, b)
3710 }
3711 func (m *AllocateIdsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3712 return xxx_messageInfo_AllocateIdsResponse.Marshal(b, m, deterministic)
3713 }
3714 func (dst *AllocateIdsResponse) XXX_Merge(src proto.Message) {
3715 xxx_messageInfo_AllocateIdsResponse.Merge(dst, src)
3716 }
3717 func (m *AllocateIdsResponse) XXX_Size() int {
3718 return xxx_messageInfo_AllocateIdsResponse.Size(m)
3719 }
3720 func (m *AllocateIdsResponse) XXX_DiscardUnknown() {
3721 xxx_messageInfo_AllocateIdsResponse.DiscardUnknown(m)
3722 }
3723
3724 var xxx_messageInfo_AllocateIdsResponse proto.InternalMessageInfo
3725
3726 func (m *AllocateIdsResponse) GetStart() int64 {
3727 if m != nil && m.Start != nil {
3728 return *m.Start
3729 }
3730 return 0
3731 }
3732
3733 func (m *AllocateIdsResponse) GetEnd() int64 {
3734 if m != nil && m.End != nil {
3735 return *m.End
3736 }
3737 return 0
3738 }
3739
3740 func (m *AllocateIdsResponse) GetCost() *Cost {
3741 if m != nil {
3742 return m.Cost
3743 }
3744 return nil
3745 }
3746
3747 type CompositeIndices struct {
3748 Index []*CompositeIndex `protobuf:"bytes,1,rep,name=index" json:"index,omitempty"`
3749 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3750 XXX_unrecognized []byte `json:"-"`
3751 XXX_sizecache int32 `json:"-"`
3752 }
3753
3754 func (m *CompositeIndices) Reset() { *m = CompositeIndices{} }
3755 func (m *CompositeIndices) String() string { return proto.CompactTextString(m) }
3756 func (*CompositeIndices) ProtoMessage() {}
3757 func (*CompositeIndices) Descriptor() ([]byte, []int) {
3758 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{33}
3759 }
3760 func (m *CompositeIndices) XXX_Unmarshal(b []byte) error {
3761 return xxx_messageInfo_CompositeIndices.Unmarshal(m, b)
3762 }
3763 func (m *CompositeIndices) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3764 return xxx_messageInfo_CompositeIndices.Marshal(b, m, deterministic)
3765 }
3766 func (dst *CompositeIndices) XXX_Merge(src proto.Message) {
3767 xxx_messageInfo_CompositeIndices.Merge(dst, src)
3768 }
3769 func (m *CompositeIndices) XXX_Size() int {
3770 return xxx_messageInfo_CompositeIndices.Size(m)
3771 }
3772 func (m *CompositeIndices) XXX_DiscardUnknown() {
3773 xxx_messageInfo_CompositeIndices.DiscardUnknown(m)
3774 }
3775
3776 var xxx_messageInfo_CompositeIndices proto.InternalMessageInfo
3777
3778 func (m *CompositeIndices) GetIndex() []*CompositeIndex {
3779 if m != nil {
3780 return m.Index
3781 }
3782 return nil
3783 }
3784
3785 type AddActionsRequest struct {
3786 Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"`
3787 Transaction *Transaction `protobuf:"bytes,1,req,name=transaction" json:"transaction,omitempty"`
3788 Action []*Action `protobuf:"bytes,2,rep,name=action" json:"action,omitempty"`
3789 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3790 XXX_unrecognized []byte `json:"-"`
3791 XXX_sizecache int32 `json:"-"`
3792 }
3793
3794 func (m *AddActionsRequest) Reset() { *m = AddActionsRequest{} }
3795 func (m *AddActionsRequest) String() string { return proto.CompactTextString(m) }
3796 func (*AddActionsRequest) ProtoMessage() {}
3797 func (*AddActionsRequest) Descriptor() ([]byte, []int) {
3798 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{34}
3799 }
3800 func (m *AddActionsRequest) XXX_Unmarshal(b []byte) error {
3801 return xxx_messageInfo_AddActionsRequest.Unmarshal(m, b)
3802 }
3803 func (m *AddActionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3804 return xxx_messageInfo_AddActionsRequest.Marshal(b, m, deterministic)
3805 }
3806 func (dst *AddActionsRequest) XXX_Merge(src proto.Message) {
3807 xxx_messageInfo_AddActionsRequest.Merge(dst, src)
3808 }
3809 func (m *AddActionsRequest) XXX_Size() int {
3810 return xxx_messageInfo_AddActionsRequest.Size(m)
3811 }
3812 func (m *AddActionsRequest) XXX_DiscardUnknown() {
3813 xxx_messageInfo_AddActionsRequest.DiscardUnknown(m)
3814 }
3815
3816 var xxx_messageInfo_AddActionsRequest proto.InternalMessageInfo
3817
3818 func (m *AddActionsRequest) GetHeader() *InternalHeader {
3819 if m != nil {
3820 return m.Header
3821 }
3822 return nil
3823 }
3824
3825 func (m *AddActionsRequest) GetTransaction() *Transaction {
3826 if m != nil {
3827 return m.Transaction
3828 }
3829 return nil
3830 }
3831
3832 func (m *AddActionsRequest) GetAction() []*Action {
3833 if m != nil {
3834 return m.Action
3835 }
3836 return nil
3837 }
3838
3839 type AddActionsResponse struct {
3840 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3841 XXX_unrecognized []byte `json:"-"`
3842 XXX_sizecache int32 `json:"-"`
3843 }
3844
3845 func (m *AddActionsResponse) Reset() { *m = AddActionsResponse{} }
3846 func (m *AddActionsResponse) String() string { return proto.CompactTextString(m) }
3847 func (*AddActionsResponse) ProtoMessage() {}
3848 func (*AddActionsResponse) Descriptor() ([]byte, []int) {
3849 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{35}
3850 }
3851 func (m *AddActionsResponse) XXX_Unmarshal(b []byte) error {
3852 return xxx_messageInfo_AddActionsResponse.Unmarshal(m, b)
3853 }
3854 func (m *AddActionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3855 return xxx_messageInfo_AddActionsResponse.Marshal(b, m, deterministic)
3856 }
3857 func (dst *AddActionsResponse) XXX_Merge(src proto.Message) {
3858 xxx_messageInfo_AddActionsResponse.Merge(dst, src)
3859 }
3860 func (m *AddActionsResponse) XXX_Size() int {
3861 return xxx_messageInfo_AddActionsResponse.Size(m)
3862 }
3863 func (m *AddActionsResponse) XXX_DiscardUnknown() {
3864 xxx_messageInfo_AddActionsResponse.DiscardUnknown(m)
3865 }
3866
3867 var xxx_messageInfo_AddActionsResponse proto.InternalMessageInfo
3868
3869 type BeginTransactionRequest struct {
3870 Header *InternalHeader `protobuf:"bytes,3,opt,name=header" json:"header,omitempty"`
3871 App *string `protobuf:"bytes,1,req,name=app" json:"app,omitempty"`
3872 AllowMultipleEg *bool `protobuf:"varint,2,opt,name=allow_multiple_eg,json=allowMultipleEg,def=0" json:"allow_multiple_eg,omitempty"`
3873 DatabaseId *string `protobuf:"bytes,4,opt,name=database_id,json=databaseId" json:"database_id,omitempty"`
3874 Mode *BeginTransactionRequest_TransactionMode `protobuf:"varint,5,opt,name=mode,enum=appengine.BeginTransactionRequest_TransactionMode,def=0" json:"mode,omitempty"`
3875 PreviousTransaction *Transaction `protobuf:"bytes,7,opt,name=previous_transaction,json=previousTransaction" json:"previous_transaction,omitempty"`
3876 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3877 XXX_unrecognized []byte `json:"-"`
3878 XXX_sizecache int32 `json:"-"`
3879 }
3880
3881 func (m *BeginTransactionRequest) Reset() { *m = BeginTransactionRequest{} }
3882 func (m *BeginTransactionRequest) String() string { return proto.CompactTextString(m) }
3883 func (*BeginTransactionRequest) ProtoMessage() {}
3884 func (*BeginTransactionRequest) Descriptor() ([]byte, []int) {
3885 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{36}
3886 }
3887 func (m *BeginTransactionRequest) XXX_Unmarshal(b []byte) error {
3888 return xxx_messageInfo_BeginTransactionRequest.Unmarshal(m, b)
3889 }
3890 func (m *BeginTransactionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3891 return xxx_messageInfo_BeginTransactionRequest.Marshal(b, m, deterministic)
3892 }
3893 func (dst *BeginTransactionRequest) XXX_Merge(src proto.Message) {
3894 xxx_messageInfo_BeginTransactionRequest.Merge(dst, src)
3895 }
3896 func (m *BeginTransactionRequest) XXX_Size() int {
3897 return xxx_messageInfo_BeginTransactionRequest.Size(m)
3898 }
3899 func (m *BeginTransactionRequest) XXX_DiscardUnknown() {
3900 xxx_messageInfo_BeginTransactionRequest.DiscardUnknown(m)
3901 }
3902
3903 var xxx_messageInfo_BeginTransactionRequest proto.InternalMessageInfo
3904
3905 const Default_BeginTransactionRequest_AllowMultipleEg bool = false
3906 const Default_BeginTransactionRequest_Mode BeginTransactionRequest_TransactionMode = BeginTransactionRequest_UNKNOWN
3907
3908 func (m *BeginTransactionRequest) GetHeader() *InternalHeader {
3909 if m != nil {
3910 return m.Header
3911 }
3912 return nil
3913 }
3914
3915 func (m *BeginTransactionRequest) GetApp() string {
3916 if m != nil && m.App != nil {
3917 return *m.App
3918 }
3919 return ""
3920 }
3921
3922 func (m *BeginTransactionRequest) GetAllowMultipleEg() bool {
3923 if m != nil && m.AllowMultipleEg != nil {
3924 return *m.AllowMultipleEg
3925 }
3926 return Default_BeginTransactionRequest_AllowMultipleEg
3927 }
3928
3929 func (m *BeginTransactionRequest) GetDatabaseId() string {
3930 if m != nil && m.DatabaseId != nil {
3931 return *m.DatabaseId
3932 }
3933 return ""
3934 }
3935
3936 func (m *BeginTransactionRequest) GetMode() BeginTransactionRequest_TransactionMode {
3937 if m != nil && m.Mode != nil {
3938 return *m.Mode
3939 }
3940 return Default_BeginTransactionRequest_Mode
3941 }
3942
3943 func (m *BeginTransactionRequest) GetPreviousTransaction() *Transaction {
3944 if m != nil {
3945 return m.PreviousTransaction
3946 }
3947 return nil
3948 }
3949
3950 type CommitResponse struct {
3951 Cost *Cost `protobuf:"bytes,1,opt,name=cost" json:"cost,omitempty"`
3952 Version []*CommitResponse_Version `protobuf:"group,3,rep,name=Version,json=version" json:"version,omitempty"`
3953 XXX_NoUnkeyedLiteral struct{} `json:"-"`
3954 XXX_unrecognized []byte `json:"-"`
3955 XXX_sizecache int32 `json:"-"`
3956 }
3957
3958 func (m *CommitResponse) Reset() { *m = CommitResponse{} }
3959 func (m *CommitResponse) String() string { return proto.CompactTextString(m) }
3960 func (*CommitResponse) ProtoMessage() {}
3961 func (*CommitResponse) Descriptor() ([]byte, []int) {
3962 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37}
3963 }
3964 func (m *CommitResponse) XXX_Unmarshal(b []byte) error {
3965 return xxx_messageInfo_CommitResponse.Unmarshal(m, b)
3966 }
3967 func (m *CommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
3968 return xxx_messageInfo_CommitResponse.Marshal(b, m, deterministic)
3969 }
3970 func (dst *CommitResponse) XXX_Merge(src proto.Message) {
3971 xxx_messageInfo_CommitResponse.Merge(dst, src)
3972 }
3973 func (m *CommitResponse) XXX_Size() int {
3974 return xxx_messageInfo_CommitResponse.Size(m)
3975 }
3976 func (m *CommitResponse) XXX_DiscardUnknown() {
3977 xxx_messageInfo_CommitResponse.DiscardUnknown(m)
3978 }
3979
3980 var xxx_messageInfo_CommitResponse proto.InternalMessageInfo
3981
3982 func (m *CommitResponse) GetCost() *Cost {
3983 if m != nil {
3984 return m.Cost
3985 }
3986 return nil
3987 }
3988
3989 func (m *CommitResponse) GetVersion() []*CommitResponse_Version {
3990 if m != nil {
3991 return m.Version
3992 }
3993 return nil
3994 }
3995
3996 type CommitResponse_Version struct {
3997 RootEntityKey *Reference `protobuf:"bytes,4,req,name=root_entity_key,json=rootEntityKey" json:"root_entity_key,omitempty"`
3998 Version *int64 `protobuf:"varint,5,req,name=version" json:"version,omitempty"`
3999 XXX_NoUnkeyedLiteral struct{} `json:"-"`
4000 XXX_unrecognized []byte `json:"-"`
4001 XXX_sizecache int32 `json:"-"`
4002 }
4003
4004 func (m *CommitResponse_Version) Reset() { *m = CommitResponse_Version{} }
4005 func (m *CommitResponse_Version) String() string { return proto.CompactTextString(m) }
4006 func (*CommitResponse_Version) ProtoMessage() {}
4007 func (*CommitResponse_Version) Descriptor() ([]byte, []int) {
4008 return fileDescriptor_datastore_v3_83b17b80c34f6179, []int{37, 0}
4009 }
4010 func (m *CommitResponse_Version) XXX_Unmarshal(b []byte) error {
4011 return xxx_messageInfo_CommitResponse_Version.Unmarshal(m, b)
4012 }
4013 func (m *CommitResponse_Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
4014 return xxx_messageInfo_CommitResponse_Version.Marshal(b, m, deterministic)
4015 }
4016 func (dst *CommitResponse_Version) XXX_Merge(src proto.Message) {
4017 xxx_messageInfo_CommitResponse_Version.Merge(dst, src)
4018 }
4019 func (m *CommitResponse_Version) XXX_Size() int {
4020 return xxx_messageInfo_CommitResponse_Version.Size(m)
4021 }
4022 func (m *CommitResponse_Version) XXX_DiscardUnknown() {
4023 xxx_messageInfo_CommitResponse_Version.DiscardUnknown(m)
4024 }
4025
4026 var xxx_messageInfo_CommitResponse_Version proto.InternalMessageInfo
4027
4028 func (m *CommitResponse_Version) GetRootEntityKey() *Reference {
4029 if m != nil {
4030 return m.RootEntityKey
4031 }
4032 return nil
4033 }
4034
4035 func (m *CommitResponse_Version) GetVersion() int64 {
4036 if m != nil && m.Version != nil {
4037 return *m.Version
4038 }
4039 return 0
4040 }
4041
4042 func init() {
4043 proto.RegisterType((*Action)(nil), "appengine.Action")
4044 proto.RegisterType((*PropertyValue)(nil), "appengine.PropertyValue")
4045 proto.RegisterType((*PropertyValue_PointValue)(nil), "appengine.PropertyValue.PointValue")
4046 proto.RegisterType((*PropertyValue_UserValue)(nil), "appengine.PropertyValue.UserValue")
4047 proto.RegisterType((*PropertyValue_ReferenceValue)(nil), "appengine.PropertyValue.ReferenceValue")
4048 proto.RegisterType((*PropertyValue_ReferenceValue_PathElement)(nil), "appengine.PropertyValue.ReferenceValue.PathElement")
4049 proto.RegisterType((*Property)(nil), "appengine.Property")
4050 proto.RegisterType((*Path)(nil), "appengine.Path")
4051 proto.RegisterType((*Path_Element)(nil), "appengine.Path.Element")
4052 proto.RegisterType((*Reference)(nil), "appengine.Reference")
4053 proto.RegisterType((*User)(nil), "appengine.User")
4054 proto.RegisterType((*EntityProto)(nil), "appengine.EntityProto")
4055 proto.RegisterType((*CompositeProperty)(nil), "appengine.CompositeProperty")
4056 proto.RegisterType((*Index)(nil), "appengine.Index")
4057 proto.RegisterType((*Index_Property)(nil), "appengine.Index.Property")
4058 proto.RegisterType((*CompositeIndex)(nil), "appengine.CompositeIndex")
4059 proto.RegisterType((*IndexPostfix)(nil), "appengine.IndexPostfix")
4060 proto.RegisterType((*IndexPostfix_IndexValue)(nil), "appengine.IndexPostfix.IndexValue")
4061 proto.RegisterType((*IndexPosition)(nil), "appengine.IndexPosition")
4062 proto.RegisterType((*Snapshot)(nil), "appengine.Snapshot")
4063 proto.RegisterType((*InternalHeader)(nil), "appengine.InternalHeader")
4064 proto.RegisterType((*Transaction)(nil), "appengine.Transaction")
4065 proto.RegisterType((*Query)(nil), "appengine.Query")
4066 proto.RegisterType((*Query_Filter)(nil), "appengine.Query.Filter")
4067 proto.RegisterType((*Query_Order)(nil), "appengine.Query.Order")
4068 proto.RegisterType((*CompiledQuery)(nil), "appengine.CompiledQuery")
4069 proto.RegisterType((*CompiledQuery_PrimaryScan)(nil), "appengine.CompiledQuery.PrimaryScan")
4070 proto.RegisterType((*CompiledQuery_MergeJoinScan)(nil), "appengine.CompiledQuery.MergeJoinScan")
4071 proto.RegisterType((*CompiledQuery_EntityFilter)(nil), "appengine.CompiledQuery.EntityFilter")
4072 proto.RegisterType((*CompiledCursor)(nil), "appengine.CompiledCursor")
4073 proto.RegisterType((*CompiledCursor_Position)(nil), "appengine.CompiledCursor.Position")
4074 proto.RegisterType((*CompiledCursor_Position_IndexValue)(nil), "appengine.CompiledCursor.Position.IndexValue")
4075 proto.RegisterType((*Cursor)(nil), "appengine.Cursor")
4076 proto.RegisterType((*Error)(nil), "appengine.Error")
4077 proto.RegisterType((*Cost)(nil), "appengine.Cost")
4078 proto.RegisterType((*Cost_CommitCost)(nil), "appengine.Cost.CommitCost")
4079 proto.RegisterType((*GetRequest)(nil), "appengine.GetRequest")
4080 proto.RegisterType((*GetResponse)(nil), "appengine.GetResponse")
4081 proto.RegisterType((*GetResponse_Entity)(nil), "appengine.GetResponse.Entity")
4082 proto.RegisterType((*PutRequest)(nil), "appengine.PutRequest")
4083 proto.RegisterType((*PutResponse)(nil), "appengine.PutResponse")
4084 proto.RegisterType((*TouchRequest)(nil), "appengine.TouchRequest")
4085 proto.RegisterType((*TouchResponse)(nil), "appengine.TouchResponse")
4086 proto.RegisterType((*DeleteRequest)(nil), "appengine.DeleteRequest")
4087 proto.RegisterType((*DeleteResponse)(nil), "appengine.DeleteResponse")
4088 proto.RegisterType((*NextRequest)(nil), "appengine.NextRequest")
4089 proto.RegisterType((*QueryResult)(nil), "appengine.QueryResult")
4090 proto.RegisterType((*AllocateIdsRequest)(nil), "appengine.AllocateIdsRequest")
4091 proto.RegisterType((*AllocateIdsResponse)(nil), "appengine.AllocateIdsResponse")
4092 proto.RegisterType((*CompositeIndices)(nil), "appengine.CompositeIndices")
4093 proto.RegisterType((*AddActionsRequest)(nil), "appengine.AddActionsRequest")
4094 proto.RegisterType((*AddActionsResponse)(nil), "appengine.AddActionsResponse")
4095 proto.RegisterType((*BeginTransactionRequest)(nil), "appengine.BeginTransactionRequest")
4096 proto.RegisterType((*CommitResponse)(nil), "appengine.CommitResponse")
4097 proto.RegisterType((*CommitResponse_Version)(nil), "appengine.CommitResponse.Version")
4098 }
4099
4100 func init() {
4101 proto.RegisterFile("google.golang.org/appengine/v2/internal/datastore/datastore_v3.proto", fileDescriptor_datastore_v3_83b17b80c34f6179)
4102 }
4103
4104 var fileDescriptor_datastore_v3_83b17b80c34f6179 = []byte{
4105 // 4156 bytes of a gzipped FileDescriptorProto
4106 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x73, 0xe3, 0x46,
4107 0x76, 0x37, 0xc1, 0xef, 0x47, 0x89, 0x82, 0x5a, 0xf3, 0xc1, 0xa1, 0x3f, 0x46, 0xc6, 0xac, 0x6d,
4108 0xd9, 0x6b, 0x73, 0x6c, 0xf9, 0x23, 0x5b, 0x4a, 0x76, 0x1d, 0x4a, 0xc4, 0x68, 0x90, 0xa1, 0x48,
4109 0xb9, 0x09, 0xd9, 0x9e, 0x5c, 0x50, 0x18, 0xa2, 0x29, 0x21, 0x43, 0x02, 0x30, 0x00, 0x6a, 0x46,
4110 0x93, 0xe4, 0x90, 0x4b, 0x2a, 0x55, 0x5b, 0xa9, 0x1c, 0x92, 0x4a, 0x25, 0xf9, 0x07, 0x72, 0xc8,
4111 0x39, 0x95, 0xaa, 0x54, 0xf6, 0x98, 0x5b, 0x0e, 0x7b, 0xc9, 0x31, 0x95, 0x73, 0xf2, 0x27, 0x24,
4112 0x39, 0xa4, 0xfa, 0x75, 0x03, 0x02, 0x28, 0x4a, 0x23, 0x6d, 0xf6, 0x90, 0x13, 0xd1, 0xef, 0xfd,
4113 0xba, 0xf1, 0xfa, 0xf5, 0xfb, 0x6c, 0x10, 0xba, 0xc7, 0xbe, 0x7f, 0x3c, 0x65, 0x9d, 0x63, 0x7f,
4114 0x6a, 0x7b, 0xc7, 0x1d, 0x3f, 0x3c, 0x7e, 0x68, 0x07, 0x01, 0xf3, 0x8e, 0x5d, 0x8f, 0x3d, 0x74,
4115 0xbd, 0x98, 0x85, 0x9e, 0x3d, 0x7d, 0xe8, 0xd8, 0xb1, 0x1d, 0xc5, 0x7e, 0xc8, 0xce, 0x9f, 0xac,
4116 0xd3, 0xcf, 0x3b, 0x41, 0xe8, 0xc7, 0x3e, 0xa9, 0xa7, 0x13, 0xb4, 0x1a, 0x54, 0xba, 0xe3, 0xd8,
4117 0xf5, 0x3d, 0xed, 0x1f, 0x2b, 0xb0, 0x7a, 0x18, 0xfa, 0x01, 0x0b, 0xe3, 0xb3, 0x6f, 0xed, 0xe9,
4118 0x9c, 0x91, 0x77, 0x00, 0x5c, 0x2f, 0xfe, 0xea, 0x0b, 0x1c, 0xb5, 0x0a, 0x9b, 0x85, 0xad, 0x22,
4119 0xcd, 0x50, 0x88, 0x06, 0x2b, 0xcf, 0x7c, 0x7f, 0xca, 0x6c, 0x4f, 0x20, 0x94, 0xcd, 0xc2, 0x56,
4120 0x8d, 0xe6, 0x68, 0x64, 0x13, 0x1a, 0x51, 0x1c, 0xba, 0xde, 0xb1, 0x80, 0x14, 0x37, 0x0b, 0x5b,
4121 0x75, 0x9a, 0x25, 0x71, 0x84, 0xe3, 0xcf, 0x9f, 0x4d, 0x99, 0x40, 0x94, 0x36, 0x0b, 0x5b, 0x05,
4122 0x9a, 0x25, 0x91, 0x3d, 0x80, 0xc0, 0x77, 0xbd, 0xf8, 0x14, 0x01, 0xe5, 0xcd, 0xc2, 0x16, 0x6c,
4123 0x3f, 0xe8, 0xa4, 0x7b, 0xe8, 0xe4, 0xa4, 0xee, 0x1c, 0x72, 0x28, 0x3e, 0xd2, 0xcc, 0x34, 0xf2,
4124 0xdb, 0x50, 0x9f, 0x47, 0x2c, 0x14, 0x6b, 0xd4, 0x70, 0x0d, 0xed, 0xd2, 0x35, 0x8e, 0x22, 0x16,
4125 0x8a, 0x25, 0xce, 0x27, 0x91, 0x21, 0x34, 0x43, 0x36, 0x61, 0x21, 0xf3, 0xc6, 0x4c, 0x2c, 0xb3,
4126 0x82, 0xcb, 0x7c, 0x70, 0xe9, 0x32, 0x34, 0x81, 0x8b, 0xb5, 0x16, 0xa6, 0xb7, 0xb7, 0x00, 0xce,
4127 0x85, 0x25, 0x2b, 0x50, 0x78, 0xd9, 0xaa, 0x6c, 0x2a, 0x5b, 0x05, 0x5a, 0x78, 0xc9, 0x47, 0x67,
4128 0xad, 0xaa, 0x18, 0x9d, 0xb5, 0xff, 0xa9, 0x00, 0xf5, 0x54, 0x26, 0x72, 0x0b, 0xca, 0x6c, 0x66,
4129 0xbb, 0xd3, 0x56, 0x7d, 0x53, 0xd9, 0xaa, 0x53, 0x31, 0x20, 0xf7, 0xa1, 0x61, 0xcf, 0xe3, 0x13,
4130 0xcb, 0xf1, 0x67, 0xb6, 0xeb, 0xb5, 0x00, 0x79, 0xc0, 0x49, 0x3d, 0xa4, 0x90, 0x36, 0xd4, 0x3c,
4131 0x77, 0xfc, 0xdc, 0xb3, 0x67, 0xac, 0xd5, 0xc0, 0x73, 0x48, 0xc7, 0xe4, 0x13, 0x20, 0x13, 0xe6,
4132 0xb0, 0xd0, 0x8e, 0x99, 0x63, 0xb9, 0x0e, 0xf3, 0x62, 0x37, 0x3e, 0x6b, 0xdd, 0x46, 0xd4, 0x7a,
4133 0xca, 0x31, 0x24, 0x23, 0x0f, 0x0f, 0x42, 0xff, 0xd4, 0x75, 0x58, 0xd8, 0xba, 0xb3, 0x00, 0x3f,
4134 0x94, 0x8c, 0xf6, 0xbf, 0x17, 0xa0, 0x99, 0xd7, 0x05, 0x51, 0xa1, 0x68, 0x07, 0x41, 0x6b, 0x15,
4135 0xa5, 0xe4, 0x8f, 0xe4, 0x6d, 0x00, 0x2e, 0x8a, 0x15, 0x05, 0xf6, 0x98, 0xb5, 0x6e, 0xe1, 0x5a,
4136 0x75, 0x4e, 0x19, 0x71, 0x02, 0x39, 0x82, 0x46, 0x60, 0xc7, 0x27, 0x6c, 0xca, 0x66, 0xcc, 0x8b,
4137 0x5b, 0xcd, 0xcd, 0xe2, 0x16, 0x6c, 0x7f, 0x7e, 0x4d, 0xd5, 0x77, 0x0e, 0xed, 0xf8, 0x44, 0x17,
4138 0x53, 0x69, 0x76, 0x9d, 0xb6, 0x0e, 0x8d, 0x0c, 0x8f, 0x10, 0x28, 0xc5, 0x67, 0x01, 0x6b, 0xad,
4139 0xa1, 0x5c, 0xf8, 0x4c, 0x9a, 0xa0, 0xb8, 0x4e, 0x4b, 0x45, 0xf3, 0x57, 0x5c, 0x87, 0x63, 0x50,
4140 0x87, 0xeb, 0x28, 0x22, 0x3e, 0x6b, 0xff, 0x51, 0x86, 0x5a, 0x22, 0x00, 0xe9, 0x42, 0x75, 0xc6,
4141 0x6c, 0xcf, 0xf5, 0x8e, 0xd1, 0x69, 0x9a, 0xdb, 0x6f, 0x2e, 0x11, 0xb3, 0x73, 0x20, 0x20, 0x3b,
4142 0x30, 0x18, 0x5a, 0x07, 0x7a, 0x77, 0x60, 0x0c, 0xf6, 0x69, 0x32, 0x8f, 0x1f, 0xa6, 0x7c, 0xb4,
4143 0xe6, 0xa1, 0x8b, 0x9e, 0x55, 0xa7, 0x20, 0x49, 0x47, 0xa1, 0x9b, 0x0a, 0x51, 0x14, 0x82, 0xe2,
4144 0x21, 0x76, 0xa0, 0x9c, 0xb8, 0x88, 0xb2, 0xd5, 0xd8, 0x6e, 0x5d, 0xa6, 0x1c, 0x2a, 0x60, 0xdc,
4145 0x20, 0x66, 0xf3, 0x69, 0xec, 0x06, 0x53, 0xee, 0x76, 0xca, 0x56, 0x8d, 0xa6, 0x63, 0xf2, 0x1e,
4146 0x40, 0xc4, 0xec, 0x70, 0x7c, 0x62, 0x3f, 0x9b, 0xb2, 0x56, 0x85, 0x7b, 0xf6, 0x4e, 0x79, 0x62,
4147 0x4f, 0x23, 0x46, 0x33, 0x0c, 0x62, 0xc3, 0xdd, 0x49, 0x1c, 0x59, 0xb1, 0xff, 0x9c, 0x79, 0xee,
4148 0x2b, 0x9b, 0x07, 0x12, 0xcb, 0x0f, 0xf8, 0x0f, 0xfa, 0x58, 0x73, 0xfb, 0xc3, 0x65, 0x5b, 0x7f,
4149 0x14, 0x47, 0x66, 0x66, 0xc6, 0x10, 0x27, 0xd0, 0xdb, 0x93, 0x65, 0x64, 0xd2, 0x86, 0xca, 0xd4,
4150 0x1f, 0xdb, 0x53, 0xd6, 0xaa, 0x73, 0x2d, 0xec, 0x28, 0xcc, 0xa3, 0x92, 0xa2, 0xfd, 0xb3, 0x02,
4151 0x55, 0xa9, 0x47, 0xd2, 0x84, 0x8c, 0x26, 0xd5, 0x37, 0x48, 0x0d, 0x4a, 0xbb, 0xfd, 0xe1, 0xae,
4152 0xda, 0xe4, 0x4f, 0xa6, 0xfe, 0xbd, 0xa9, 0xae, 0x71, 0xcc, 0xee, 0x53, 0x53, 0x1f, 0x99, 0x94,
4153 0x63, 0x54, 0xb2, 0x0e, 0xab, 0x5d, 0x73, 0x78, 0x60, 0xed, 0x75, 0x4d, 0x7d, 0x7f, 0x48, 0x9f,
4154 0xaa, 0x05, 0xb2, 0x0a, 0x75, 0x24, 0xf5, 0x8d, 0xc1, 0x13, 0x55, 0xe1, 0x33, 0x70, 0x68, 0x1a,
4155 0x66, 0x5f, 0x57, 0x8b, 0x44, 0x85, 0x15, 0x31, 0x63, 0x38, 0x30, 0xf5, 0x81, 0xa9, 0x96, 0x52,
4156 0xca, 0xe8, 0xe8, 0xe0, 0xa0, 0x4b, 0x9f, 0xaa, 0x65, 0xb2, 0x06, 0x0d, 0xa4, 0x74, 0x8f, 0xcc,
4157 0xc7, 0x43, 0xaa, 0x56, 0x48, 0x03, 0xaa, 0xfb, 0x3d, 0xeb, 0xbb, 0xc7, 0xfa, 0x40, 0xad, 0x92,
4158 0x15, 0xa8, 0xed, 0xf7, 0x2c, 0xfd, 0xa0, 0x6b, 0xf4, 0xd5, 0x1a, 0x9f, 0xbd, 0xaf, 0x0f, 0xe9,
4159 0x68, 0x64, 0x1d, 0x0e, 0x8d, 0x81, 0xa9, 0xd6, 0x49, 0x1d, 0xca, 0xfb, 0x3d, 0xcb, 0x38, 0x50,
4160 0x81, 0x10, 0x68, 0xee, 0xf7, 0xac, 0xc3, 0xc7, 0xc3, 0x81, 0x3e, 0x38, 0x3a, 0xd8, 0xd5, 0xa9,
4161 0xda, 0x20, 0xb7, 0x40, 0xe5, 0xb4, 0xe1, 0xc8, 0xec, 0xf6, 0xbb, 0xbd, 0x1e, 0xd5, 0x47, 0x23,
4162 0x75, 0x85, 0x4b, 0xbd, 0xdf, 0xb3, 0x68, 0xd7, 0xe4, 0xfb, 0x5a, 0xe5, 0x2f, 0xe4, 0x7b, 0x7f,
4163 0xa2, 0x3f, 0x55, 0xd7, 0xf9, 0x2b, 0xf4, 0x81, 0x69, 0x98, 0x4f, 0xad, 0x43, 0x3a, 0x34, 0x87,
4164 0xea, 0x06, 0x17, 0xd0, 0x18, 0xf4, 0xf4, 0xef, 0xad, 0x6f, 0xbb, 0xfd, 0x23, 0x5d, 0x25, 0xda,
4165 0x8f, 0xe1, 0xf6, 0xd2, 0x33, 0xe1, 0xaa, 0x7b, 0x6c, 0x1e, 0xf4, 0xd5, 0x02, 0x7f, 0xe2, 0x9b,
4166 0x52, 0x15, 0xed, 0x0f, 0xa0, 0xc4, 0x5d, 0x86, 0x7c, 0x06, 0xd5, 0xc4, 0x1b, 0x0b, 0xe8, 0x8d,
4167 0x77, 0xb3, 0x67, 0x6d, 0xc7, 0x27, 0x9d, 0xc4, 0xe3, 0x12, 0x5c, 0xbb, 0x0b, 0xd5, 0x45, 0x4f,
4168 0x53, 0x2e, 0x78, 0x5a, 0xf1, 0x82, 0xa7, 0x95, 0x32, 0x9e, 0x66, 0x43, 0x3d, 0xf5, 0xed, 0x9b,
4169 0x47, 0x91, 0x07, 0x50, 0xe2, 0xde, 0xdf, 0x6a, 0xa2, 0x87, 0xac, 0x2d, 0x08, 0x4c, 0x91, 0xa9,
4170 0xfd, 0x43, 0x01, 0x4a, 0x3c, 0xda, 0x9e, 0x07, 0xda, 0xc2, 0x15, 0x81, 0x56, 0xb9, 0x32, 0xd0,
4171 0x16, 0xaf, 0x15, 0x68, 0x2b, 0x37, 0x0b, 0xb4, 0xd5, 0x4b, 0x02, 0xad, 0xf6, 0x67, 0x45, 0x68,
4172 0xe8, 0x38, 0xf3, 0x10, 0x13, 0xfd, 0xfb, 0x50, 0x7c, 0xce, 0xce, 0x50, 0x3f, 0x8d, 0xed, 0x5b,
4173 0x99, 0xdd, 0xa6, 0x2a, 0xa4, 0x1c, 0x40, 0xb6, 0x61, 0x45, 0xbc, 0xd0, 0x3a, 0x0e, 0xfd, 0x79,
4174 0xd0, 0x52, 0x97, 0xab, 0xa7, 0x21, 0x40, 0xfb, 0x1c, 0x43, 0xde, 0x83, 0xb2, 0xff, 0xc2, 0x63,
4175 0x21, 0xc6, 0xc1, 0x3c, 0x98, 0x2b, 0x8f, 0x0a, 0x2e, 0x79, 0x08, 0xa5, 0xe7, 0xae, 0xe7, 0xe0,
4176 0x19, 0xe6, 0x23, 0x61, 0x46, 0xd0, 0xce, 0x13, 0xd7, 0x73, 0x28, 0x02, 0xc9, 0x3d, 0xa8, 0xf1,
4177 0x5f, 0x8c, 0x7b, 0x65, 0xdc, 0x68, 0x95, 0x8f, 0x79, 0xd0, 0x7b, 0x08, 0xb5, 0x40, 0xc6, 0x10,
4178 0x4c, 0x00, 0x8d, 0xed, 0x8d, 0x25, 0xe1, 0x85, 0xa6, 0x20, 0xf2, 0x15, 0xac, 0x84, 0xf6, 0x0b,
4179 0x2b, 0x9d, 0xb4, 0x76, 0xf9, 0xa4, 0x46, 0x68, 0xbf, 0x48, 0x23, 0x38, 0x81, 0x52, 0x68, 0x7b,
4180 0xcf, 0x5b, 0x64, 0xb3, 0xb0, 0x55, 0xa6, 0xf8, 0xac, 0x7d, 0x01, 0x25, 0x2e, 0x25, 0x8f, 0x08,
4181 0xfb, 0x3d, 0xf4, 0xff, 0xee, 0x9e, 0xa9, 0x16, 0x12, 0x7f, 0xfe, 0x96, 0x47, 0x03, 0x45, 0x72,
4182 0x0f, 0xf4, 0xd1, 0xa8, 0xbb, 0xaf, 0xab, 0x45, 0xad, 0x07, 0xeb, 0x7b, 0xfe, 0x2c, 0xf0, 0x23,
4183 0x37, 0x66, 0xe9, 0xf2, 0xf7, 0xa0, 0xe6, 0x7a, 0x0e, 0x7b, 0x69, 0xb9, 0x0e, 0x9a, 0x56, 0x91,
4184 0x56, 0x71, 0x6c, 0x38, 0xdc, 0xe4, 0x4e, 0x65, 0x31, 0x55, 0xe4, 0x26, 0x87, 0x03, 0xed, 0x2f,
4185 0x15, 0x28, 0x1b, 0x1c, 0xc1, 0x8d, 0x4f, 0x9e, 0x14, 0x7a, 0x8f, 0x30, 0x4c, 0x10, 0x24, 0x93,
4186 0xfb, 0x50, 0x1b, 0x6a, 0xb6, 0x37, 0x66, 0xbc, 0xe2, 0xc3, 0x3c, 0x50, 0xa3, 0xe9, 0x98, 0x7c,
4187 0x99, 0xd1, 0x9f, 0x82, 0x2e, 0x7b, 0x2f, 0xa3, 0x0a, 0x7c, 0xc1, 0x12, 0x2d, 0xb6, 0xff, 0xaa,
4188 0x90, 0x49, 0x6e, 0xcb, 0x12, 0x4f, 0x1f, 0xea, 0x8e, 0x1b, 0x32, 0xac, 0x23, 0xe5, 0x41, 0x3f,
4189 0xb8, 0x74, 0xe1, 0x4e, 0x2f, 0x81, 0xee, 0xd4, 0xbb, 0xa3, 0x3d, 0x7d, 0xd0, 0xe3, 0x99, 0xef,
4190 0x7c, 0x01, 0xed, 0x23, 0xa8, 0xa7, 0x10, 0x0c, 0xc7, 0x09, 0x48, 0x2d, 0x70, 0xf5, 0xf6, 0xf4,
4191 0x74, 0xac, 0x68, 0x7f, 0xad, 0x40, 0x33, 0xd5, 0xaf, 0xd0, 0xd0, 0x6d, 0xa8, 0xd8, 0x41, 0x90,
4192 0xa8, 0xb6, 0x4e, 0xcb, 0x76, 0x10, 0x18, 0x8e, 0x8c, 0x2d, 0x0a, 0x6a, 0x9b, 0xc7, 0x96, 0x4f,
4193 0x01, 0x1c, 0x36, 0x71, 0x3d, 0x17, 0x85, 0x2e, 0xa2, 0xc1, 0xab, 0x8b, 0x42, 0xd3, 0x0c, 0x86,
4194 0x7c, 0x09, 0xe5, 0x28, 0xb6, 0x63, 0x91, 0x2b, 0x9b, 0xdb, 0xf7, 0x33, 0xe0, 0xbc, 0x08, 0x9d,
4195 0x11, 0x87, 0x51, 0x81, 0x26, 0x5f, 0xc1, 0x2d, 0xdf, 0x9b, 0x9e, 0x59, 0xf3, 0x88, 0x59, 0xee,
4196 0xc4, 0x0a, 0xd9, 0x0f, 0x73, 0x37, 0x64, 0x4e, 0x3e, 0xa7, 0xae, 0x73, 0xc8, 0x51, 0xc4, 0x8c,
4197 0x09, 0x95, 0x7c, 0xed, 0x6b, 0x28, 0xe3, 0x3a, 0x7c, 0xcf, 0xdf, 0x51, 0xc3, 0xd4, 0xad, 0xe1,
4198 0xa0, 0xff, 0x54, 0xe8, 0x80, 0xea, 0xdd, 0x9e, 0x85, 0x44, 0x55, 0xe1, 0xc1, 0xbe, 0xa7, 0xf7,
4199 0x75, 0x53, 0xef, 0xa9, 0x45, 0x9e, 0x3d, 0x74, 0x4a, 0x87, 0x54, 0x2d, 0x69, 0xff, 0x53, 0x80,
4200 0x15, 0x94, 0xe7, 0xd0, 0x8f, 0xe2, 0x89, 0xfb, 0x92, 0xec, 0x41, 0x43, 0x98, 0xdd, 0xa9, 0x2c,
4201 0xe8, 0xb9, 0x33, 0x68, 0x8b, 0x7b, 0x96, 0x68, 0x31, 0x90, 0x75, 0xb4, 0x9b, 0x3e, 0x27, 0x21,
4202 0x45, 0x41, 0xa7, 0xbf, 0x22, 0xa4, 0xbc, 0x05, 0x95, 0x67, 0x6c, 0xe2, 0x87, 0x22, 0x04, 0xd6,
4203 0x76, 0x4a, 0x71, 0x38, 0x67, 0x54, 0xd2, 0xda, 0x36, 0xc0, 0xf9, 0xfa, 0xe4, 0x01, 0xac, 0x26,
4204 0xc6, 0x66, 0xa1, 0x71, 0x89, 0x93, 0x5b, 0x49, 0x88, 0x83, 0x5c, 0x75, 0xa3, 0x5c, 0xab, 0xba,
4205 0xd1, 0xbe, 0x86, 0xd5, 0x64, 0x3f, 0xe2, 0xfc, 0x54, 0x21, 0x79, 0x01, 0x63, 0xca, 0x82, 0x8c,
4206 0xca, 0x45, 0x19, 0xb5, 0x9f, 0x41, 0x6d, 0xe4, 0xd9, 0x41, 0x74, 0xe2, 0xc7, 0xdc, 0x7a, 0xe2,
4207 0x48, 0xfa, 0xaa, 0x12, 0x47, 0x9a, 0x06, 0x15, 0x7e, 0x38, 0xf3, 0x88, 0xbb, 0xbf, 0x31, 0xe8,
4208 0xee, 0x99, 0xc6, 0xb7, 0xba, 0xfa, 0x06, 0x01, 0xa8, 0xc8, 0xe7, 0x82, 0xa6, 0x41, 0xd3, 0x90,
4209 0xed, 0xd8, 0x63, 0x66, 0x3b, 0x2c, 0xe4, 0x12, 0xfc, 0xe0, 0x47, 0x89, 0x04, 0x3f, 0xf8, 0x91,
4210 0xf6, 0x17, 0x05, 0x68, 0x98, 0xa1, 0xed, 0x45, 0xb6, 0x30, 0xf7, 0xcf, 0xa0, 0x72, 0x82, 0x58,
4211 0x74, 0xa3, 0xc6, 0x82, 0x7f, 0x66, 0x17, 0xa3, 0x12, 0x48, 0xee, 0x40, 0xe5, 0xc4, 0xf6, 0x9c,
4212 0xa9, 0xd0, 0x5a, 0x85, 0xca, 0x51, 0x92, 0x1b, 0x95, 0xf3, 0xdc, 0xb8, 0x05, 0x2b, 0x33, 0x3b,
4213 0x7c, 0x6e, 0x8d, 0x4f, 0x6c, 0xef, 0x98, 0x45, 0xf2, 0x60, 0xa4, 0x05, 0x36, 0x38, 0x6b, 0x4f,
4214 0x70, 0xb4, 0xbf, 0x5f, 0x81, 0xf2, 0x37, 0x73, 0x16, 0x9e, 0x65, 0x04, 0xfa, 0xe0, 0xba, 0x02,
4215 0xc9, 0x17, 0x17, 0x2e, 0x4b, 0xca, 0x6f, 0x2f, 0x26, 0x65, 0x22, 0x53, 0x84, 0xc8, 0x95, 0x22,
4216 0x0b, 0x7c, 0x9a, 0x09, 0x63, 0xeb, 0x57, 0xd8, 0xda, 0x79, 0x70, 0x7b, 0x08, 0x95, 0x89, 0x3b,
4217 0x8d, 0x51, 0x75, 0x8b, 0xd5, 0x08, 0xee, 0xa5, 0xf3, 0x08, 0xd9, 0x54, 0xc2, 0xc8, 0xbb, 0xb0,
4218 0x22, 0x2a, 0x59, 0xeb, 0x07, 0xce, 0xc6, 0x82, 0x95, 0xf7, 0xa6, 0x48, 0x13, 0xbb, 0xff, 0x18,
4219 0xca, 0x7e, 0xc8, 0x37, 0x5f, 0xc7, 0x25, 0xef, 0x5c, 0x58, 0x72, 0xc8, 0xb9, 0x54, 0x80, 0xc8,
4220 0x87, 0x50, 0x3a, 0x71, 0xbd, 0x18, 0xb3, 0x46, 0x73, 0xfb, 0xf6, 0x05, 0xf0, 0x63, 0xd7, 0x8b,
4221 0x29, 0x42, 0x78, 0x98, 0x1f, 0xfb, 0x73, 0x2f, 0x6e, 0xdd, 0xc5, 0x0c, 0x23, 0x06, 0xe4, 0x1e,
4222 0x54, 0xfc, 0xc9, 0x24, 0x62, 0x31, 0x76, 0x96, 0xe5, 0x9d, 0xc2, 0xa7, 0x54, 0x12, 0xf8, 0x84,
4223 0xa9, 0x3b, 0x73, 0x63, 0xec, 0x43, 0xca, 0x54, 0x0c, 0xc8, 0x2e, 0xac, 0x8d, 0xfd, 0x59, 0xe0,
4224 0x4e, 0x99, 0x63, 0x8d, 0xe7, 0x61, 0xe4, 0x87, 0xad, 0x77, 0x2e, 0x1c, 0xd3, 0x9e, 0x44, 0xec,
4225 0x21, 0x80, 0x36, 0xc7, 0xb9, 0x31, 0x31, 0x60, 0x83, 0x79, 0x8e, 0xb5, 0xb8, 0xce, 0xfd, 0xd7,
4226 0xad, 0xb3, 0xce, 0x3c, 0x27, 0x4f, 0x4a, 0xc4, 0xc1, 0x48, 0x68, 0x61, 0xcc, 0x68, 0x6d, 0x60,
4227 0x90, 0xb9, 0x77, 0x69, 0xac, 0x14, 0xe2, 0x64, 0xc2, 0xf7, 0x6f, 0xc0, 0x2d, 0x19, 0x22, 0xad,
4228 0x80, 0x85, 0x13, 0x36, 0x8e, 0xad, 0x60, 0x6a, 0x7b, 0x58, 0xca, 0xa5, 0xc6, 0x4a, 0x24, 0xe4,
4229 0x50, 0x20, 0x0e, 0xa7, 0xb6, 0x47, 0x34, 0xa8, 0x3f, 0x67, 0x67, 0x91, 0xc5, 0x23, 0x29, 0x76,
4230 0xae, 0x29, 0xba, 0xc6, 0xe9, 0x43, 0x6f, 0x7a, 0x46, 0x7e, 0x02, 0x8d, 0xf8, 0xdc, 0xdb, 0xb0,
4231 0x61, 0x6d, 0xe4, 0x4e, 0x35, 0xe3, 0x8b, 0x34, 0x0b, 0x25, 0xf7, 0xa1, 0x2a, 0x35, 0xd4, 0xba,
4232 0x97, 0x5d, 0x3b, 0xa1, 0xf2, 0xc4, 0x3c, 0xb1, 0xdd, 0xa9, 0x7f, 0xca, 0x42, 0x6b, 0x16, 0xb5,
4233 0xda, 0xe2, 0xb6, 0x24, 0x21, 0x1d, 0x44, 0xdc, 0x4f, 0xa3, 0x38, 0xf4, 0xbd, 0xe3, 0xd6, 0x26,
4234 0xde, 0x93, 0xc8, 0xd1, 0xc5, 0xe0, 0xf7, 0x2e, 0x66, 0xfe, 0x7c, 0xf0, 0xfb, 0x1c, 0xee, 0x60,
4235 0x65, 0x66, 0x3d, 0x3b, 0xb3, 0xf2, 0x68, 0x0d, 0xd1, 0x1b, 0xc8, 0xdd, 0x3d, 0x3b, 0xcc, 0x4e,
4236 0x6a, 0x43, 0xcd, 0x71, 0xa3, 0xd8, 0xf5, 0xc6, 0x71, 0xab, 0x85, 0xef, 0x4c, 0xc7, 0xe4, 0x33,
4237 0xb8, 0x3d, 0x73, 0x3d, 0x2b, 0xb2, 0x27, 0xcc, 0x8a, 0x5d, 0xee, 0x9b, 0x6c, 0xec, 0x7b, 0x4e,
4238 0xd4, 0x7a, 0x80, 0x82, 0x93, 0x99, 0xeb, 0x8d, 0xec, 0x09, 0x33, 0xdd, 0x19, 0x1b, 0x09, 0x0e,
4239 0xf9, 0x08, 0xd6, 0x11, 0x1e, 0xb2, 0x60, 0xea, 0x8e, 0x6d, 0xf1, 0xfa, 0x1f, 0xe1, 0xeb, 0xd7,
4240 0x38, 0x83, 0x0a, 0x3a, 0xbe, 0xfa, 0x63, 0x68, 0x06, 0x2c, 0x8c, 0xdc, 0x28, 0xb6, 0xa4, 0x45,
4241 0xbf, 0x97, 0xd5, 0xda, 0xaa, 0x64, 0x0e, 0x91, 0xd7, 0xfe, 0xcf, 0x02, 0x54, 0x84, 0x73, 0x92,
4242 0x4f, 0x41, 0xf1, 0x03, 0xbc, 0x06, 0x69, 0x6e, 0x6f, 0x5e, 0xe2, 0xc1, 0x9d, 0x61, 0xc0, 0xeb,
4243 0x5e, 0x3f, 0xa4, 0x8a, 0x1f, 0xdc, 0xb8, 0x28, 0xd4, 0xfe, 0x10, 0x6a, 0xc9, 0x02, 0xbc, 0xbc,
4244 0xe8, 0xeb, 0xa3, 0x91, 0x65, 0x3e, 0xee, 0x0e, 0xd4, 0x02, 0xb9, 0x03, 0x24, 0x1d, 0x5a, 0x43,
4245 0x6a, 0xe9, 0xdf, 0x1c, 0x75, 0xfb, 0xaa, 0x82, 0x5d, 0x1a, 0xd5, 0xbb, 0xa6, 0x4e, 0x05, 0xb2,
4246 0x48, 0xee, 0xc1, 0xed, 0x2c, 0xe5, 0x1c, 0x5c, 0xc2, 0x14, 0x8c, 0x8f, 0x65, 0x52, 0x01, 0xc5,
4247 0x18, 0xa8, 0x15, 0x9e, 0x16, 0xf4, 0xef, 0x8d, 0x91, 0x39, 0x52, 0xab, 0xed, 0xbf, 0x29, 0x40,
4248 0x19, 0xc3, 0x06, 0x3f, 0x9f, 0x54, 0x72, 0x71, 0x5d, 0x73, 0x5e, 0xb9, 0x1a, 0xd9, 0x92, 0xaa,
4249 0x81, 0x01, 0x65, 0x73, 0x79, 0xf4, 0xf9, 0xb5, 0xd6, 0x53, 0x3f, 0x85, 0x12, 0x8f, 0x52, 0xbc,
4250 0x43, 0x1c, 0xd2, 0x9e, 0x4e, 0xad, 0x47, 0x06, 0x1d, 0xf1, 0x2a, 0x97, 0x40, 0xb3, 0x3b, 0xd8,
4251 0xd3, 0x47, 0xe6, 0x30, 0xa1, 0xa1, 0x56, 0x1e, 0x19, 0x7d, 0x33, 0x45, 0x15, 0xb5, 0x9f, 0xd7,
4252 0x60, 0x35, 0x89, 0x09, 0x22, 0x82, 0x3e, 0x82, 0x46, 0x10, 0xba, 0x33, 0x3b, 0x3c, 0x8b, 0xc6,
4253 0xb6, 0x87, 0x49, 0x01, 0xb6, 0x7f, 0xb4, 0x24, 0xaa, 0x88, 0x1d, 0x1d, 0x0a, 0xec, 0x68, 0x6c,
4254 0x7b, 0x34, 0x3b, 0x91, 0xf4, 0x61, 0x75, 0xc6, 0xc2, 0x63, 0xf6, 0x7b, 0xbe, 0xeb, 0xe1, 0x4a,
4255 0x55, 0x8c, 0xc8, 0xef, 0x5f, 0xba, 0xd2, 0x01, 0x47, 0xff, 0x8e, 0xef, 0x7a, 0xb8, 0x56, 0x7e,
4256 0x32, 0xf9, 0x04, 0xea, 0xa2, 0x12, 0x72, 0xd8, 0x04, 0x63, 0xc5, 0xb2, 0xda, 0x4f, 0xd4, 0xe8,
4257 0x3d, 0x36, 0xc9, 0xc4, 0x65, 0xb8, 0x34, 0x2e, 0x37, 0xb2, 0x71, 0xf9, 0xcd, 0x6c, 0x2c, 0x5a,
4258 0x11, 0x55, 0x78, 0x1a, 0x84, 0x2e, 0x38, 0x7c, 0x6b, 0x89, 0xc3, 0x77, 0x60, 0x23, 0xf1, 0x55,
4259 0xcb, 0xf5, 0x26, 0xee, 0x4b, 0x2b, 0x72, 0x5f, 0x89, 0xd8, 0x53, 0xa6, 0xeb, 0x09, 0xcb, 0xe0,
4260 0x9c, 0x91, 0xfb, 0x8a, 0x11, 0x23, 0xe9, 0xe0, 0x64, 0x0e, 0x5c, 0xc5, 0xab, 0xc9, 0xf7, 0x2e,
4261 0x55, 0x8f, 0x68, 0xbe, 0x64, 0x46, 0xcc, 0x4d, 0x6d, 0xff, 0x52, 0x81, 0x46, 0xe6, 0x1c, 0x78,
4262 0xf6, 0x16, 0xca, 0x42, 0x61, 0xc5, 0x55, 0x94, 0x50, 0x1f, 0x4a, 0xfa, 0x26, 0xd4, 0xa3, 0xd8,
4263 0x0e, 0x63, 0x8b, 0x17, 0x57, 0xb2, 0xdd, 0x45, 0xc2, 0x13, 0x76, 0x46, 0x3e, 0x80, 0x35, 0xc1,
4264 0x74, 0xbd, 0xf1, 0x74, 0x1e, 0xb9, 0xa7, 0xa2, 0x99, 0xaf, 0xd1, 0x26, 0x92, 0x8d, 0x84, 0x4a,
4265 0xee, 0x42, 0x95, 0x67, 0x21, 0xbe, 0x86, 0x68, 0xfa, 0x2a, 0xcc, 0x73, 0xf8, 0x0a, 0x0f, 0x60,
4266 0x95, 0x33, 0xce, 0xe7, 0x57, 0xc4, 0x2d, 0x33, 0xf3, 0x9c, 0xf3, 0xd9, 0x1d, 0xd8, 0x10, 0xaf,
4267 0x09, 0x44, 0xf1, 0x2a, 0x2b, 0xdc, 0x3b, 0xa8, 0xd8, 0x75, 0x64, 0xc9, 0xb2, 0x56, 0x14, 0x9c,
4268 0x1f, 0x01, 0xcf, 0x5e, 0x0b, 0xe8, 0xbb, 0x22, 0x94, 0x31, 0xcf, 0xc9, 0x61, 0x77, 0xe1, 0x1d,
4269 0x8e, 0x9d, 0x7b, 0x76, 0x10, 0x4c, 0x5d, 0xe6, 0x58, 0x53, 0xff, 0x18, 0x43, 0x66, 0x14, 0xdb,
4270 0xb3, 0xc0, 0x9a, 0x47, 0xad, 0x0d, 0x0c, 0x99, 0x6d, 0xe6, 0x39, 0x47, 0x09, 0xa8, 0xef, 0x1f,
4271 0x9b, 0x09, 0xe4, 0x28, 0x6a, 0xff, 0x3e, 0xac, 0xe6, 0xec, 0x71, 0x41, 0xa7, 0x35, 0x74, 0xfe,
4272 0x8c, 0x4e, 0xdf, 0x85, 0x95, 0x20, 0x64, 0xe7, 0xa2, 0xd5, 0x51, 0xb4, 0x86, 0xa0, 0x09, 0xb1,
4273 0xb6, 0x60, 0x05, 0x79, 0x96, 0x20, 0xe6, 0xf3, 0x63, 0x03, 0x59, 0x87, 0xc8, 0x69, 0xbf, 0x80,
4274 0x95, 0xec, 0x69, 0x93, 0x77, 0x33, 0x69, 0xa1, 0x99, 0xcb, 0x93, 0x69, 0x76, 0x48, 0x2a, 0xb2,
4275 0xf5, 0x4b, 0x2a, 0x32, 0x72, 0x9d, 0x8a, 0x4c, 0xfb, 0x2f, 0xd9, 0x9c, 0x65, 0x2a, 0x84, 0x9f,
4276 0x41, 0x2d, 0x90, 0xf5, 0x38, 0x5a, 0x52, 0xfe, 0x12, 0x3e, 0x0f, 0xee, 0x24, 0x95, 0x3b, 0x4d,
4277 0xe7, 0xb4, 0xff, 0x56, 0x81, 0x5a, 0x5a, 0xd0, 0xe7, 0x2c, 0xef, 0xcd, 0x05, 0xcb, 0x3b, 0x90,
4278 0x1a, 0x16, 0x0a, 0x7c, 0x1b, 0xa3, 0xc5, 0x27, 0xaf, 0x7f, 0xd7, 0xc5, 0xb6, 0xe7, 0x34, 0xdb,
4279 0xf6, 0x6c, 0xbe, 0xae, 0xed, 0xf9, 0xe4, 0xa2, 0xc1, 0xbf, 0x95, 0xe9, 0x2d, 0x16, 0xcc, 0xbe,
4280 0xfd, 0x7d, 0xae, 0x0f, 0xca, 0x26, 0x84, 0x77, 0xc4, 0x7e, 0xd2, 0x84, 0x90, 0xb6, 0x3f, 0xf7,
4281 0xaf, 0xd7, 0xfe, 0x6c, 0x43, 0x45, 0xea, 0xfc, 0x0e, 0x54, 0x64, 0x4d, 0x27, 0x1b, 0x04, 0x31,
4282 0x3a, 0x6f, 0x10, 0x0a, 0xb2, 0x4e, 0xd7, 0x7e, 0xae, 0x40, 0x59, 0x0f, 0x43, 0x3f, 0xd4, 0xfe,
4283 0x48, 0x81, 0x3a, 0x3e, 0xed, 0xf9, 0x0e, 0xe3, 0xd9, 0x60, 0xb7, 0xdb, 0xb3, 0xa8, 0xfe, 0xcd,
4284 0x91, 0x8e, 0xd9, 0xa0, 0x0d, 0x77, 0xf6, 0x86, 0x83, 0xbd, 0x23, 0x4a, 0xf5, 0x81, 0x69, 0x99,
4285 0xb4, 0x3b, 0x18, 0xf1, 0xb6, 0x67, 0x38, 0x50, 0x15, 0x9e, 0x29, 0x8c, 0x81, 0xa9, 0xd3, 0x41,
4286 0xb7, 0x6f, 0x89, 0x56, 0xb4, 0x88, 0x77, 0xb3, 0xba, 0xde, 0xb3, 0xf0, 0xd6, 0x51, 0x2d, 0xf1,
4287 0x96, 0xd5, 0x34, 0x0e, 0xf4, 0xe1, 0x91, 0xa9, 0x96, 0xc9, 0x6d, 0x58, 0x3f, 0xd4, 0xe9, 0x81,
4288 0x31, 0x1a, 0x19, 0xc3, 0x81, 0xd5, 0xd3, 0x07, 0x86, 0xde, 0x53, 0x2b, 0x7c, 0x9d, 0x5d, 0x63,
4289 0xdf, 0xec, 0xee, 0xf6, 0x75, 0xb9, 0x4e, 0x95, 0x6c, 0xc2, 0x5b, 0x7b, 0xc3, 0x83, 0x03, 0xc3,
4290 0x34, 0xf5, 0x9e, 0xb5, 0x7b, 0x64, 0x5a, 0x23, 0xd3, 0xe8, 0xf7, 0xad, 0xee, 0xe1, 0x61, 0xff,
4291 0x29, 0x4f, 0x60, 0x35, 0x72, 0x17, 0x36, 0xf6, 0xba, 0x87, 0xdd, 0x5d, 0xa3, 0x6f, 0x98, 0x4f,
4292 0xad, 0x9e, 0x31, 0xe2, 0xf3, 0x7b, 0x6a, 0x9d, 0x27, 0x6c, 0x93, 0x3e, 0xb5, 0xba, 0x7d, 0x14,
4293 0xcd, 0xd4, 0xad, 0xdd, 0xee, 0xde, 0x13, 0x7d, 0xd0, 0x53, 0x81, 0x0b, 0x30, 0xea, 0x3e, 0xd2,
4294 0x2d, 0x2e, 0x92, 0x65, 0x0e, 0x87, 0xd6, 0xb0, 0xdf, 0x53, 0x1b, 0xda, 0xbf, 0x14, 0xa1, 0xb4,
4295 0xe7, 0x47, 0x31, 0xf7, 0x46, 0xe1, 0xac, 0x2f, 0x42, 0x37, 0x66, 0xa2, 0x7f, 0x2b, 0x53, 0xd1,
4296 0x4b, 0x7f, 0x87, 0x24, 0x1e, 0x50, 0x32, 0x10, 0xeb, 0xd9, 0x19, 0xc7, 0x29, 0x88, 0x5b, 0x3b,
4297 0xc7, 0xed, 0x72, 0xb2, 0x88, 0x68, 0x78, 0x85, 0x23, 0xd7, 0x2b, 0x22, 0x4e, 0x06, 0x61, 0xb9,
4298 0xe0, 0xc7, 0x40, 0xb2, 0x20, 0xb9, 0x62, 0x09, 0x91, 0x6a, 0x06, 0x29, 0x96, 0xdc, 0x01, 0x18,
4299 0xfb, 0xb3, 0x99, 0x1b, 0x8f, 0xfd, 0x28, 0x96, 0x5f, 0xc8, 0xda, 0x39, 0x63, 0x8f, 0x62, 0x6e,
4300 0xf1, 0x33, 0x37, 0xe6, 0x8f, 0x34, 0x83, 0x26, 0x3b, 0x70, 0xcf, 0x0e, 0x82, 0xd0, 0x7f, 0xe9,
4301 0xce, 0xec, 0x98, 0x59, 0xdc, 0x73, 0xed, 0x63, 0x66, 0x39, 0x6c, 0x1a, 0xdb, 0xd8, 0x13, 0x95,
4302 0xe9, 0xdd, 0x0c, 0x60, 0x24, 0xf8, 0x3d, 0xce, 0xe6, 0x71, 0xd7, 0x75, 0xac, 0x88, 0xfd, 0x30,
4303 0xe7, 0x1e, 0x60, 0xcd, 0x03, 0xc7, 0xe6, 0x62, 0xd6, 0x45, 0x96, 0x72, 0x9d, 0x91, 0xe4, 0x1c,
4304 0x09, 0x46, 0xfb, 0x15, 0xc0, 0xb9, 0x14, 0x64, 0x1b, 0x6e, 0xf3, 0x3a, 0x9e, 0x45, 0x31, 0x73,
4305 0x2c, 0xb9, 0xdb, 0x60, 0x1e, 0x47, 0x18, 0xe2, 0xcb, 0x74, 0x23, 0x65, 0xca, 0x9b, 0xc2, 0x79,
4306 0x1c, 0x91, 0x9f, 0x40, 0xeb, 0xc2, 0x1c, 0x87, 0x4d, 0x19, 0x7f, 0x6d, 0x15, 0xa7, 0xdd, 0x59,
4307 0x98, 0xd6, 0x13, 0x5c, 0xed, 0x4f, 0x14, 0x80, 0x7d, 0x16, 0x53, 0xc1, 0xcd, 0x34, 0xb6, 0x95,
4308 0xeb, 0x36, 0xb6, 0xef, 0x27, 0x17, 0x08, 0xc5, 0xab, 0x63, 0xc0, 0x42, 0x97, 0xa1, 0xdc, 0xa4,
4309 0xcb, 0xc8, 0x35, 0x11, 0xc5, 0x2b, 0x9a, 0x88, 0x52, 0xae, 0x89, 0xf8, 0x18, 0x9a, 0xf6, 0x74,
4310 0xea, 0xbf, 0xe0, 0x05, 0x0d, 0x0b, 0x43, 0xe6, 0xa0, 0x11, 0x9c, 0xd7, 0xdb, 0xc8, 0xec, 0x49,
4311 0x9e, 0xf6, 0xe7, 0x0a, 0x34, 0x50, 0x15, 0x51, 0xe0, 0x7b, 0x11, 0x23, 0x5f, 0x42, 0x45, 0x5e,
4312 0x44, 0x8b, 0x8b, 0xfc, 0xb7, 0x33, 0xb2, 0x66, 0x70, 0xb2, 0x68, 0xa0, 0x12, 0xcc, 0x33, 0x42,
4313 0xe6, 0x75, 0x97, 0x2b, 0x25, 0x45, 0x91, 0xfb, 0x50, 0x73, 0x3d, 0x4b, 0xb4, 0xd4, 0x95, 0x4c,
4314 0x58, 0xac, 0xba, 0x1e, 0xd6, 0xb2, 0xed, 0x57, 0x50, 0x11, 0x2f, 0x21, 0x9d, 0x54, 0xa6, 0x8b,
4315 0xfa, 0xcb, 0xdc, 0x1c, 0xa7, 0xc2, 0xc8, 0xc3, 0x29, 0xbd, 0x2e, 0x40, 0xb7, 0xa0, 0x7a, 0xca,
4316 0x9b, 0x0f, 0xbc, 0xf4, 0xe3, 0xea, 0x4d, 0x86, 0xda, 0x1f, 0x97, 0x00, 0x0e, 0xe7, 0x4b, 0x0c,
4317 0xa4, 0x71, 0x5d, 0x03, 0xe9, 0xe4, 0xf4, 0xf8, 0x7a, 0x99, 0x7f, 0x75, 0x43, 0x59, 0xd2, 0x69,
4318 0x17, 0x6f, 0xda, 0x69, 0xdf, 0x87, 0x6a, 0x1c, 0xce, 0xb9, 0xa3, 0x08, 0x63, 0x4a, 0x5b, 0x5a,
4319 0x49, 0x25, 0x6f, 0x42, 0x79, 0xe2, 0x87, 0x63, 0x86, 0x8e, 0x95, 0xb2, 0x05, 0xed, 0xc2, 0x65,
4320 0x52, 0xed, 0xb2, 0xcb, 0x24, 0xde, 0xa0, 0x45, 0xf2, 0x1e, 0x0d, 0x0b, 0x99, 0x7c, 0x83, 0x96,
4321 0x5c, 0xb1, 0xd1, 0x14, 0x44, 0xbe, 0x81, 0xa6, 0x3d, 0x8f, 0x7d, 0xcb, 0xe5, 0x15, 0xda, 0xd4,
4322 0x1d, 0x9f, 0x61, 0xd9, 0xdd, 0xcc, 0x7f, 0xaf, 0x4f, 0x0f, 0xaa, 0xd3, 0x9d, 0xc7, 0xbe, 0xe1,
4323 0x1c, 0x22, 0x72, 0xa7, 0x2a, 0x93, 0x12, 0x5d, 0xb1, 0x33, 0x64, 0xed, 0xc7, 0xb0, 0x92, 0x85,
4324 0xf1, 0x04, 0x24, 0x81, 0xea, 0x1b, 0x3c, 0x3b, 0x8d, 0x78, 0x6a, 0x1b, 0x98, 0x46, 0xb7, 0xaf,
4325 0x16, 0xb4, 0x18, 0x1a, 0xb8, 0xbc, 0xf4, 0x8e, 0xeb, 0xba, 0xfd, 0x03, 0x28, 0x61, 0xf8, 0x55,
4326 0x2e, 0x7c, 0x0f, 0xc1, 0x98, 0x8b, 0xcc, 0xbc, 0xf9, 0x15, 0xb3, 0xe6, 0xf7, 0xdf, 0x05, 0x58,
4327 0x31, 0xfd, 0xf9, 0xf8, 0xe4, 0xa2, 0x01, 0xc2, 0xaf, 0x3b, 0x42, 0x2d, 0x31, 0x1f, 0xe5, 0xa6,
4328 0xe6, 0x93, 0x5a, 0x47, 0x71, 0x89, 0x75, 0xdc, 0xf4, 0xcc, 0xb5, 0x2f, 0x60, 0x55, 0x6e, 0x5e,
4329 0x6a, 0x3d, 0xd1, 0x66, 0xe1, 0x0a, 0x6d, 0x6a, 0xbf, 0x50, 0x60, 0x55, 0xc4, 0xf7, 0xff, 0xbb,
4330 0xd2, 0x2a, 0x37, 0x0c, 0xeb, 0xe5, 0x1b, 0x5d, 0x1e, 0xfd, 0xbf, 0xf4, 0x34, 0x6d, 0x08, 0xcd,
4331 0x44, 0x7d, 0x37, 0x50, 0xfb, 0x15, 0x46, 0xfc, 0x8b, 0x02, 0x34, 0x06, 0xec, 0xe5, 0x92, 0x20,
4332 0x5a, 0xbe, 0xee, 0x71, 0x7c, 0x98, 0x2b, 0x57, 0x1b, 0xdb, 0xeb, 0x59, 0x19, 0xc4, 0xd5, 0x63,
4333 0x52, 0xc1, 0xa6, 0xb7, 0xa8, 0xca, 0xf2, 0x5b, 0xd4, 0xd2, 0x62, 0xb7, 0x9e, 0xb9, 0xc5, 0x2b,
4334 0x2e, 0xbb, 0xc5, 0xd3, 0xfe, 0xad, 0x08, 0x0d, 0x6c, 0x90, 0x29, 0x8b, 0xe6, 0xd3, 0x38, 0x27,
4335 0x4c, 0xe1, 0x6a, 0x61, 0x3a, 0x50, 0x09, 0x71, 0x92, 0x74, 0xa5, 0x4b, 0x83, 0xbf, 0x40, 0x61,
4336 0x6b, 0xfc, 0xdc, 0x0d, 0x02, 0xe6, 0x58, 0x82, 0x92, 0x14, 0x30, 0x4d, 0x49, 0x16, 0x22, 0x44,
4337 0xbc, 0xfc, 0x9c, 0xf9, 0x21, 0x4b, 0x51, 0x45, 0xbc, 0x4f, 0x68, 0x70, 0x5a, 0x02, 0xc9, 0xdd,
4338 0x37, 0x88, 0xca, 0xe0, 0xfc, 0xbe, 0x21, 0xed, 0x35, 0x91, 0x5b, 0x47, 0xae, 0xe8, 0x35, 0x91,
4339 0xcd, 0xbb, 0xa8, 0x99, 0x3d, 0x9d, 0x5a, 0x7e, 0x10, 0xa1, 0xd3, 0xd4, 0x68, 0x0d, 0x09, 0xc3,
4340 0x20, 0x22, 0x5f, 0x43, 0x7a, 0x5d, 0x2c, 0x6f, 0xc9, 0xc5, 0x39, 0xb6, 0x2e, 0xbb, 0x58, 0xa0,
4341 0xab, 0xe3, 0xdc, 0xfd, 0xcf, 0x92, 0x1b, 0xea, 0xca, 0x4d, 0x6f, 0xa8, 0x1f, 0x42, 0x59, 0xc4,
4342 0xa8, 0xda, 0xeb, 0x62, 0x94, 0xc0, 0x65, 0xed, 0xb3, 0x91, 0xb7, 0xcf, 0x5f, 0x16, 0x80, 0x74,
4343 0xa7, 0x53, 0x7f, 0x6c, 0xc7, 0xcc, 0x70, 0xa2, 0x8b, 0x66, 0x7a, 0xed, 0xcf, 0x2e, 0x9f, 0x41,
4344 0x7d, 0xe6, 0x3b, 0x6c, 0x6a, 0x25, 0xdf, 0x94, 0x2e, 0xad, 0x7e, 0x10, 0xc6, 0x5b, 0x52, 0x02,
4345 0x25, 0xbc, 0xc4, 0x51, 0xb0, 0xee, 0xc0, 0x67, 0xde, 0x84, 0xcd, 0xec, 0x97, 0xb2, 0x14, 0xe1,
4346 0x8f, 0xa4, 0x03, 0xd5, 0x90, 0x45, 0x2c, 0x3c, 0x65, 0x57, 0x16, 0x55, 0x09, 0x48, 0x7b, 0x06,
4347 0x1b, 0xb9, 0x1d, 0x49, 0x47, 0xbe, 0x85, 0x5f, 0x2b, 0xc3, 0x58, 0x7e, 0xb4, 0x12, 0x03, 0xfe,
4348 0x3a, 0xe6, 0x25, 0x9f, 0x41, 0xf9, 0x63, 0xea, 0xf0, 0xc5, 0xab, 0xe2, 0xec, 0x1e, 0xa8, 0x59,
4349 0x4d, 0xbb, 0x63, 0x0c, 0x36, 0xf2, 0x54, 0x0a, 0xd7, 0x3b, 0x15, 0xed, 0xef, 0x0a, 0xb0, 0xde,
4350 0x75, 0x1c, 0xf1, 0x77, 0xc3, 0x25, 0xaa, 0x2f, 0x5e, 0x57, 0xf5, 0x0b, 0x81, 0x58, 0x84, 0x89,
4351 0x6b, 0x05, 0xe2, 0x0f, 0xa1, 0x92, 0xd6, 0x5a, 0xc5, 0x05, 0x77, 0x16, 0x72, 0x51, 0x09, 0xd0,
4352 0x6e, 0x01, 0xc9, 0x0a, 0x2b, 0xb4, 0xaa, 0xfd, 0x69, 0x11, 0xee, 0xee, 0xb2, 0x63, 0xd7, 0xcb,
4353 0xbe, 0xe2, 0x57, 0xdf, 0xc9, 0xc5, 0x4f, 0x65, 0x9f, 0xc1, 0xba, 0x28, 0xe4, 0x93, 0x7f, 0x62,
4354 0x59, 0xec, 0x58, 0x7e, 0x9d, 0x94, 0xb1, 0x6a, 0x0d, 0xf9, 0x07, 0x92, 0xad, 0xe3, 0x7f, 0xc5,
4355 0x1c, 0x3b, 0xb6, 0x9f, 0xd9, 0x11, 0xb3, 0x5c, 0x47, 0xfe, 0x59, 0x06, 0x12, 0x92, 0xe1, 0x90,
4356 0x21, 0x94, 0xb8, 0x0d, 0xa2, 0xeb, 0x36, 0xb7, 0xb7, 0x33, 0x62, 0x5d, 0xb2, 0x95, 0xac, 0x02,
4357 0x0f, 0x7c, 0x87, 0xed, 0x54, 0x8f, 0x06, 0x4f, 0x06, 0xc3, 0xef, 0x06, 0x14, 0x17, 0x22, 0x06,
4358 0xdc, 0x0a, 0x42, 0x76, 0xea, 0xfa, 0xf3, 0xc8, 0xca, 0x9e, 0x44, 0xf5, 0xca, 0x94, 0xb8, 0x91,
4359 0xcc, 0xc9, 0x10, 0xb5, 0x9f, 0xc2, 0xda, 0xc2, 0xcb, 0x78, 0x6d, 0x26, 0x5f, 0xa7, 0xbe, 0x41,
4360 0x56, 0xa1, 0x8e, 0x1f, 0xbb, 0x97, 0x7f, 0xfb, 0xd6, 0xfe, 0xb5, 0x80, 0x57, 0x4c, 0x33, 0x37,
4361 0xbe, 0x59, 0x06, 0xfb, 0xcd, 0x7c, 0x06, 0x83, 0xed, 0x77, 0xf3, 0xe6, 0x9b, 0x59, 0xb0, 0xf3,
4362 0xad, 0x00, 0xa6, 0x41, 0xa4, 0x6d, 0x43, 0x55, 0xd2, 0xc8, 0x6f, 0xc1, 0x5a, 0xe8, 0xfb, 0x71,
4363 0xd2, 0x89, 0x8a, 0x0e, 0xe4, 0xf2, 0x3f, 0xdb, 0xac, 0x72, 0xb0, 0x48, 0x06, 0x4f, 0xf2, 0xbd,
4364 0x48, 0x59, 0xfc, 0x0d, 0x44, 0x0e, 0x77, 0x1b, 0xbf, 0x5b, 0x4f, 0xff, 0xb7, 0xfb, 0xbf, 0x01,
4365 0x00, 0x00, 0xff, 0xff, 0x35, 0x9f, 0x30, 0x98, 0xf2, 0x2b, 0x00, 0x00,
4366 }
0 syntax = "proto2";
1 option go_package = "datastore";
2
3 package appengine;
4
5 message Action{}
6
7 message PropertyValue {
8 optional int64 int64Value = 1;
9 optional bool booleanValue = 2;
10 optional string stringValue = 3;
11 optional double doubleValue = 4;
12
13 optional group PointValue = 5 {
14 required double x = 6;
15 required double y = 7;
16 }
17
18 optional group UserValue = 8 {
19 required string email = 9;
20 required string auth_domain = 10;
21 optional string nickname = 11;
22 optional string federated_identity = 21;
23 optional string federated_provider = 22;
24 }
25
26 optional group ReferenceValue = 12 {
27 required string app = 13;
28 optional string name_space = 20;
29 repeated group PathElement = 14 {
30 required string type = 15;
31 optional int64 id = 16;
32 optional string name = 17;
33 }
34 }
35 }
36
37 message Property {
38 enum Meaning {
39 NO_MEANING = 0;
40 BLOB = 14;
41 TEXT = 15;
42 BYTESTRING = 16;
43
44 ATOM_CATEGORY = 1;
45 ATOM_LINK = 2;
46 ATOM_TITLE = 3;
47 ATOM_CONTENT = 4;
48 ATOM_SUMMARY = 5;
49 ATOM_AUTHOR = 6;
50
51 GD_WHEN = 7;
52 GD_EMAIL = 8;
53 GEORSS_POINT = 9;
54 GD_IM = 10;
55
56 GD_PHONENUMBER = 11;
57 GD_POSTALADDRESS = 12;
58
59 GD_RATING = 13;
60
61 BLOBKEY = 17;
62 ENTITY_PROTO = 19;
63
64 INDEX_VALUE = 18;
65 };
66
67 optional Meaning meaning = 1 [default = NO_MEANING];
68 optional string meaning_uri = 2;
69
70 required string name = 3;
71
72 required PropertyValue value = 5;
73
74 required bool multiple = 4;
75
76 optional bool searchable = 6 [default=false];
77
78 enum FtsTokenizationOption {
79 HTML = 1;
80 ATOM = 2;
81 }
82
83 optional FtsTokenizationOption fts_tokenization_option = 8;
84
85 optional string locale = 9 [default = "en"];
86 }
87
88 message Path {
89 repeated group Element = 1 {
90 required string type = 2;
91 optional int64 id = 3;
92 optional string name = 4;
93 }
94 }
95
96 message Reference {
97 required string app = 13;
98 optional string name_space = 20;
99 required Path path = 14;
100 }
101
102 message User {
103 required string email = 1;
104 required string auth_domain = 2;
105 optional string nickname = 3;
106 optional string federated_identity = 6;
107 optional string federated_provider = 7;
108 }
109
110 message EntityProto {
111 required Reference key = 13;
112 required Path entity_group = 16;
113 optional User owner = 17;
114
115 enum Kind {
116 GD_CONTACT = 1;
117 GD_EVENT = 2;
118 GD_MESSAGE = 3;
119 }
120 optional Kind kind = 4;
121 optional string kind_uri = 5;
122
123 repeated Property property = 14;
124 repeated Property raw_property = 15;
125
126 optional int32 rank = 18;
127 }
128
129 message CompositeProperty {
130 required int64 index_id = 1;
131 repeated string value = 2;
132 }
133
134 message Index {
135 required string entity_type = 1;
136 required bool ancestor = 5;
137 repeated group Property = 2 {
138 required string name = 3;
139 enum Direction {
140 ASCENDING = 1;
141 DESCENDING = 2;
142 }
143 optional Direction direction = 4 [default = ASCENDING];
144 }
145 }
146
147 message CompositeIndex {
148 required string app_id = 1;
149 required int64 id = 2;
150 required Index definition = 3;
151
152 enum State {
153 WRITE_ONLY = 1;
154 READ_WRITE = 2;
155 DELETED = 3;
156 ERROR = 4;
157 }
158 required State state = 4;
159
160 optional bool only_use_if_required = 6 [default = false];
161 }
162
163 message IndexPostfix {
164 message IndexValue {
165 required string property_name = 1;
166 required PropertyValue value = 2;
167 }
168
169 repeated IndexValue index_value = 1;
170
171 optional Reference key = 2;
172
173 optional bool before = 3 [default=true];
174 }
175
176 message IndexPosition {
177 optional string key = 1;
178
179 optional bool before = 2 [default=true];
180 }
181
182 message Snapshot {
183 enum Status {
184 INACTIVE = 0;
185 ACTIVE = 1;
186 }
187
188 required int64 ts = 1;
189 }
190
191 message InternalHeader {
192 optional string qos = 1;
193 }
194
195 message Transaction {
196 optional InternalHeader header = 4;
197 required fixed64 handle = 1;
198 required string app = 2;
199 optional bool mark_changes = 3 [default = false];
200 }
201
202 message Query {
203 optional InternalHeader header = 39;
204
205 required string app = 1;
206 optional string name_space = 29;
207
208 optional string kind = 3;
209 optional Reference ancestor = 17;
210
211 repeated group Filter = 4 {
212 enum Operator {
213 LESS_THAN = 1;
214 LESS_THAN_OR_EQUAL = 2;
215 GREATER_THAN = 3;
216 GREATER_THAN_OR_EQUAL = 4;
217 EQUAL = 5;
218 IN = 6;
219 EXISTS = 7;
220 }
221
222 required Operator op = 6;
223 repeated Property property = 14;
224 }
225
226 optional string search_query = 8;
227
228 repeated group Order = 9 {
229 enum Direction {
230 ASCENDING = 1;
231 DESCENDING = 2;
232 }
233
234 required string property = 10;
235 optional Direction direction = 11 [default = ASCENDING];
236 }
237
238 enum Hint {
239 ORDER_FIRST = 1;
240 ANCESTOR_FIRST = 2;
241 FILTER_FIRST = 3;
242 }
243 optional Hint hint = 18;
244
245 optional int32 count = 23;
246
247 optional int32 offset = 12 [default = 0];
248
249 optional int32 limit = 16;
250
251 optional CompiledCursor compiled_cursor = 30;
252 optional CompiledCursor end_compiled_cursor = 31;
253
254 repeated CompositeIndex composite_index = 19;
255
256 optional bool require_perfect_plan = 20 [default = false];
257
258 optional bool keys_only = 21 [default = false];
259
260 optional Transaction transaction = 22;
261
262 optional bool compile = 25 [default = false];
263
264 optional int64 failover_ms = 26;
265
266 optional bool strong = 32;
267
268 repeated string property_name = 33;
269
270 repeated string group_by_property_name = 34;
271
272 optional bool distinct = 24;
273
274 optional int64 min_safe_time_seconds = 35;
275
276 repeated string safe_replica_name = 36;
277
278 optional bool persist_offset = 37 [default=false];
279 }
280
281 message CompiledQuery {
282 required group PrimaryScan = 1 {
283 optional string index_name = 2;
284
285 optional string start_key = 3;
286 optional bool start_inclusive = 4;
287 optional string end_key = 5;
288 optional bool end_inclusive = 6;
289
290 repeated string start_postfix_value = 22;
291 repeated string end_postfix_value = 23;
292
293 optional int64 end_unapplied_log_timestamp_us = 19;
294 }
295
296 repeated group MergeJoinScan = 7 {
297 required string index_name = 8;
298
299 repeated string prefix_value = 9;
300
301 optional bool value_prefix = 20 [default=false];
302 }
303
304 optional Index index_def = 21;
305
306 optional int32 offset = 10 [default = 0];
307
308 optional int32 limit = 11;
309
310 required bool keys_only = 12;
311
312 repeated string property_name = 24;
313
314 optional int32 distinct_infix_size = 25;
315
316 optional group EntityFilter = 13 {
317 optional bool distinct = 14 [default=false];
318
319 optional string kind = 17;
320 optional Reference ancestor = 18;
321 }
322 }
323
324 message CompiledCursor {
325 optional group Position = 2 {
326 optional string start_key = 27;
327
328 repeated group IndexValue = 29 {
329 optional string property = 30;
330 required PropertyValue value = 31;
331 }
332
333 optional Reference key = 32;
334
335 optional bool start_inclusive = 28 [default=true];
336 }
337 }
338
339 message Cursor {
340 required fixed64 cursor = 1;
341
342 optional string app = 2;
343 }
344
345 message Error {
346 enum ErrorCode {
347 BAD_REQUEST = 1;
348 CONCURRENT_TRANSACTION = 2;
349 INTERNAL_ERROR = 3;
350 NEED_INDEX = 4;
351 TIMEOUT = 5;
352 PERMISSION_DENIED = 6;
353 BIGTABLE_ERROR = 7;
354 COMMITTED_BUT_STILL_APPLYING = 8;
355 CAPABILITY_DISABLED = 9;
356 TRY_ALTERNATE_BACKEND = 10;
357 SAFE_TIME_TOO_OLD = 11;
358 }
359 }
360
361 message Cost {
362 optional int32 index_writes = 1;
363 optional int32 index_write_bytes = 2;
364 optional int32 entity_writes = 3;
365 optional int32 entity_write_bytes = 4;
366 optional group CommitCost = 5 {
367 optional int32 requested_entity_puts = 6;
368 optional int32 requested_entity_deletes = 7;
369 };
370 optional int32 approximate_storage_delta = 8;
371 optional int32 id_sequence_updates = 9;
372 }
373
374 message GetRequest {
375 optional InternalHeader header = 6;
376
377 repeated Reference key = 1;
378 optional Transaction transaction = 2;
379
380 optional int64 failover_ms = 3;
381
382 optional bool strong = 4;
383
384 optional bool allow_deferred = 5 [default=false];
385 }
386
387 message GetResponse {
388 repeated group Entity = 1 {
389 optional EntityProto entity = 2;
390 optional Reference key = 4;
391
392 optional int64 version = 3;
393 }
394
395 repeated Reference deferred = 5;
396
397 optional bool in_order = 6 [default=true];
398 }
399
400 message PutRequest {
401 optional InternalHeader header = 11;
402
403 repeated EntityProto entity = 1;
404 optional Transaction transaction = 2;
405 repeated CompositeIndex composite_index = 3;
406
407 optional bool trusted = 4 [default = false];
408
409 optional bool force = 7 [default = false];
410
411 optional bool mark_changes = 8 [default = false];
412 repeated Snapshot snapshot = 9;
413
414 enum AutoIdPolicy {
415 CURRENT = 0;
416 SEQUENTIAL = 1;
417 }
418 optional AutoIdPolicy auto_id_policy = 10 [default = CURRENT];
419 }
420
421 message PutResponse {
422 repeated Reference key = 1;
423 optional Cost cost = 2;
424 repeated int64 version = 3;
425 }
426
427 message TouchRequest {
428 optional InternalHeader header = 10;
429
430 repeated Reference key = 1;
431 repeated CompositeIndex composite_index = 2;
432 optional bool force = 3 [default = false];
433 repeated Snapshot snapshot = 9;
434 }
435
436 message TouchResponse {
437 optional Cost cost = 1;
438 }
439
440 message DeleteRequest {
441 optional InternalHeader header = 10;
442
443 repeated Reference key = 6;
444 optional Transaction transaction = 5;
445
446 optional bool trusted = 4 [default = false];
447
448 optional bool force = 7 [default = false];
449
450 optional bool mark_changes = 8 [default = false];
451 repeated Snapshot snapshot = 9;
452 }
453
454 message DeleteResponse {
455 optional Cost cost = 1;
456 repeated int64 version = 3;
457 }
458
459 message NextRequest {
460 optional InternalHeader header = 5;
461
462 required Cursor cursor = 1;
463 optional int32 count = 2;
464
465 optional int32 offset = 4 [default = 0];
466
467 optional bool compile = 3 [default = false];
468 }
469
470 message QueryResult {
471 optional Cursor cursor = 1;
472
473 repeated EntityProto result = 2;
474
475 optional int32 skipped_results = 7;
476
477 required bool more_results = 3;
478
479 optional bool keys_only = 4;
480
481 optional bool index_only = 9;
482
483 optional bool small_ops = 10;
484
485 optional CompiledQuery compiled_query = 5;
486
487 optional CompiledCursor compiled_cursor = 6;
488
489 repeated CompositeIndex index = 8;
490
491 repeated int64 version = 11;
492 }
493
494 message AllocateIdsRequest {
495 optional InternalHeader header = 4;
496
497 optional Reference model_key = 1;
498
499 optional int64 size = 2;
500
501 optional int64 max = 3;
502
503 repeated Reference reserve = 5;
504 }
505
506 message AllocateIdsResponse {
507 required int64 start = 1;
508 required int64 end = 2;
509 optional Cost cost = 3;
510 }
511
512 message CompositeIndices {
513 repeated CompositeIndex index = 1;
514 }
515
516 message AddActionsRequest {
517 optional InternalHeader header = 3;
518
519 required Transaction transaction = 1;
520 repeated Action action = 2;
521 }
522
523 message AddActionsResponse {
524 }
525
526 message BeginTransactionRequest {
527 optional InternalHeader header = 3;
528
529 required string app = 1;
530 optional bool allow_multiple_eg = 2 [default = false];
531 optional string database_id = 4;
532
533 enum TransactionMode {
534 UNKNOWN = 0;
535 READ_ONLY = 1;
536 READ_WRITE = 2;
537 }
538 optional TransactionMode mode = 5 [default = UNKNOWN];
539
540 optional Transaction previous_transaction = 7;
541 }
542
543 message CommitResponse {
544 optional Cost cost = 1;
545
546 repeated group Version = 3 {
547 required Reference root_entity_key = 4;
548 required int64 version = 5;
549 }
550 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 netcontext "context"
8 "log"
9 "net/http"
10 "os"
11 "strings"
12 )
13
14 // These functions are implementations of the wrapper functions
15 // in ../appengine/identity.go. See that file for commentary.
16
17 const (
18 hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname"
19 hRequestLogId = "X-AppEngine-Request-Log-Id"
20 hDatacenter = "X-AppEngine-Datacenter"
21 )
22
23 var (
24 // This is set to true in identity_flex.go, which is behind the appenginevm build tag.
25 appengineFlex bool
26 )
27
28 // AppID is the implementation of the wrapper function of the same name in
29 // ../identity.go. See that file for commentary.
30 func AppID(c netcontext.Context) string {
31 return appID(FullyQualifiedAppID(c))
32 }
33
34 // IsStandard is the implementation of the wrapper function of the same name in
35 // ../appengine.go. See that file for commentary.
36 func IsStandard() bool {
37 return IsSecondGen()
38 }
39
40 // IsStandard is the implementation of the wrapper function of the same name in
41 // ../appengine.go. See that file for commentary.
42 func IsSecondGen() bool {
43 // Second-gen runtimes set $GAE_ENV so we use that to check if we're on a second-gen runtime.
44 return os.Getenv("GAE_ENV") == "standard"
45 }
46
47 // IsFlex is the implementation of the wrapper function of the same name in
48 // ../appengine.go. See that file for commentary.
49 func IsFlex() bool {
50 return appengineFlex
51 }
52
53 // IsAppEngine is the implementation of the wrapper function of the same name in
54 // ../appengine.go. See that file for commentary.
55 func IsAppEngine() bool {
56 return IsStandard() || IsFlex()
57 }
58
59 func ctxHeaders(ctx netcontext.Context) http.Header {
60 c := fromContext(ctx)
61 if c == nil {
62 return nil
63 }
64 return c.Request().Header
65 }
66
67 func DefaultVersionHostname(ctx netcontext.Context) string {
68 return ctxHeaders(ctx).Get(hDefaultVersionHostname)
69 }
70
71 func RequestID(ctx netcontext.Context) string {
72 return ctxHeaders(ctx).Get(hRequestLogId)
73 }
74
75 func Datacenter(ctx netcontext.Context) string {
76 if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" {
77 return dc
78 }
79 // If the header isn't set, read zone from the metadata service.
80 // It has the format projects/[NUMERIC_PROJECT_ID]/zones/[ZONE]
81 zone, err := getMetadata("instance/zone")
82 if err != nil {
83 log.Printf("Datacenter: %v", err)
84 return ""
85 }
86 parts := strings.Split(string(zone), "/")
87 if len(parts) == 0 {
88 return ""
89 }
90 return parts[len(parts)-1]
91 }
92
93 func ServerSoftware() string {
94 // TODO(dsymonds): Remove fallback when we've verified this.
95 if s := os.Getenv("SERVER_SOFTWARE"); s != "" {
96 return s
97 }
98 if s := os.Getenv("GAE_ENV"); s != "" {
99 return s
100 }
101 return "Google App Engine/1.x.x"
102 }
103
104 // TODO(dsymonds): Remove the metadata fetches.
105
106 func ModuleName(_ netcontext.Context) string {
107 if s := os.Getenv("GAE_MODULE_NAME"); s != "" {
108 return s
109 }
110 if s := os.Getenv("GAE_SERVICE"); s != "" {
111 return s
112 }
113 return string(mustGetMetadata("instance/attributes/gae_backend_name"))
114 }
115
116 func VersionID(_ netcontext.Context) string {
117 if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" {
118 return s1 + "." + s2
119 }
120 if s1, s2 := os.Getenv("GAE_VERSION"), os.Getenv("GAE_DEPLOYMENT_ID"); s1 != "" && s2 != "" {
121 return s1 + "." + s2
122 }
123 return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version"))
124 }
125
126 func InstanceID() string {
127 if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" {
128 return s
129 }
130 if s := os.Getenv("GAE_INSTANCE"); s != "" {
131 return s
132 }
133 return string(mustGetMetadata("instance/attributes/gae_backend_instance"))
134 }
135
136 func partitionlessAppID() string {
137 // gae_project has everything except the partition prefix.
138 if appID := os.Getenv("GAE_LONG_APP_ID"); appID != "" {
139 return appID
140 }
141 return projectID()
142 }
143
144 func projectID() string {
145 if project := os.Getenv("GOOGLE_CLOUD_PROJECT"); project != "" {
146 return project
147 }
148 return string(mustGetMetadata("instance/attributes/gae_project"))
149 }
150
151 func fullyQualifiedAppID(_ netcontext.Context) string {
152 if s := os.Getenv("GAE_APPLICATION"); s != "" {
153 return s
154 }
155 appID := partitionlessAppID()
156
157 part := os.Getenv("GAE_PARTITION")
158 if part == "" {
159 part = string(mustGetMetadata("instance/attributes/gae_partition"))
160 }
161
162 if part != "" {
163 appID = part + "~" + appID
164 }
165 return appID
166 }
167
168 func IsDevAppServer() bool {
169 return os.Getenv("RUN_WITH_DEVAPPSERVER") != "" || os.Getenv("GAE_ENV") == "localdev"
170 }
0 // Copyright 2018 Google LLC. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 //go:build appenginevm
5 // +build appenginevm
6
7 package internal
8
9 func init() {
10 appengineFlex = true
11 }
0 package internal
1
2 import (
3 "os"
4 "testing"
5 )
6
7 func TestIsDevAppServer(t *testing.T) {
8 tests := []struct {
9 desc string // See http://go/gotip/episodes/25 for naming guidance.
10 env map[string]string
11 want bool
12 }{
13 {desc: "empty", env: map[string]string{}, want: false},
14 {desc: "legacy", env: map[string]string{"RUN_WITH_DEVAPPSERVER": "1"}, want: true},
15 {desc: "new", env: map[string]string{"GAE_ENV": "localdev"}, want: true},
16 }
17 for _, test := range tests {
18 t.Run(test.desc, func(t *testing.T) {
19 for key, value := range test.env {
20 defer setenv(t, key, value)()
21 }
22 if got := IsDevAppServer(); got != test.want {
23 t.Errorf("env=%v IsDevAppServer() got %v, want %v", test.env, got, test.want)
24 }
25 })
26 }
27 }
28
29 // setenv is a backport of https://pkg.go.dev/testing#T.Setenv
30 func setenv(t *testing.T, key, value string) func() {
31 t.Helper()
32 prevValue, ok := os.LookupEnv(key)
33
34 if err := os.Setenv(key, value); err != nil {
35 t.Fatalf("cannot set environment variable: %v", err)
36 }
37
38 if ok {
39 return func() {
40 os.Setenv(key, prevValue)
41 }
42 }
43 return func() {
44 os.Unsetenv(key)
45 }
46 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/image/images_service.proto
2
3 package image
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type ImagesServiceError_ErrorCode int32
21
22 const (
23 ImagesServiceError_UNSPECIFIED_ERROR ImagesServiceError_ErrorCode = 1
24 ImagesServiceError_BAD_TRANSFORM_DATA ImagesServiceError_ErrorCode = 2
25 ImagesServiceError_NOT_IMAGE ImagesServiceError_ErrorCode = 3
26 ImagesServiceError_BAD_IMAGE_DATA ImagesServiceError_ErrorCode = 4
27 ImagesServiceError_IMAGE_TOO_LARGE ImagesServiceError_ErrorCode = 5
28 ImagesServiceError_INVALID_BLOB_KEY ImagesServiceError_ErrorCode = 6
29 ImagesServiceError_ACCESS_DENIED ImagesServiceError_ErrorCode = 7
30 ImagesServiceError_OBJECT_NOT_FOUND ImagesServiceError_ErrorCode = 8
31 )
32
33 var ImagesServiceError_ErrorCode_name = map[int32]string{
34 1: "UNSPECIFIED_ERROR",
35 2: "BAD_TRANSFORM_DATA",
36 3: "NOT_IMAGE",
37 4: "BAD_IMAGE_DATA",
38 5: "IMAGE_TOO_LARGE",
39 6: "INVALID_BLOB_KEY",
40 7: "ACCESS_DENIED",
41 8: "OBJECT_NOT_FOUND",
42 }
43 var ImagesServiceError_ErrorCode_value = map[string]int32{
44 "UNSPECIFIED_ERROR": 1,
45 "BAD_TRANSFORM_DATA": 2,
46 "NOT_IMAGE": 3,
47 "BAD_IMAGE_DATA": 4,
48 "IMAGE_TOO_LARGE": 5,
49 "INVALID_BLOB_KEY": 6,
50 "ACCESS_DENIED": 7,
51 "OBJECT_NOT_FOUND": 8,
52 }
53
54 func (x ImagesServiceError_ErrorCode) Enum() *ImagesServiceError_ErrorCode {
55 p := new(ImagesServiceError_ErrorCode)
56 *p = x
57 return p
58 }
59 func (x ImagesServiceError_ErrorCode) String() string {
60 return proto.EnumName(ImagesServiceError_ErrorCode_name, int32(x))
61 }
62 func (x *ImagesServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
63 value, err := proto.UnmarshalJSONEnum(ImagesServiceError_ErrorCode_value, data, "ImagesServiceError_ErrorCode")
64 if err != nil {
65 return err
66 }
67 *x = ImagesServiceError_ErrorCode(value)
68 return nil
69 }
70 func (ImagesServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
71 return fileDescriptor_images_service_42a9d451721edce4, []int{0, 0}
72 }
73
74 type ImagesServiceTransform_Type int32
75
76 const (
77 ImagesServiceTransform_RESIZE ImagesServiceTransform_Type = 1
78 ImagesServiceTransform_ROTATE ImagesServiceTransform_Type = 2
79 ImagesServiceTransform_HORIZONTAL_FLIP ImagesServiceTransform_Type = 3
80 ImagesServiceTransform_VERTICAL_FLIP ImagesServiceTransform_Type = 4
81 ImagesServiceTransform_CROP ImagesServiceTransform_Type = 5
82 ImagesServiceTransform_IM_FEELING_LUCKY ImagesServiceTransform_Type = 6
83 )
84
85 var ImagesServiceTransform_Type_name = map[int32]string{
86 1: "RESIZE",
87 2: "ROTATE",
88 3: "HORIZONTAL_FLIP",
89 4: "VERTICAL_FLIP",
90 5: "CROP",
91 6: "IM_FEELING_LUCKY",
92 }
93 var ImagesServiceTransform_Type_value = map[string]int32{
94 "RESIZE": 1,
95 "ROTATE": 2,
96 "HORIZONTAL_FLIP": 3,
97 "VERTICAL_FLIP": 4,
98 "CROP": 5,
99 "IM_FEELING_LUCKY": 6,
100 }
101
102 func (x ImagesServiceTransform_Type) Enum() *ImagesServiceTransform_Type {
103 p := new(ImagesServiceTransform_Type)
104 *p = x
105 return p
106 }
107 func (x ImagesServiceTransform_Type) String() string {
108 return proto.EnumName(ImagesServiceTransform_Type_name, int32(x))
109 }
110 func (x *ImagesServiceTransform_Type) UnmarshalJSON(data []byte) error {
111 value, err := proto.UnmarshalJSONEnum(ImagesServiceTransform_Type_value, data, "ImagesServiceTransform_Type")
112 if err != nil {
113 return err
114 }
115 *x = ImagesServiceTransform_Type(value)
116 return nil
117 }
118 func (ImagesServiceTransform_Type) EnumDescriptor() ([]byte, []int) {
119 return fileDescriptor_images_service_42a9d451721edce4, []int{1, 0}
120 }
121
122 type InputSettings_ORIENTATION_CORRECTION_TYPE int32
123
124 const (
125 InputSettings_UNCHANGED_ORIENTATION InputSettings_ORIENTATION_CORRECTION_TYPE = 0
126 InputSettings_CORRECT_ORIENTATION InputSettings_ORIENTATION_CORRECTION_TYPE = 1
127 )
128
129 var InputSettings_ORIENTATION_CORRECTION_TYPE_name = map[int32]string{
130 0: "UNCHANGED_ORIENTATION",
131 1: "CORRECT_ORIENTATION",
132 }
133 var InputSettings_ORIENTATION_CORRECTION_TYPE_value = map[string]int32{
134 "UNCHANGED_ORIENTATION": 0,
135 "CORRECT_ORIENTATION": 1,
136 }
137
138 func (x InputSettings_ORIENTATION_CORRECTION_TYPE) Enum() *InputSettings_ORIENTATION_CORRECTION_TYPE {
139 p := new(InputSettings_ORIENTATION_CORRECTION_TYPE)
140 *p = x
141 return p
142 }
143 func (x InputSettings_ORIENTATION_CORRECTION_TYPE) String() string {
144 return proto.EnumName(InputSettings_ORIENTATION_CORRECTION_TYPE_name, int32(x))
145 }
146 func (x *InputSettings_ORIENTATION_CORRECTION_TYPE) UnmarshalJSON(data []byte) error {
147 value, err := proto.UnmarshalJSONEnum(InputSettings_ORIENTATION_CORRECTION_TYPE_value, data, "InputSettings_ORIENTATION_CORRECTION_TYPE")
148 if err != nil {
149 return err
150 }
151 *x = InputSettings_ORIENTATION_CORRECTION_TYPE(value)
152 return nil
153 }
154 func (InputSettings_ORIENTATION_CORRECTION_TYPE) EnumDescriptor() ([]byte, []int) {
155 return fileDescriptor_images_service_42a9d451721edce4, []int{4, 0}
156 }
157
158 type OutputSettings_MIME_TYPE int32
159
160 const (
161 OutputSettings_PNG OutputSettings_MIME_TYPE = 0
162 OutputSettings_JPEG OutputSettings_MIME_TYPE = 1
163 OutputSettings_WEBP OutputSettings_MIME_TYPE = 2
164 )
165
166 var OutputSettings_MIME_TYPE_name = map[int32]string{
167 0: "PNG",
168 1: "JPEG",
169 2: "WEBP",
170 }
171 var OutputSettings_MIME_TYPE_value = map[string]int32{
172 "PNG": 0,
173 "JPEG": 1,
174 "WEBP": 2,
175 }
176
177 func (x OutputSettings_MIME_TYPE) Enum() *OutputSettings_MIME_TYPE {
178 p := new(OutputSettings_MIME_TYPE)
179 *p = x
180 return p
181 }
182 func (x OutputSettings_MIME_TYPE) String() string {
183 return proto.EnumName(OutputSettings_MIME_TYPE_name, int32(x))
184 }
185 func (x *OutputSettings_MIME_TYPE) UnmarshalJSON(data []byte) error {
186 value, err := proto.UnmarshalJSONEnum(OutputSettings_MIME_TYPE_value, data, "OutputSettings_MIME_TYPE")
187 if err != nil {
188 return err
189 }
190 *x = OutputSettings_MIME_TYPE(value)
191 return nil
192 }
193 func (OutputSettings_MIME_TYPE) EnumDescriptor() ([]byte, []int) {
194 return fileDescriptor_images_service_42a9d451721edce4, []int{5, 0}
195 }
196
197 type CompositeImageOptions_ANCHOR int32
198
199 const (
200 CompositeImageOptions_TOP_LEFT CompositeImageOptions_ANCHOR = 0
201 CompositeImageOptions_TOP CompositeImageOptions_ANCHOR = 1
202 CompositeImageOptions_TOP_RIGHT CompositeImageOptions_ANCHOR = 2
203 CompositeImageOptions_LEFT CompositeImageOptions_ANCHOR = 3
204 CompositeImageOptions_CENTER CompositeImageOptions_ANCHOR = 4
205 CompositeImageOptions_RIGHT CompositeImageOptions_ANCHOR = 5
206 CompositeImageOptions_BOTTOM_LEFT CompositeImageOptions_ANCHOR = 6
207 CompositeImageOptions_BOTTOM CompositeImageOptions_ANCHOR = 7
208 CompositeImageOptions_BOTTOM_RIGHT CompositeImageOptions_ANCHOR = 8
209 )
210
211 var CompositeImageOptions_ANCHOR_name = map[int32]string{
212 0: "TOP_LEFT",
213 1: "TOP",
214 2: "TOP_RIGHT",
215 3: "LEFT",
216 4: "CENTER",
217 5: "RIGHT",
218 6: "BOTTOM_LEFT",
219 7: "BOTTOM",
220 8: "BOTTOM_RIGHT",
221 }
222 var CompositeImageOptions_ANCHOR_value = map[string]int32{
223 "TOP_LEFT": 0,
224 "TOP": 1,
225 "TOP_RIGHT": 2,
226 "LEFT": 3,
227 "CENTER": 4,
228 "RIGHT": 5,
229 "BOTTOM_LEFT": 6,
230 "BOTTOM": 7,
231 "BOTTOM_RIGHT": 8,
232 }
233
234 func (x CompositeImageOptions_ANCHOR) Enum() *CompositeImageOptions_ANCHOR {
235 p := new(CompositeImageOptions_ANCHOR)
236 *p = x
237 return p
238 }
239 func (x CompositeImageOptions_ANCHOR) String() string {
240 return proto.EnumName(CompositeImageOptions_ANCHOR_name, int32(x))
241 }
242 func (x *CompositeImageOptions_ANCHOR) UnmarshalJSON(data []byte) error {
243 value, err := proto.UnmarshalJSONEnum(CompositeImageOptions_ANCHOR_value, data, "CompositeImageOptions_ANCHOR")
244 if err != nil {
245 return err
246 }
247 *x = CompositeImageOptions_ANCHOR(value)
248 return nil
249 }
250 func (CompositeImageOptions_ANCHOR) EnumDescriptor() ([]byte, []int) {
251 return fileDescriptor_images_service_42a9d451721edce4, []int{8, 0}
252 }
253
254 type ImagesServiceError struct {
255 XXX_NoUnkeyedLiteral struct{} `json:"-"`
256 XXX_unrecognized []byte `json:"-"`
257 XXX_sizecache int32 `json:"-"`
258 }
259
260 func (m *ImagesServiceError) Reset() { *m = ImagesServiceError{} }
261 func (m *ImagesServiceError) String() string { return proto.CompactTextString(m) }
262 func (*ImagesServiceError) ProtoMessage() {}
263 func (*ImagesServiceError) Descriptor() ([]byte, []int) {
264 return fileDescriptor_images_service_42a9d451721edce4, []int{0}
265 }
266 func (m *ImagesServiceError) XXX_Unmarshal(b []byte) error {
267 return xxx_messageInfo_ImagesServiceError.Unmarshal(m, b)
268 }
269 func (m *ImagesServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
270 return xxx_messageInfo_ImagesServiceError.Marshal(b, m, deterministic)
271 }
272 func (dst *ImagesServiceError) XXX_Merge(src proto.Message) {
273 xxx_messageInfo_ImagesServiceError.Merge(dst, src)
274 }
275 func (m *ImagesServiceError) XXX_Size() int {
276 return xxx_messageInfo_ImagesServiceError.Size(m)
277 }
278 func (m *ImagesServiceError) XXX_DiscardUnknown() {
279 xxx_messageInfo_ImagesServiceError.DiscardUnknown(m)
280 }
281
282 var xxx_messageInfo_ImagesServiceError proto.InternalMessageInfo
283
284 type ImagesServiceTransform struct {
285 XXX_NoUnkeyedLiteral struct{} `json:"-"`
286 XXX_unrecognized []byte `json:"-"`
287 XXX_sizecache int32 `json:"-"`
288 }
289
290 func (m *ImagesServiceTransform) Reset() { *m = ImagesServiceTransform{} }
291 func (m *ImagesServiceTransform) String() string { return proto.CompactTextString(m) }
292 func (*ImagesServiceTransform) ProtoMessage() {}
293 func (*ImagesServiceTransform) Descriptor() ([]byte, []int) {
294 return fileDescriptor_images_service_42a9d451721edce4, []int{1}
295 }
296 func (m *ImagesServiceTransform) XXX_Unmarshal(b []byte) error {
297 return xxx_messageInfo_ImagesServiceTransform.Unmarshal(m, b)
298 }
299 func (m *ImagesServiceTransform) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
300 return xxx_messageInfo_ImagesServiceTransform.Marshal(b, m, deterministic)
301 }
302 func (dst *ImagesServiceTransform) XXX_Merge(src proto.Message) {
303 xxx_messageInfo_ImagesServiceTransform.Merge(dst, src)
304 }
305 func (m *ImagesServiceTransform) XXX_Size() int {
306 return xxx_messageInfo_ImagesServiceTransform.Size(m)
307 }
308 func (m *ImagesServiceTransform) XXX_DiscardUnknown() {
309 xxx_messageInfo_ImagesServiceTransform.DiscardUnknown(m)
310 }
311
312 var xxx_messageInfo_ImagesServiceTransform proto.InternalMessageInfo
313
314 type Transform struct {
315 Width *int32 `protobuf:"varint,1,opt,name=width" json:"width,omitempty"`
316 Height *int32 `protobuf:"varint,2,opt,name=height" json:"height,omitempty"`
317 CropToFit *bool `protobuf:"varint,11,opt,name=crop_to_fit,json=cropToFit,def=0" json:"crop_to_fit,omitempty"`
318 CropOffsetX *float32 `protobuf:"fixed32,12,opt,name=crop_offset_x,json=cropOffsetX,def=0.5" json:"crop_offset_x,omitempty"`
319 CropOffsetY *float32 `protobuf:"fixed32,13,opt,name=crop_offset_y,json=cropOffsetY,def=0.5" json:"crop_offset_y,omitempty"`
320 Rotate *int32 `protobuf:"varint,3,opt,name=rotate,def=0" json:"rotate,omitempty"`
321 HorizontalFlip *bool `protobuf:"varint,4,opt,name=horizontal_flip,json=horizontalFlip,def=0" json:"horizontal_flip,omitempty"`
322 VerticalFlip *bool `protobuf:"varint,5,opt,name=vertical_flip,json=verticalFlip,def=0" json:"vertical_flip,omitempty"`
323 CropLeftX *float32 `protobuf:"fixed32,6,opt,name=crop_left_x,json=cropLeftX,def=0" json:"crop_left_x,omitempty"`
324 CropTopY *float32 `protobuf:"fixed32,7,opt,name=crop_top_y,json=cropTopY,def=0" json:"crop_top_y,omitempty"`
325 CropRightX *float32 `protobuf:"fixed32,8,opt,name=crop_right_x,json=cropRightX,def=1" json:"crop_right_x,omitempty"`
326 CropBottomY *float32 `protobuf:"fixed32,9,opt,name=crop_bottom_y,json=cropBottomY,def=1" json:"crop_bottom_y,omitempty"`
327 Autolevels *bool `protobuf:"varint,10,opt,name=autolevels,def=0" json:"autolevels,omitempty"`
328 AllowStretch *bool `protobuf:"varint,14,opt,name=allow_stretch,json=allowStretch,def=0" json:"allow_stretch,omitempty"`
329 XXX_NoUnkeyedLiteral struct{} `json:"-"`
330 XXX_unrecognized []byte `json:"-"`
331 XXX_sizecache int32 `json:"-"`
332 }
333
334 func (m *Transform) Reset() { *m = Transform{} }
335 func (m *Transform) String() string { return proto.CompactTextString(m) }
336 func (*Transform) ProtoMessage() {}
337 func (*Transform) Descriptor() ([]byte, []int) {
338 return fileDescriptor_images_service_42a9d451721edce4, []int{2}
339 }
340 func (m *Transform) XXX_Unmarshal(b []byte) error {
341 return xxx_messageInfo_Transform.Unmarshal(m, b)
342 }
343 func (m *Transform) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
344 return xxx_messageInfo_Transform.Marshal(b, m, deterministic)
345 }
346 func (dst *Transform) XXX_Merge(src proto.Message) {
347 xxx_messageInfo_Transform.Merge(dst, src)
348 }
349 func (m *Transform) XXX_Size() int {
350 return xxx_messageInfo_Transform.Size(m)
351 }
352 func (m *Transform) XXX_DiscardUnknown() {
353 xxx_messageInfo_Transform.DiscardUnknown(m)
354 }
355
356 var xxx_messageInfo_Transform proto.InternalMessageInfo
357
358 const Default_Transform_CropToFit bool = false
359 const Default_Transform_CropOffsetX float32 = 0.5
360 const Default_Transform_CropOffsetY float32 = 0.5
361 const Default_Transform_Rotate int32 = 0
362 const Default_Transform_HorizontalFlip bool = false
363 const Default_Transform_VerticalFlip bool = false
364 const Default_Transform_CropLeftX float32 = 0
365 const Default_Transform_CropTopY float32 = 0
366 const Default_Transform_CropRightX float32 = 1
367 const Default_Transform_CropBottomY float32 = 1
368 const Default_Transform_Autolevels bool = false
369 const Default_Transform_AllowStretch bool = false
370
371 func (m *Transform) GetWidth() int32 {
372 if m != nil && m.Width != nil {
373 return *m.Width
374 }
375 return 0
376 }
377
378 func (m *Transform) GetHeight() int32 {
379 if m != nil && m.Height != nil {
380 return *m.Height
381 }
382 return 0
383 }
384
385 func (m *Transform) GetCropToFit() bool {
386 if m != nil && m.CropToFit != nil {
387 return *m.CropToFit
388 }
389 return Default_Transform_CropToFit
390 }
391
392 func (m *Transform) GetCropOffsetX() float32 {
393 if m != nil && m.CropOffsetX != nil {
394 return *m.CropOffsetX
395 }
396 return Default_Transform_CropOffsetX
397 }
398
399 func (m *Transform) GetCropOffsetY() float32 {
400 if m != nil && m.CropOffsetY != nil {
401 return *m.CropOffsetY
402 }
403 return Default_Transform_CropOffsetY
404 }
405
406 func (m *Transform) GetRotate() int32 {
407 if m != nil && m.Rotate != nil {
408 return *m.Rotate
409 }
410 return Default_Transform_Rotate
411 }
412
413 func (m *Transform) GetHorizontalFlip() bool {
414 if m != nil && m.HorizontalFlip != nil {
415 return *m.HorizontalFlip
416 }
417 return Default_Transform_HorizontalFlip
418 }
419
420 func (m *Transform) GetVerticalFlip() bool {
421 if m != nil && m.VerticalFlip != nil {
422 return *m.VerticalFlip
423 }
424 return Default_Transform_VerticalFlip
425 }
426
427 func (m *Transform) GetCropLeftX() float32 {
428 if m != nil && m.CropLeftX != nil {
429 return *m.CropLeftX
430 }
431 return Default_Transform_CropLeftX
432 }
433
434 func (m *Transform) GetCropTopY() float32 {
435 if m != nil && m.CropTopY != nil {
436 return *m.CropTopY
437 }
438 return Default_Transform_CropTopY
439 }
440
441 func (m *Transform) GetCropRightX() float32 {
442 if m != nil && m.CropRightX != nil {
443 return *m.CropRightX
444 }
445 return Default_Transform_CropRightX
446 }
447
448 func (m *Transform) GetCropBottomY() float32 {
449 if m != nil && m.CropBottomY != nil {
450 return *m.CropBottomY
451 }
452 return Default_Transform_CropBottomY
453 }
454
455 func (m *Transform) GetAutolevels() bool {
456 if m != nil && m.Autolevels != nil {
457 return *m.Autolevels
458 }
459 return Default_Transform_Autolevels
460 }
461
462 func (m *Transform) GetAllowStretch() bool {
463 if m != nil && m.AllowStretch != nil {
464 return *m.AllowStretch
465 }
466 return Default_Transform_AllowStretch
467 }
468
469 type ImageData struct {
470 Content []byte `protobuf:"bytes,1,req,name=content" json:"content,omitempty"`
471 BlobKey *string `protobuf:"bytes,2,opt,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
472 Width *int32 `protobuf:"varint,3,opt,name=width" json:"width,omitempty"`
473 Height *int32 `protobuf:"varint,4,opt,name=height" json:"height,omitempty"`
474 XXX_NoUnkeyedLiteral struct{} `json:"-"`
475 XXX_unrecognized []byte `json:"-"`
476 XXX_sizecache int32 `json:"-"`
477 }
478
479 func (m *ImageData) Reset() { *m = ImageData{} }
480 func (m *ImageData) String() string { return proto.CompactTextString(m) }
481 func (*ImageData) ProtoMessage() {}
482 func (*ImageData) Descriptor() ([]byte, []int) {
483 return fileDescriptor_images_service_42a9d451721edce4, []int{3}
484 }
485 func (m *ImageData) XXX_Unmarshal(b []byte) error {
486 return xxx_messageInfo_ImageData.Unmarshal(m, b)
487 }
488 func (m *ImageData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
489 return xxx_messageInfo_ImageData.Marshal(b, m, deterministic)
490 }
491 func (dst *ImageData) XXX_Merge(src proto.Message) {
492 xxx_messageInfo_ImageData.Merge(dst, src)
493 }
494 func (m *ImageData) XXX_Size() int {
495 return xxx_messageInfo_ImageData.Size(m)
496 }
497 func (m *ImageData) XXX_DiscardUnknown() {
498 xxx_messageInfo_ImageData.DiscardUnknown(m)
499 }
500
501 var xxx_messageInfo_ImageData proto.InternalMessageInfo
502
503 func (m *ImageData) GetContent() []byte {
504 if m != nil {
505 return m.Content
506 }
507 return nil
508 }
509
510 func (m *ImageData) GetBlobKey() string {
511 if m != nil && m.BlobKey != nil {
512 return *m.BlobKey
513 }
514 return ""
515 }
516
517 func (m *ImageData) GetWidth() int32 {
518 if m != nil && m.Width != nil {
519 return *m.Width
520 }
521 return 0
522 }
523
524 func (m *ImageData) GetHeight() int32 {
525 if m != nil && m.Height != nil {
526 return *m.Height
527 }
528 return 0
529 }
530
531 type InputSettings struct {
532 CorrectExifOrientation *InputSettings_ORIENTATION_CORRECTION_TYPE `protobuf:"varint,1,opt,name=correct_exif_orientation,json=correctExifOrientation,enum=appengine.InputSettings_ORIENTATION_CORRECTION_TYPE,def=0" json:"correct_exif_orientation,omitempty"`
533 ParseMetadata *bool `protobuf:"varint,2,opt,name=parse_metadata,json=parseMetadata,def=0" json:"parse_metadata,omitempty"`
534 TransparentSubstitutionRgb *int32 `protobuf:"varint,3,opt,name=transparent_substitution_rgb,json=transparentSubstitutionRgb" json:"transparent_substitution_rgb,omitempty"`
535 XXX_NoUnkeyedLiteral struct{} `json:"-"`
536 XXX_unrecognized []byte `json:"-"`
537 XXX_sizecache int32 `json:"-"`
538 }
539
540 func (m *InputSettings) Reset() { *m = InputSettings{} }
541 func (m *InputSettings) String() string { return proto.CompactTextString(m) }
542 func (*InputSettings) ProtoMessage() {}
543 func (*InputSettings) Descriptor() ([]byte, []int) {
544 return fileDescriptor_images_service_42a9d451721edce4, []int{4}
545 }
546 func (m *InputSettings) XXX_Unmarshal(b []byte) error {
547 return xxx_messageInfo_InputSettings.Unmarshal(m, b)
548 }
549 func (m *InputSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
550 return xxx_messageInfo_InputSettings.Marshal(b, m, deterministic)
551 }
552 func (dst *InputSettings) XXX_Merge(src proto.Message) {
553 xxx_messageInfo_InputSettings.Merge(dst, src)
554 }
555 func (m *InputSettings) XXX_Size() int {
556 return xxx_messageInfo_InputSettings.Size(m)
557 }
558 func (m *InputSettings) XXX_DiscardUnknown() {
559 xxx_messageInfo_InputSettings.DiscardUnknown(m)
560 }
561
562 var xxx_messageInfo_InputSettings proto.InternalMessageInfo
563
564 const Default_InputSettings_CorrectExifOrientation InputSettings_ORIENTATION_CORRECTION_TYPE = InputSettings_UNCHANGED_ORIENTATION
565 const Default_InputSettings_ParseMetadata bool = false
566
567 func (m *InputSettings) GetCorrectExifOrientation() InputSettings_ORIENTATION_CORRECTION_TYPE {
568 if m != nil && m.CorrectExifOrientation != nil {
569 return *m.CorrectExifOrientation
570 }
571 return Default_InputSettings_CorrectExifOrientation
572 }
573
574 func (m *InputSettings) GetParseMetadata() bool {
575 if m != nil && m.ParseMetadata != nil {
576 return *m.ParseMetadata
577 }
578 return Default_InputSettings_ParseMetadata
579 }
580
581 func (m *InputSettings) GetTransparentSubstitutionRgb() int32 {
582 if m != nil && m.TransparentSubstitutionRgb != nil {
583 return *m.TransparentSubstitutionRgb
584 }
585 return 0
586 }
587
588 type OutputSettings struct {
589 MimeType *OutputSettings_MIME_TYPE `protobuf:"varint,1,opt,name=mime_type,json=mimeType,enum=appengine.OutputSettings_MIME_TYPE,def=0" json:"mime_type,omitempty"`
590 Quality *int32 `protobuf:"varint,2,opt,name=quality" json:"quality,omitempty"`
591 XXX_NoUnkeyedLiteral struct{} `json:"-"`
592 XXX_unrecognized []byte `json:"-"`
593 XXX_sizecache int32 `json:"-"`
594 }
595
596 func (m *OutputSettings) Reset() { *m = OutputSettings{} }
597 func (m *OutputSettings) String() string { return proto.CompactTextString(m) }
598 func (*OutputSettings) ProtoMessage() {}
599 func (*OutputSettings) Descriptor() ([]byte, []int) {
600 return fileDescriptor_images_service_42a9d451721edce4, []int{5}
601 }
602 func (m *OutputSettings) XXX_Unmarshal(b []byte) error {
603 return xxx_messageInfo_OutputSettings.Unmarshal(m, b)
604 }
605 func (m *OutputSettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
606 return xxx_messageInfo_OutputSettings.Marshal(b, m, deterministic)
607 }
608 func (dst *OutputSettings) XXX_Merge(src proto.Message) {
609 xxx_messageInfo_OutputSettings.Merge(dst, src)
610 }
611 func (m *OutputSettings) XXX_Size() int {
612 return xxx_messageInfo_OutputSettings.Size(m)
613 }
614 func (m *OutputSettings) XXX_DiscardUnknown() {
615 xxx_messageInfo_OutputSettings.DiscardUnknown(m)
616 }
617
618 var xxx_messageInfo_OutputSettings proto.InternalMessageInfo
619
620 const Default_OutputSettings_MimeType OutputSettings_MIME_TYPE = OutputSettings_PNG
621
622 func (m *OutputSettings) GetMimeType() OutputSettings_MIME_TYPE {
623 if m != nil && m.MimeType != nil {
624 return *m.MimeType
625 }
626 return Default_OutputSettings_MimeType
627 }
628
629 func (m *OutputSettings) GetQuality() int32 {
630 if m != nil && m.Quality != nil {
631 return *m.Quality
632 }
633 return 0
634 }
635
636 type ImagesTransformRequest struct {
637 Image *ImageData `protobuf:"bytes,1,req,name=image" json:"image,omitempty"`
638 Transform []*Transform `protobuf:"bytes,2,rep,name=transform" json:"transform,omitempty"`
639 Output *OutputSettings `protobuf:"bytes,3,req,name=output" json:"output,omitempty"`
640 Input *InputSettings `protobuf:"bytes,4,opt,name=input" json:"input,omitempty"`
641 XXX_NoUnkeyedLiteral struct{} `json:"-"`
642 XXX_unrecognized []byte `json:"-"`
643 XXX_sizecache int32 `json:"-"`
644 }
645
646 func (m *ImagesTransformRequest) Reset() { *m = ImagesTransformRequest{} }
647 func (m *ImagesTransformRequest) String() string { return proto.CompactTextString(m) }
648 func (*ImagesTransformRequest) ProtoMessage() {}
649 func (*ImagesTransformRequest) Descriptor() ([]byte, []int) {
650 return fileDescriptor_images_service_42a9d451721edce4, []int{6}
651 }
652 func (m *ImagesTransformRequest) XXX_Unmarshal(b []byte) error {
653 return xxx_messageInfo_ImagesTransformRequest.Unmarshal(m, b)
654 }
655 func (m *ImagesTransformRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
656 return xxx_messageInfo_ImagesTransformRequest.Marshal(b, m, deterministic)
657 }
658 func (dst *ImagesTransformRequest) XXX_Merge(src proto.Message) {
659 xxx_messageInfo_ImagesTransformRequest.Merge(dst, src)
660 }
661 func (m *ImagesTransformRequest) XXX_Size() int {
662 return xxx_messageInfo_ImagesTransformRequest.Size(m)
663 }
664 func (m *ImagesTransformRequest) XXX_DiscardUnknown() {
665 xxx_messageInfo_ImagesTransformRequest.DiscardUnknown(m)
666 }
667
668 var xxx_messageInfo_ImagesTransformRequest proto.InternalMessageInfo
669
670 func (m *ImagesTransformRequest) GetImage() *ImageData {
671 if m != nil {
672 return m.Image
673 }
674 return nil
675 }
676
677 func (m *ImagesTransformRequest) GetTransform() []*Transform {
678 if m != nil {
679 return m.Transform
680 }
681 return nil
682 }
683
684 func (m *ImagesTransformRequest) GetOutput() *OutputSettings {
685 if m != nil {
686 return m.Output
687 }
688 return nil
689 }
690
691 func (m *ImagesTransformRequest) GetInput() *InputSettings {
692 if m != nil {
693 return m.Input
694 }
695 return nil
696 }
697
698 type ImagesTransformResponse struct {
699 Image *ImageData `protobuf:"bytes,1,req,name=image" json:"image,omitempty"`
700 SourceMetadata *string `protobuf:"bytes,2,opt,name=source_metadata,json=sourceMetadata" json:"source_metadata,omitempty"`
701 XXX_NoUnkeyedLiteral struct{} `json:"-"`
702 XXX_unrecognized []byte `json:"-"`
703 XXX_sizecache int32 `json:"-"`
704 }
705
706 func (m *ImagesTransformResponse) Reset() { *m = ImagesTransformResponse{} }
707 func (m *ImagesTransformResponse) String() string { return proto.CompactTextString(m) }
708 func (*ImagesTransformResponse) ProtoMessage() {}
709 func (*ImagesTransformResponse) Descriptor() ([]byte, []int) {
710 return fileDescriptor_images_service_42a9d451721edce4, []int{7}
711 }
712 func (m *ImagesTransformResponse) XXX_Unmarshal(b []byte) error {
713 return xxx_messageInfo_ImagesTransformResponse.Unmarshal(m, b)
714 }
715 func (m *ImagesTransformResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
716 return xxx_messageInfo_ImagesTransformResponse.Marshal(b, m, deterministic)
717 }
718 func (dst *ImagesTransformResponse) XXX_Merge(src proto.Message) {
719 xxx_messageInfo_ImagesTransformResponse.Merge(dst, src)
720 }
721 func (m *ImagesTransformResponse) XXX_Size() int {
722 return xxx_messageInfo_ImagesTransformResponse.Size(m)
723 }
724 func (m *ImagesTransformResponse) XXX_DiscardUnknown() {
725 xxx_messageInfo_ImagesTransformResponse.DiscardUnknown(m)
726 }
727
728 var xxx_messageInfo_ImagesTransformResponse proto.InternalMessageInfo
729
730 func (m *ImagesTransformResponse) GetImage() *ImageData {
731 if m != nil {
732 return m.Image
733 }
734 return nil
735 }
736
737 func (m *ImagesTransformResponse) GetSourceMetadata() string {
738 if m != nil && m.SourceMetadata != nil {
739 return *m.SourceMetadata
740 }
741 return ""
742 }
743
744 type CompositeImageOptions struct {
745 SourceIndex *int32 `protobuf:"varint,1,req,name=source_index,json=sourceIndex" json:"source_index,omitempty"`
746 XOffset *int32 `protobuf:"varint,2,req,name=x_offset,json=xOffset" json:"x_offset,omitempty"`
747 YOffset *int32 `protobuf:"varint,3,req,name=y_offset,json=yOffset" json:"y_offset,omitempty"`
748 Opacity *float32 `protobuf:"fixed32,4,req,name=opacity" json:"opacity,omitempty"`
749 Anchor *CompositeImageOptions_ANCHOR `protobuf:"varint,5,req,name=anchor,enum=appengine.CompositeImageOptions_ANCHOR" json:"anchor,omitempty"`
750 XXX_NoUnkeyedLiteral struct{} `json:"-"`
751 XXX_unrecognized []byte `json:"-"`
752 XXX_sizecache int32 `json:"-"`
753 }
754
755 func (m *CompositeImageOptions) Reset() { *m = CompositeImageOptions{} }
756 func (m *CompositeImageOptions) String() string { return proto.CompactTextString(m) }
757 func (*CompositeImageOptions) ProtoMessage() {}
758 func (*CompositeImageOptions) Descriptor() ([]byte, []int) {
759 return fileDescriptor_images_service_42a9d451721edce4, []int{8}
760 }
761 func (m *CompositeImageOptions) XXX_Unmarshal(b []byte) error {
762 return xxx_messageInfo_CompositeImageOptions.Unmarshal(m, b)
763 }
764 func (m *CompositeImageOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
765 return xxx_messageInfo_CompositeImageOptions.Marshal(b, m, deterministic)
766 }
767 func (dst *CompositeImageOptions) XXX_Merge(src proto.Message) {
768 xxx_messageInfo_CompositeImageOptions.Merge(dst, src)
769 }
770 func (m *CompositeImageOptions) XXX_Size() int {
771 return xxx_messageInfo_CompositeImageOptions.Size(m)
772 }
773 func (m *CompositeImageOptions) XXX_DiscardUnknown() {
774 xxx_messageInfo_CompositeImageOptions.DiscardUnknown(m)
775 }
776
777 var xxx_messageInfo_CompositeImageOptions proto.InternalMessageInfo
778
779 func (m *CompositeImageOptions) GetSourceIndex() int32 {
780 if m != nil && m.SourceIndex != nil {
781 return *m.SourceIndex
782 }
783 return 0
784 }
785
786 func (m *CompositeImageOptions) GetXOffset() int32 {
787 if m != nil && m.XOffset != nil {
788 return *m.XOffset
789 }
790 return 0
791 }
792
793 func (m *CompositeImageOptions) GetYOffset() int32 {
794 if m != nil && m.YOffset != nil {
795 return *m.YOffset
796 }
797 return 0
798 }
799
800 func (m *CompositeImageOptions) GetOpacity() float32 {
801 if m != nil && m.Opacity != nil {
802 return *m.Opacity
803 }
804 return 0
805 }
806
807 func (m *CompositeImageOptions) GetAnchor() CompositeImageOptions_ANCHOR {
808 if m != nil && m.Anchor != nil {
809 return *m.Anchor
810 }
811 return CompositeImageOptions_TOP_LEFT
812 }
813
814 type ImagesCanvas struct {
815 Width *int32 `protobuf:"varint,1,req,name=width" json:"width,omitempty"`
816 Height *int32 `protobuf:"varint,2,req,name=height" json:"height,omitempty"`
817 Output *OutputSettings `protobuf:"bytes,3,req,name=output" json:"output,omitempty"`
818 Color *int32 `protobuf:"varint,4,opt,name=color,def=-1" json:"color,omitempty"`
819 XXX_NoUnkeyedLiteral struct{} `json:"-"`
820 XXX_unrecognized []byte `json:"-"`
821 XXX_sizecache int32 `json:"-"`
822 }
823
824 func (m *ImagesCanvas) Reset() { *m = ImagesCanvas{} }
825 func (m *ImagesCanvas) String() string { return proto.CompactTextString(m) }
826 func (*ImagesCanvas) ProtoMessage() {}
827 func (*ImagesCanvas) Descriptor() ([]byte, []int) {
828 return fileDescriptor_images_service_42a9d451721edce4, []int{9}
829 }
830 func (m *ImagesCanvas) XXX_Unmarshal(b []byte) error {
831 return xxx_messageInfo_ImagesCanvas.Unmarshal(m, b)
832 }
833 func (m *ImagesCanvas) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
834 return xxx_messageInfo_ImagesCanvas.Marshal(b, m, deterministic)
835 }
836 func (dst *ImagesCanvas) XXX_Merge(src proto.Message) {
837 xxx_messageInfo_ImagesCanvas.Merge(dst, src)
838 }
839 func (m *ImagesCanvas) XXX_Size() int {
840 return xxx_messageInfo_ImagesCanvas.Size(m)
841 }
842 func (m *ImagesCanvas) XXX_DiscardUnknown() {
843 xxx_messageInfo_ImagesCanvas.DiscardUnknown(m)
844 }
845
846 var xxx_messageInfo_ImagesCanvas proto.InternalMessageInfo
847
848 const Default_ImagesCanvas_Color int32 = -1
849
850 func (m *ImagesCanvas) GetWidth() int32 {
851 if m != nil && m.Width != nil {
852 return *m.Width
853 }
854 return 0
855 }
856
857 func (m *ImagesCanvas) GetHeight() int32 {
858 if m != nil && m.Height != nil {
859 return *m.Height
860 }
861 return 0
862 }
863
864 func (m *ImagesCanvas) GetOutput() *OutputSettings {
865 if m != nil {
866 return m.Output
867 }
868 return nil
869 }
870
871 func (m *ImagesCanvas) GetColor() int32 {
872 if m != nil && m.Color != nil {
873 return *m.Color
874 }
875 return Default_ImagesCanvas_Color
876 }
877
878 type ImagesCompositeRequest struct {
879 Image []*ImageData `protobuf:"bytes,1,rep,name=image" json:"image,omitempty"`
880 Options []*CompositeImageOptions `protobuf:"bytes,2,rep,name=options" json:"options,omitempty"`
881 Canvas *ImagesCanvas `protobuf:"bytes,3,req,name=canvas" json:"canvas,omitempty"`
882 XXX_NoUnkeyedLiteral struct{} `json:"-"`
883 XXX_unrecognized []byte `json:"-"`
884 XXX_sizecache int32 `json:"-"`
885 }
886
887 func (m *ImagesCompositeRequest) Reset() { *m = ImagesCompositeRequest{} }
888 func (m *ImagesCompositeRequest) String() string { return proto.CompactTextString(m) }
889 func (*ImagesCompositeRequest) ProtoMessage() {}
890 func (*ImagesCompositeRequest) Descriptor() ([]byte, []int) {
891 return fileDescriptor_images_service_42a9d451721edce4, []int{10}
892 }
893 func (m *ImagesCompositeRequest) XXX_Unmarshal(b []byte) error {
894 return xxx_messageInfo_ImagesCompositeRequest.Unmarshal(m, b)
895 }
896 func (m *ImagesCompositeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
897 return xxx_messageInfo_ImagesCompositeRequest.Marshal(b, m, deterministic)
898 }
899 func (dst *ImagesCompositeRequest) XXX_Merge(src proto.Message) {
900 xxx_messageInfo_ImagesCompositeRequest.Merge(dst, src)
901 }
902 func (m *ImagesCompositeRequest) XXX_Size() int {
903 return xxx_messageInfo_ImagesCompositeRequest.Size(m)
904 }
905 func (m *ImagesCompositeRequest) XXX_DiscardUnknown() {
906 xxx_messageInfo_ImagesCompositeRequest.DiscardUnknown(m)
907 }
908
909 var xxx_messageInfo_ImagesCompositeRequest proto.InternalMessageInfo
910
911 func (m *ImagesCompositeRequest) GetImage() []*ImageData {
912 if m != nil {
913 return m.Image
914 }
915 return nil
916 }
917
918 func (m *ImagesCompositeRequest) GetOptions() []*CompositeImageOptions {
919 if m != nil {
920 return m.Options
921 }
922 return nil
923 }
924
925 func (m *ImagesCompositeRequest) GetCanvas() *ImagesCanvas {
926 if m != nil {
927 return m.Canvas
928 }
929 return nil
930 }
931
932 type ImagesCompositeResponse struct {
933 Image *ImageData `protobuf:"bytes,1,req,name=image" json:"image,omitempty"`
934 XXX_NoUnkeyedLiteral struct{} `json:"-"`
935 XXX_unrecognized []byte `json:"-"`
936 XXX_sizecache int32 `json:"-"`
937 }
938
939 func (m *ImagesCompositeResponse) Reset() { *m = ImagesCompositeResponse{} }
940 func (m *ImagesCompositeResponse) String() string { return proto.CompactTextString(m) }
941 func (*ImagesCompositeResponse) ProtoMessage() {}
942 func (*ImagesCompositeResponse) Descriptor() ([]byte, []int) {
943 return fileDescriptor_images_service_42a9d451721edce4, []int{11}
944 }
945 func (m *ImagesCompositeResponse) XXX_Unmarshal(b []byte) error {
946 return xxx_messageInfo_ImagesCompositeResponse.Unmarshal(m, b)
947 }
948 func (m *ImagesCompositeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
949 return xxx_messageInfo_ImagesCompositeResponse.Marshal(b, m, deterministic)
950 }
951 func (dst *ImagesCompositeResponse) XXX_Merge(src proto.Message) {
952 xxx_messageInfo_ImagesCompositeResponse.Merge(dst, src)
953 }
954 func (m *ImagesCompositeResponse) XXX_Size() int {
955 return xxx_messageInfo_ImagesCompositeResponse.Size(m)
956 }
957 func (m *ImagesCompositeResponse) XXX_DiscardUnknown() {
958 xxx_messageInfo_ImagesCompositeResponse.DiscardUnknown(m)
959 }
960
961 var xxx_messageInfo_ImagesCompositeResponse proto.InternalMessageInfo
962
963 func (m *ImagesCompositeResponse) GetImage() *ImageData {
964 if m != nil {
965 return m.Image
966 }
967 return nil
968 }
969
970 type ImagesHistogramRequest struct {
971 Image *ImageData `protobuf:"bytes,1,req,name=image" json:"image,omitempty"`
972 XXX_NoUnkeyedLiteral struct{} `json:"-"`
973 XXX_unrecognized []byte `json:"-"`
974 XXX_sizecache int32 `json:"-"`
975 }
976
977 func (m *ImagesHistogramRequest) Reset() { *m = ImagesHistogramRequest{} }
978 func (m *ImagesHistogramRequest) String() string { return proto.CompactTextString(m) }
979 func (*ImagesHistogramRequest) ProtoMessage() {}
980 func (*ImagesHistogramRequest) Descriptor() ([]byte, []int) {
981 return fileDescriptor_images_service_42a9d451721edce4, []int{12}
982 }
983 func (m *ImagesHistogramRequest) XXX_Unmarshal(b []byte) error {
984 return xxx_messageInfo_ImagesHistogramRequest.Unmarshal(m, b)
985 }
986 func (m *ImagesHistogramRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
987 return xxx_messageInfo_ImagesHistogramRequest.Marshal(b, m, deterministic)
988 }
989 func (dst *ImagesHistogramRequest) XXX_Merge(src proto.Message) {
990 xxx_messageInfo_ImagesHistogramRequest.Merge(dst, src)
991 }
992 func (m *ImagesHistogramRequest) XXX_Size() int {
993 return xxx_messageInfo_ImagesHistogramRequest.Size(m)
994 }
995 func (m *ImagesHistogramRequest) XXX_DiscardUnknown() {
996 xxx_messageInfo_ImagesHistogramRequest.DiscardUnknown(m)
997 }
998
999 var xxx_messageInfo_ImagesHistogramRequest proto.InternalMessageInfo
1000
1001 func (m *ImagesHistogramRequest) GetImage() *ImageData {
1002 if m != nil {
1003 return m.Image
1004 }
1005 return nil
1006 }
1007
1008 type ImagesHistogram struct {
1009 Red []int32 `protobuf:"varint,1,rep,name=red" json:"red,omitempty"`
1010 Green []int32 `protobuf:"varint,2,rep,name=green" json:"green,omitempty"`
1011 Blue []int32 `protobuf:"varint,3,rep,name=blue" json:"blue,omitempty"`
1012 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1013 XXX_unrecognized []byte `json:"-"`
1014 XXX_sizecache int32 `json:"-"`
1015 }
1016
1017 func (m *ImagesHistogram) Reset() { *m = ImagesHistogram{} }
1018 func (m *ImagesHistogram) String() string { return proto.CompactTextString(m) }
1019 func (*ImagesHistogram) ProtoMessage() {}
1020 func (*ImagesHistogram) Descriptor() ([]byte, []int) {
1021 return fileDescriptor_images_service_42a9d451721edce4, []int{13}
1022 }
1023 func (m *ImagesHistogram) XXX_Unmarshal(b []byte) error {
1024 return xxx_messageInfo_ImagesHistogram.Unmarshal(m, b)
1025 }
1026 func (m *ImagesHistogram) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1027 return xxx_messageInfo_ImagesHistogram.Marshal(b, m, deterministic)
1028 }
1029 func (dst *ImagesHistogram) XXX_Merge(src proto.Message) {
1030 xxx_messageInfo_ImagesHistogram.Merge(dst, src)
1031 }
1032 func (m *ImagesHistogram) XXX_Size() int {
1033 return xxx_messageInfo_ImagesHistogram.Size(m)
1034 }
1035 func (m *ImagesHistogram) XXX_DiscardUnknown() {
1036 xxx_messageInfo_ImagesHistogram.DiscardUnknown(m)
1037 }
1038
1039 var xxx_messageInfo_ImagesHistogram proto.InternalMessageInfo
1040
1041 func (m *ImagesHistogram) GetRed() []int32 {
1042 if m != nil {
1043 return m.Red
1044 }
1045 return nil
1046 }
1047
1048 func (m *ImagesHistogram) GetGreen() []int32 {
1049 if m != nil {
1050 return m.Green
1051 }
1052 return nil
1053 }
1054
1055 func (m *ImagesHistogram) GetBlue() []int32 {
1056 if m != nil {
1057 return m.Blue
1058 }
1059 return nil
1060 }
1061
1062 type ImagesHistogramResponse struct {
1063 Histogram *ImagesHistogram `protobuf:"bytes,1,req,name=histogram" json:"histogram,omitempty"`
1064 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1065 XXX_unrecognized []byte `json:"-"`
1066 XXX_sizecache int32 `json:"-"`
1067 }
1068
1069 func (m *ImagesHistogramResponse) Reset() { *m = ImagesHistogramResponse{} }
1070 func (m *ImagesHistogramResponse) String() string { return proto.CompactTextString(m) }
1071 func (*ImagesHistogramResponse) ProtoMessage() {}
1072 func (*ImagesHistogramResponse) Descriptor() ([]byte, []int) {
1073 return fileDescriptor_images_service_42a9d451721edce4, []int{14}
1074 }
1075 func (m *ImagesHistogramResponse) XXX_Unmarshal(b []byte) error {
1076 return xxx_messageInfo_ImagesHistogramResponse.Unmarshal(m, b)
1077 }
1078 func (m *ImagesHistogramResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1079 return xxx_messageInfo_ImagesHistogramResponse.Marshal(b, m, deterministic)
1080 }
1081 func (dst *ImagesHistogramResponse) XXX_Merge(src proto.Message) {
1082 xxx_messageInfo_ImagesHistogramResponse.Merge(dst, src)
1083 }
1084 func (m *ImagesHistogramResponse) XXX_Size() int {
1085 return xxx_messageInfo_ImagesHistogramResponse.Size(m)
1086 }
1087 func (m *ImagesHistogramResponse) XXX_DiscardUnknown() {
1088 xxx_messageInfo_ImagesHistogramResponse.DiscardUnknown(m)
1089 }
1090
1091 var xxx_messageInfo_ImagesHistogramResponse proto.InternalMessageInfo
1092
1093 func (m *ImagesHistogramResponse) GetHistogram() *ImagesHistogram {
1094 if m != nil {
1095 return m.Histogram
1096 }
1097 return nil
1098 }
1099
1100 type ImagesGetUrlBaseRequest struct {
1101 BlobKey *string `protobuf:"bytes,1,req,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
1102 CreateSecureUrl *bool `protobuf:"varint,2,opt,name=create_secure_url,json=createSecureUrl,def=0" json:"create_secure_url,omitempty"`
1103 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1104 XXX_unrecognized []byte `json:"-"`
1105 XXX_sizecache int32 `json:"-"`
1106 }
1107
1108 func (m *ImagesGetUrlBaseRequest) Reset() { *m = ImagesGetUrlBaseRequest{} }
1109 func (m *ImagesGetUrlBaseRequest) String() string { return proto.CompactTextString(m) }
1110 func (*ImagesGetUrlBaseRequest) ProtoMessage() {}
1111 func (*ImagesGetUrlBaseRequest) Descriptor() ([]byte, []int) {
1112 return fileDescriptor_images_service_42a9d451721edce4, []int{15}
1113 }
1114 func (m *ImagesGetUrlBaseRequest) XXX_Unmarshal(b []byte) error {
1115 return xxx_messageInfo_ImagesGetUrlBaseRequest.Unmarshal(m, b)
1116 }
1117 func (m *ImagesGetUrlBaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1118 return xxx_messageInfo_ImagesGetUrlBaseRequest.Marshal(b, m, deterministic)
1119 }
1120 func (dst *ImagesGetUrlBaseRequest) XXX_Merge(src proto.Message) {
1121 xxx_messageInfo_ImagesGetUrlBaseRequest.Merge(dst, src)
1122 }
1123 func (m *ImagesGetUrlBaseRequest) XXX_Size() int {
1124 return xxx_messageInfo_ImagesGetUrlBaseRequest.Size(m)
1125 }
1126 func (m *ImagesGetUrlBaseRequest) XXX_DiscardUnknown() {
1127 xxx_messageInfo_ImagesGetUrlBaseRequest.DiscardUnknown(m)
1128 }
1129
1130 var xxx_messageInfo_ImagesGetUrlBaseRequest proto.InternalMessageInfo
1131
1132 const Default_ImagesGetUrlBaseRequest_CreateSecureUrl bool = false
1133
1134 func (m *ImagesGetUrlBaseRequest) GetBlobKey() string {
1135 if m != nil && m.BlobKey != nil {
1136 return *m.BlobKey
1137 }
1138 return ""
1139 }
1140
1141 func (m *ImagesGetUrlBaseRequest) GetCreateSecureUrl() bool {
1142 if m != nil && m.CreateSecureUrl != nil {
1143 return *m.CreateSecureUrl
1144 }
1145 return Default_ImagesGetUrlBaseRequest_CreateSecureUrl
1146 }
1147
1148 type ImagesGetUrlBaseResponse struct {
1149 Url *string `protobuf:"bytes,1,req,name=url" json:"url,omitempty"`
1150 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1151 XXX_unrecognized []byte `json:"-"`
1152 XXX_sizecache int32 `json:"-"`
1153 }
1154
1155 func (m *ImagesGetUrlBaseResponse) Reset() { *m = ImagesGetUrlBaseResponse{} }
1156 func (m *ImagesGetUrlBaseResponse) String() string { return proto.CompactTextString(m) }
1157 func (*ImagesGetUrlBaseResponse) ProtoMessage() {}
1158 func (*ImagesGetUrlBaseResponse) Descriptor() ([]byte, []int) {
1159 return fileDescriptor_images_service_42a9d451721edce4, []int{16}
1160 }
1161 func (m *ImagesGetUrlBaseResponse) XXX_Unmarshal(b []byte) error {
1162 return xxx_messageInfo_ImagesGetUrlBaseResponse.Unmarshal(m, b)
1163 }
1164 func (m *ImagesGetUrlBaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1165 return xxx_messageInfo_ImagesGetUrlBaseResponse.Marshal(b, m, deterministic)
1166 }
1167 func (dst *ImagesGetUrlBaseResponse) XXX_Merge(src proto.Message) {
1168 xxx_messageInfo_ImagesGetUrlBaseResponse.Merge(dst, src)
1169 }
1170 func (m *ImagesGetUrlBaseResponse) XXX_Size() int {
1171 return xxx_messageInfo_ImagesGetUrlBaseResponse.Size(m)
1172 }
1173 func (m *ImagesGetUrlBaseResponse) XXX_DiscardUnknown() {
1174 xxx_messageInfo_ImagesGetUrlBaseResponse.DiscardUnknown(m)
1175 }
1176
1177 var xxx_messageInfo_ImagesGetUrlBaseResponse proto.InternalMessageInfo
1178
1179 func (m *ImagesGetUrlBaseResponse) GetUrl() string {
1180 if m != nil && m.Url != nil {
1181 return *m.Url
1182 }
1183 return ""
1184 }
1185
1186 type ImagesDeleteUrlBaseRequest struct {
1187 BlobKey *string `protobuf:"bytes,1,req,name=blob_key,json=blobKey" json:"blob_key,omitempty"`
1188 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1189 XXX_unrecognized []byte `json:"-"`
1190 XXX_sizecache int32 `json:"-"`
1191 }
1192
1193 func (m *ImagesDeleteUrlBaseRequest) Reset() { *m = ImagesDeleteUrlBaseRequest{} }
1194 func (m *ImagesDeleteUrlBaseRequest) String() string { return proto.CompactTextString(m) }
1195 func (*ImagesDeleteUrlBaseRequest) ProtoMessage() {}
1196 func (*ImagesDeleteUrlBaseRequest) Descriptor() ([]byte, []int) {
1197 return fileDescriptor_images_service_42a9d451721edce4, []int{17}
1198 }
1199 func (m *ImagesDeleteUrlBaseRequest) XXX_Unmarshal(b []byte) error {
1200 return xxx_messageInfo_ImagesDeleteUrlBaseRequest.Unmarshal(m, b)
1201 }
1202 func (m *ImagesDeleteUrlBaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1203 return xxx_messageInfo_ImagesDeleteUrlBaseRequest.Marshal(b, m, deterministic)
1204 }
1205 func (dst *ImagesDeleteUrlBaseRequest) XXX_Merge(src proto.Message) {
1206 xxx_messageInfo_ImagesDeleteUrlBaseRequest.Merge(dst, src)
1207 }
1208 func (m *ImagesDeleteUrlBaseRequest) XXX_Size() int {
1209 return xxx_messageInfo_ImagesDeleteUrlBaseRequest.Size(m)
1210 }
1211 func (m *ImagesDeleteUrlBaseRequest) XXX_DiscardUnknown() {
1212 xxx_messageInfo_ImagesDeleteUrlBaseRequest.DiscardUnknown(m)
1213 }
1214
1215 var xxx_messageInfo_ImagesDeleteUrlBaseRequest proto.InternalMessageInfo
1216
1217 func (m *ImagesDeleteUrlBaseRequest) GetBlobKey() string {
1218 if m != nil && m.BlobKey != nil {
1219 return *m.BlobKey
1220 }
1221 return ""
1222 }
1223
1224 type ImagesDeleteUrlBaseResponse struct {
1225 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1226 XXX_unrecognized []byte `json:"-"`
1227 XXX_sizecache int32 `json:"-"`
1228 }
1229
1230 func (m *ImagesDeleteUrlBaseResponse) Reset() { *m = ImagesDeleteUrlBaseResponse{} }
1231 func (m *ImagesDeleteUrlBaseResponse) String() string { return proto.CompactTextString(m) }
1232 func (*ImagesDeleteUrlBaseResponse) ProtoMessage() {}
1233 func (*ImagesDeleteUrlBaseResponse) Descriptor() ([]byte, []int) {
1234 return fileDescriptor_images_service_42a9d451721edce4, []int{18}
1235 }
1236 func (m *ImagesDeleteUrlBaseResponse) XXX_Unmarshal(b []byte) error {
1237 return xxx_messageInfo_ImagesDeleteUrlBaseResponse.Unmarshal(m, b)
1238 }
1239 func (m *ImagesDeleteUrlBaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1240 return xxx_messageInfo_ImagesDeleteUrlBaseResponse.Marshal(b, m, deterministic)
1241 }
1242 func (dst *ImagesDeleteUrlBaseResponse) XXX_Merge(src proto.Message) {
1243 xxx_messageInfo_ImagesDeleteUrlBaseResponse.Merge(dst, src)
1244 }
1245 func (m *ImagesDeleteUrlBaseResponse) XXX_Size() int {
1246 return xxx_messageInfo_ImagesDeleteUrlBaseResponse.Size(m)
1247 }
1248 func (m *ImagesDeleteUrlBaseResponse) XXX_DiscardUnknown() {
1249 xxx_messageInfo_ImagesDeleteUrlBaseResponse.DiscardUnknown(m)
1250 }
1251
1252 var xxx_messageInfo_ImagesDeleteUrlBaseResponse proto.InternalMessageInfo
1253
1254 func init() {
1255 proto.RegisterType((*ImagesServiceError)(nil), "appengine.ImagesServiceError")
1256 proto.RegisterType((*ImagesServiceTransform)(nil), "appengine.ImagesServiceTransform")
1257 proto.RegisterType((*Transform)(nil), "appengine.Transform")
1258 proto.RegisterType((*ImageData)(nil), "appengine.ImageData")
1259 proto.RegisterType((*InputSettings)(nil), "appengine.InputSettings")
1260 proto.RegisterType((*OutputSettings)(nil), "appengine.OutputSettings")
1261 proto.RegisterType((*ImagesTransformRequest)(nil), "appengine.ImagesTransformRequest")
1262 proto.RegisterType((*ImagesTransformResponse)(nil), "appengine.ImagesTransformResponse")
1263 proto.RegisterType((*CompositeImageOptions)(nil), "appengine.CompositeImageOptions")
1264 proto.RegisterType((*ImagesCanvas)(nil), "appengine.ImagesCanvas")
1265 proto.RegisterType((*ImagesCompositeRequest)(nil), "appengine.ImagesCompositeRequest")
1266 proto.RegisterType((*ImagesCompositeResponse)(nil), "appengine.ImagesCompositeResponse")
1267 proto.RegisterType((*ImagesHistogramRequest)(nil), "appengine.ImagesHistogramRequest")
1268 proto.RegisterType((*ImagesHistogram)(nil), "appengine.ImagesHistogram")
1269 proto.RegisterType((*ImagesHistogramResponse)(nil), "appengine.ImagesHistogramResponse")
1270 proto.RegisterType((*ImagesGetUrlBaseRequest)(nil), "appengine.ImagesGetUrlBaseRequest")
1271 proto.RegisterType((*ImagesGetUrlBaseResponse)(nil), "appengine.ImagesGetUrlBaseResponse")
1272 proto.RegisterType((*ImagesDeleteUrlBaseRequest)(nil), "appengine.ImagesDeleteUrlBaseRequest")
1273 proto.RegisterType((*ImagesDeleteUrlBaseResponse)(nil), "appengine.ImagesDeleteUrlBaseResponse")
1274 }
1275
1276 func init() {
1277 proto.RegisterFile("google.golang.org/appengine/v2/internal/image/images_service.proto", fileDescriptor_images_service_42a9d451721edce4)
1278 }
1279
1280 var fileDescriptor_images_service_42a9d451721edce4 = []byte{
1281 // 1460 bytes of a gzipped FileDescriptorProto
1282 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0xe3, 0xc6,
1283 0x15, 0x5e, 0x52, 0xff, 0xc7, 0xb2, 0xcc, 0x9d, 0xec, 0x0f, 0x77, 0x93, 0xa2, 0x0a, 0x83, 0xc5,
1284 0x1a, 0x41, 0x2a, 0xaf, 0x8d, 0x16, 0x2d, 0x7c, 0x93, 0xea, 0x87, 0x92, 0x99, 0x95, 0x44, 0x75,
1285 0x44, 0xa7, 0xeb, 0xbd, 0x19, 0xd0, 0xf2, 0x48, 0x26, 0x4a, 0x73, 0x98, 0xe1, 0xc8, 0xb1, 0x7a,
1286 0x51, 0xf4, 0xa6, 0x17, 0x05, 0xfa, 0x06, 0x7d, 0x8a, 0xbe, 0x45, 0x81, 0xbe, 0x41, 0xfb, 0x32,
1287 0xc5, 0x0c, 0x49, 0x99, 0xf6, 0x3a, 0x4d, 0xb3, 0x37, 0xc2, 0xcc, 0x39, 0xdf, 0xf9, 0x9d, 0x8f,
1288 0xe7, 0x08, 0xbe, 0x5e, 0x31, 0xb6, 0x0a, 0x69, 0x67, 0xc5, 0x42, 0x3f, 0x5a, 0x75, 0x18, 0x5f,
1289 0x1d, 0xf8, 0x71, 0x4c, 0xa3, 0x55, 0x10, 0xd1, 0x83, 0x20, 0x12, 0x94, 0x47, 0x7e, 0x78, 0x10,
1290 0x5c, 0xf9, 0x2b, 0x9a, 0xfe, 0x26, 0x24, 0xa1, 0xfc, 0x3a, 0x58, 0xd0, 0x4e, 0xcc, 0x99, 0x60,
1291 0xa8, 0xb1, 0x85, 0x5b, 0xff, 0xd4, 0x00, 0x39, 0x0a, 0x33, 0x4f, 0x21, 0x36, 0xe7, 0x8c, 0x5b,
1292 0xff, 0xd0, 0xa0, 0xa1, 0x4e, 0x7d, 0x76, 0x41, 0xd1, 0x53, 0x78, 0x7c, 0x3a, 0x9d, 0xcf, 0xec,
1293 0xbe, 0x33, 0x74, 0xec, 0x01, 0xb1, 0x31, 0x76, 0xb1, 0xa1, 0xa1, 0x67, 0x80, 0x7a, 0xdd, 0x01,
1294 0xf1, 0x70, 0x77, 0x3a, 0x1f, 0xba, 0x78, 0x42, 0x06, 0x5d, 0xaf, 0x6b, 0xe8, 0x68, 0x17, 0x1a,
1295 0x53, 0xd7, 0x23, 0xce, 0xa4, 0x3b, 0xb2, 0x8d, 0x12, 0x42, 0xd0, 0x92, 0x30, 0x75, 0x4d, 0x21,
1296 0x65, 0xf4, 0x09, 0xec, 0xa5, 0x77, 0xcf, 0x75, 0xc9, 0xb8, 0x8b, 0x47, 0xb6, 0x51, 0x41, 0x4f,
1297 0xc0, 0x70, 0xa6, 0xdf, 0x76, 0xc7, 0xce, 0x80, 0xf4, 0xc6, 0x6e, 0x8f, 0xbc, 0xb5, 0xcf, 0x8c,
1298 0x2a, 0x7a, 0x0c, 0xbb, 0xdd, 0x7e, 0xdf, 0x9e, 0xcf, 0xc9, 0xc0, 0x9e, 0x3a, 0xf6, 0xc0, 0xa8,
1299 0x49, 0xa0, 0xdb, 0xfb, 0xc6, 0xee, 0x7b, 0x44, 0xc6, 0x19, 0xba, 0xa7, 0xd3, 0x81, 0x51, 0xb7,
1300 0xfe, 0xac, 0xc1, 0xb3, 0x3b, 0xa5, 0x78, 0xdc, 0x8f, 0x92, 0x25, 0xe3, 0x57, 0xd6, 0x12, 0xca,
1301 0xde, 0x26, 0xa6, 0x08, 0xa0, 0x8a, 0xed, 0xb9, 0xf3, 0xde, 0x36, 0x34, 0x75, 0x76, 0xbd, 0xae,
1302 0x67, 0x1b, 0xba, 0x4c, 0xe7, 0xc4, 0xc5, 0xce, 0x7b, 0x77, 0xea, 0x75, 0xc7, 0x64, 0x38, 0x76,
1303 0x66, 0x46, 0x49, 0x06, 0xfe, 0xd6, 0xc6, 0x9e, 0xd3, 0xcf, 0x45, 0x65, 0x54, 0x87, 0x72, 0x1f,
1304 0xbb, 0xb3, 0x2c, 0xd7, 0x09, 0x19, 0xda, 0xf6, 0xd8, 0x99, 0x8e, 0xc8, 0xf8, 0xb4, 0xff, 0xf6,
1305 0xcc, 0xa8, 0x5a, 0x7f, 0x2b, 0x43, 0x63, 0x1b, 0x15, 0x3d, 0x81, 0xca, 0xf7, 0xc1, 0x85, 0xb8,
1306 0x34, 0xb5, 0xb6, 0xb6, 0x5f, 0xc1, 0xe9, 0x05, 0x3d, 0x83, 0xea, 0x25, 0x0d, 0x56, 0x97, 0xc2,
1307 0xd4, 0x95, 0x38, 0xbb, 0xa1, 0x57, 0xb0, 0xb3, 0xe0, 0x2c, 0x26, 0x82, 0x91, 0x65, 0x20, 0xcc,
1308 0x9d, 0xb6, 0xb6, 0x5f, 0x3f, 0xae, 0x2c, 0xfd, 0x30, 0xa1, 0xb8, 0x21, 0x35, 0x1e, 0x1b, 0x06,
1309 0x02, 0xbd, 0x86, 0x5d, 0x05, 0x63, 0xcb, 0x65, 0x42, 0x05, 0xb9, 0x31, 0x9b, 0x6d, 0x6d, 0x5f,
1310 0x3f, 0x2e, 0xbd, 0xe9, 0xfc, 0x0a, 0x2b, 0x07, 0xae, 0x52, 0xbc, 0xbb, 0x0f, 0xdc, 0x98, 0xbb,
1311 0x0f, 0x02, 0xcf, 0xd0, 0x0b, 0xa8, 0x72, 0x26, 0x7c, 0x41, 0xcd, 0x92, 0x4c, 0xe8, 0x58, 0x7b,
1312 0x83, 0x33, 0x01, 0xea, 0xc0, 0xde, 0x25, 0xe3, 0xc1, 0x1f, 0x59, 0x24, 0xfc, 0x90, 0x2c, 0xc3,
1313 0x20, 0x36, 0xcb, 0xc5, 0xbc, 0x5a, 0xb7, 0xda, 0x61, 0x18, 0xc4, 0xe8, 0x4b, 0xd8, 0xbd, 0xa6,
1314 0x5c, 0x04, 0x8b, 0x1c, 0x5d, 0x29, 0xa2, 0x9b, 0xb9, 0x4e, 0x61, 0x3f, 0xcf, 0xea, 0x0d, 0xe9,
1315 0x52, 0x96, 0x51, 0x55, 0xd9, 0x69, 0x6f, 0xd2, 0x5a, 0xc7, 0x74, 0x29, 0xde, 0xa1, 0x9f, 0x03,
1316 0x64, 0x2d, 0x89, 0xc9, 0xc6, 0xac, 0xe5, 0x88, 0x7a, 0xda, 0x8d, 0xf8, 0x0c, 0x7d, 0x01, 0x4d,
1317 0x05, 0xe0, 0xb2, 0x83, 0xe4, 0xc6, 0xac, 0xa7, 0x90, 0x43, 0xac, 0xec, 0xb0, 0x94, 0xbe, 0x43,
1318 0xaf, 0xb2, 0x46, 0x9c, 0x33, 0x21, 0xd8, 0x15, 0xd9, 0x98, 0x8d, 0x1c, 0xa5, 0x12, 0xe8, 0x29,
1319 0xf1, 0x19, 0x7a, 0x05, 0xe0, 0xaf, 0x05, 0x0b, 0xe9, 0x35, 0x0d, 0x13, 0x13, 0x8a, 0x89, 0x17,
1320 0x14, 0xb2, 0x44, 0x3f, 0x0c, 0xd9, 0xf7, 0x24, 0x11, 0x9c, 0x8a, 0xc5, 0xa5, 0xd9, 0xba, 0x53,
1321 0xa2, 0xd2, 0xcd, 0x53, 0x95, 0xc5, 0xa1, 0xa1, 0x08, 0x39, 0xf0, 0x85, 0x8f, 0x3e, 0x83, 0xda,
1322 0x82, 0x45, 0x82, 0x46, 0xc2, 0xd4, 0xda, 0xfa, 0x7e, 0xb3, 0xa7, 0xd7, 0x35, 0x9c, 0x8b, 0xd0,
1323 0x0b, 0xa8, 0x9f, 0x87, 0xec, 0x9c, 0xfc, 0x81, 0x6e, 0x14, 0x2f, 0x1a, 0xb8, 0x26, 0xef, 0x6f,
1324 0xe9, 0xe6, 0x96, 0x46, 0xa5, 0x87, 0x69, 0x54, 0x2e, 0xd2, 0xc8, 0xfa, 0xb7, 0x0e, 0xbb, 0x4e,
1325 0x14, 0xaf, 0xc5, 0x9c, 0x0a, 0x11, 0x44, 0xab, 0x04, 0xfd, 0x45, 0x03, 0x73, 0xc1, 0x38, 0xa7,
1326 0x0b, 0x41, 0xe8, 0x4d, 0xb0, 0x24, 0x8c, 0x07, 0x34, 0x12, 0xbe, 0x08, 0x58, 0xa4, 0xa8, 0xd9,
1327 0x3a, 0xfa, 0x65, 0x67, 0x3b, 0x11, 0x3a, 0x77, 0x8c, 0x3b, 0x2e, 0x76, 0xec, 0xa9, 0xd7, 0xf5,
1328 0x1c, 0x77, 0x4a, 0xfa, 0x2e, 0xc6, 0x76, 0x5f, 0x1d, 0xbd, 0xb3, 0x99, 0x7d, 0xfc, 0xf4, 0x74,
1329 0xda, 0x3f, 0xe9, 0x4e, 0x47, 0xf6, 0x80, 0x14, 0x60, 0xf8, 0x59, 0x16, 0xcc, 0xbe, 0x09, 0x96,
1330 0xee, 0x6d, 0x28, 0xf4, 0x15, 0xb4, 0x62, 0x9f, 0x27, 0x94, 0x5c, 0x51, 0xe1, 0x5f, 0xf8, 0xc2,
1331 0x57, 0x85, 0x6e, 0x5b, 0xb7, 0xab, 0x94, 0x93, 0x4c, 0x87, 0x7e, 0x0b, 0x9f, 0x09, 0xf9, 0x25,
1332 0xc5, 0x3e, 0xa7, 0x91, 0x20, 0xc9, 0xfa, 0x3c, 0x11, 0x81, 0x58, 0x4b, 0x4f, 0x84, 0xaf, 0xce,
1333 0xb3, 0x66, 0xbc, 0x2c, 0x60, 0xe6, 0x05, 0x08, 0x5e, 0x9d, 0x5b, 0xbf, 0x83, 0x4f, 0xff, 0x47,
1334 0xf6, 0xe8, 0x05, 0x3c, 0x9c, 0xbf, 0xf1, 0x08, 0x3d, 0x87, 0x4f, 0x32, 0xf4, 0x1d, 0x85, 0x66,
1335 0xfd, 0x5d, 0x83, 0x96, 0xbb, 0x16, 0xc5, 0xee, 0xda, 0xd0, 0xb8, 0x0a, 0xae, 0x28, 0x11, 0x9b,
1336 0x98, 0x66, 0xdd, 0xfc, 0xa2, 0xd0, 0xcd, 0xbb, 0xe8, 0xce, 0xc4, 0x99, 0xd8, 0x69, 0xf3, 0x4a,
1337 0xb3, 0xe9, 0x08, 0xd7, 0xa5, 0xa9, 0x9a, 0x4c, 0x26, 0xd4, 0xbe, 0x5b, 0xfb, 0x61, 0x20, 0x36,
1338 0xd9, 0x58, 0xc8, 0xaf, 0xd6, 0x3e, 0x34, 0xb6, 0x56, 0xa8, 0x06, 0xd2, 0xce, 0x78, 0x24, 0x27,
1339 0xd1, 0x37, 0x33, 0x7b, 0x64, 0x68, 0xf2, 0xf4, 0x7b, 0xbb, 0x37, 0x33, 0x74, 0xeb, 0x3f, 0xdb,
1340 0x01, 0xb8, 0x9d, 0x41, 0x98, 0x7e, 0xb7, 0xa6, 0x89, 0x40, 0x5f, 0x42, 0x45, 0x6d, 0x02, 0x45,
1341 0xbd, 0x9d, 0xa3, 0x27, 0xc5, 0xf7, 0xce, 0x19, 0x8a, 0x53, 0x08, 0x3a, 0x82, 0x86, 0xc8, 0xed,
1342 0x4d, 0xbd, 0x5d, 0xba, 0x87, 0xbf, 0xf5, 0x7d, 0x0b, 0x43, 0x87, 0x50, 0x65, 0xaa, 0x52, 0xb3,
1343 0xa4, 0x02, 0xbc, 0xf8, 0xc1, 0x16, 0xe0, 0x0c, 0x88, 0x3a, 0x50, 0x09, 0x24, 0xd5, 0x14, 0x7f,
1344 0x77, 0x8e, 0xcc, 0x1f, 0xa2, 0x20, 0x4e, 0x61, 0x56, 0x04, 0xcf, 0x3f, 0x28, 0x2e, 0x89, 0x59,
1345 0x94, 0xd0, 0x9f, 0x54, 0xdd, 0x6b, 0xd8, 0x4b, 0xd8, 0x9a, 0x2f, 0xee, 0xd1, 0xb0, 0x81, 0x5b,
1346 0xa9, 0x38, 0x27, 0xa0, 0xf5, 0x2f, 0x1d, 0x9e, 0xf6, 0xd9, 0x55, 0xcc, 0x92, 0x40, 0x50, 0xe5,
1347 0xc6, 0x8d, 0x25, 0xb5, 0x12, 0xf4, 0x39, 0x34, 0x33, 0x17, 0x41, 0x74, 0x41, 0x6f, 0x54, 0xd4,
1348 0x0a, 0xde, 0x49, 0x65, 0x8e, 0x14, 0xc9, 0xcf, 0xf9, 0x26, 0x9b, 0xbc, 0xa6, 0xae, 0xd4, 0xb5,
1349 0x9b, 0x74, 0xde, 0x4a, 0xd5, 0x26, 0x57, 0x95, 0x52, 0xd5, 0x26, 0x53, 0x99, 0x50, 0x63, 0xb1,
1350 0xbf, 0x90, 0x24, 0x28, 0xb7, 0xf5, 0x7d, 0x1d, 0xe7, 0x57, 0xf4, 0x35, 0x54, 0xfd, 0x68, 0x71,
1351 0xc9, 0xb8, 0x59, 0x69, 0xeb, 0xfb, 0xad, 0xa3, 0xd7, 0x85, 0x12, 0x1f, 0x4c, 0xb2, 0xd3, 0x9d,
1352 0xf6, 0x4f, 0x5c, 0x8c, 0x33, 0x33, 0xeb, 0x4f, 0x50, 0x4d, 0x25, 0xa8, 0x09, 0x75, 0xcf, 0x9d,
1353 0x91, 0xb1, 0x3d, 0xf4, 0x8c, 0x47, 0x92, 0x50, 0x9e, 0x3b, 0x33, 0x34, 0xb9, 0xb4, 0xa5, 0x18,
1354 0x3b, 0xa3, 0x13, 0xcf, 0xd0, 0x25, 0xab, 0x14, 0xa2, 0x24, 0xf7, 0x64, 0xdf, 0x9e, 0x7a, 0x36,
1355 0x36, 0xca, 0xa8, 0x01, 0x95, 0x14, 0x50, 0x41, 0x7b, 0xb0, 0xd3, 0x73, 0x3d, 0xcf, 0x9d, 0xa4,
1356 0x9e, 0xaa, 0x12, 0x97, 0x0a, 0x8c, 0x1a, 0x32, 0xa0, 0x99, 0x29, 0x53, 0x78, 0xdd, 0xfa, 0xab,
1357 0x06, 0xcd, 0xf4, 0xf9, 0xfa, 0x7e, 0x74, 0xed, 0x27, 0xc5, 0xe5, 0xa8, 0x3f, 0xbc, 0x1c, 0xf5,
1358 0xc2, 0x72, 0xfc, 0x08, 0x7e, 0x99, 0x50, 0x59, 0xb0, 0x90, 0xf1, 0x74, 0x3e, 0x1e, 0xeb, 0xbf,
1359 0x38, 0xc4, 0xa9, 0x40, 0xfe, 0xb9, 0xc9, 0xbe, 0x93, 0x6d, 0xeb, 0x1e, 0xf8, 0x4e, 0x4a, 0x3f,
1360 0xc6, 0xa4, 0x63, 0xf9, 0x5a, 0xaa, 0xd9, 0xd9, 0x57, 0xd2, 0xfe, 0xb1, 0x47, 0xc1, 0xb9, 0x01,
1361 0x3a, 0x80, 0xea, 0x42, 0xf5, 0x21, 0xab, 0xe7, 0xf9, 0xfd, 0x40, 0x59, 0x9b, 0x70, 0x06, 0xb3,
1362 0xec, 0x9c, 0xfd, 0x85, 0x94, 0x7f, 0x3a, 0xfb, 0xad, 0x41, 0x5e, 0xf9, 0x49, 0x90, 0x08, 0xb6,
1363 0xe2, 0xfe, 0xc7, 0x4c, 0x08, 0x6b, 0x02, 0x7b, 0xf7, 0xbc, 0x20, 0x03, 0x4a, 0x9c, 0x5e, 0xa8,
1364 0xb6, 0x55, 0xb0, 0x3c, 0xca, 0x07, 0x5e, 0x71, 0x4a, 0x23, 0xd5, 0x9c, 0x0a, 0x4e, 0x2f, 0x08,
1365 0x41, 0xf9, 0x3c, 0x5c, 0xcb, 0xbf, 0x1a, 0x52, 0xa8, 0xce, 0xd6, 0x3c, 0xaf, 0xad, 0x90, 0x54,
1366 0x56, 0xdb, 0x6f, 0xa0, 0x71, 0x99, 0x0b, 0xb3, 0xcc, 0x5e, 0x7e, 0xd0, 0xaa, 0x5b, 0xb3, 0x5b,
1367 0xb0, 0xb5, 0xca, 0x9d, 0x8e, 0xa8, 0x38, 0xe5, 0x61, 0xcf, 0x4f, 0xb6, 0x8f, 0x5c, 0xdc, 0xb5,
1368 0xd2, 0x67, 0x61, 0xd7, 0x1e, 0xc2, 0xe3, 0x05, 0xa7, 0xbe, 0xa0, 0x24, 0xa1, 0x8b, 0x35, 0xa7,
1369 0x64, 0xcd, 0xc3, 0xbb, 0x6b, 0x6a, 0x2f, 0xd5, 0xcf, 0x95, 0xfa, 0x94, 0x87, 0xd6, 0x57, 0x60,
1370 0x7e, 0x18, 0x28, 0x4b, 0xdf, 0x80, 0x92, 0x74, 0x90, 0x06, 0x91, 0x47, 0xeb, 0xd7, 0xf0, 0x32,
1371 0x45, 0x0f, 0x68, 0x48, 0x05, 0xfd, 0xbf, 0x33, 0xb3, 0x7e, 0x06, 0x9f, 0x3e, 0x68, 0x98, 0x46,
1372 0xea, 0xd5, 0xde, 0xa7, 0x6f, 0xf3, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x74, 0x30, 0x89,
1373 0x1d, 0x0c, 0x00, 0x00,
1374 }
0 syntax = "proto2";
1 option go_package = "image";
2
3 package appengine;
4
5 message ImagesServiceError {
6 enum ErrorCode {
7 UNSPECIFIED_ERROR = 1;
8 BAD_TRANSFORM_DATA = 2;
9 NOT_IMAGE = 3;
10 BAD_IMAGE_DATA = 4;
11 IMAGE_TOO_LARGE = 5;
12 INVALID_BLOB_KEY = 6;
13 ACCESS_DENIED = 7;
14 OBJECT_NOT_FOUND = 8;
15 }
16 }
17
18 message ImagesServiceTransform {
19 enum Type {
20 RESIZE = 1;
21 ROTATE = 2;
22 HORIZONTAL_FLIP = 3;
23 VERTICAL_FLIP = 4;
24 CROP = 5;
25 IM_FEELING_LUCKY = 6;
26 }
27 }
28
29 message Transform {
30 optional int32 width = 1;
31 optional int32 height = 2;
32 optional bool crop_to_fit = 11 [default = false];
33 optional float crop_offset_x = 12 [default = 0.5];
34 optional float crop_offset_y = 13 [default = 0.5];
35
36 optional int32 rotate = 3 [default = 0];
37
38 optional bool horizontal_flip = 4 [default = false];
39
40 optional bool vertical_flip = 5 [default = false];
41
42 optional float crop_left_x = 6 [default = 0.0];
43 optional float crop_top_y = 7 [default = 0.0];
44 optional float crop_right_x = 8 [default = 1.0];
45 optional float crop_bottom_y = 9 [default = 1.0];
46
47 optional bool autolevels = 10 [default = false];
48
49 optional bool allow_stretch = 14 [default = false];
50 }
51
52 message ImageData {
53 required bytes content = 1 [ctype=CORD];
54 optional string blob_key = 2;
55
56 optional int32 width = 3;
57 optional int32 height = 4;
58 }
59
60 message InputSettings {
61 enum ORIENTATION_CORRECTION_TYPE {
62 UNCHANGED_ORIENTATION = 0;
63 CORRECT_ORIENTATION = 1;
64 }
65 optional ORIENTATION_CORRECTION_TYPE correct_exif_orientation = 1
66 [default=UNCHANGED_ORIENTATION];
67 optional bool parse_metadata = 2 [default=false];
68 optional int32 transparent_substitution_rgb = 3;
69 }
70
71 message OutputSettings {
72 enum MIME_TYPE {
73 PNG = 0;
74 JPEG = 1;
75 WEBP = 2;
76 }
77
78 optional MIME_TYPE mime_type = 1 [default=PNG];
79 optional int32 quality = 2;
80 }
81
82 message ImagesTransformRequest {
83 required ImageData image = 1;
84 repeated Transform transform = 2;
85 required OutputSettings output = 3;
86 optional InputSettings input = 4;
87 }
88
89 message ImagesTransformResponse {
90 required ImageData image = 1;
91 optional string source_metadata = 2;
92 }
93
94 message CompositeImageOptions {
95 required int32 source_index = 1;
96 required int32 x_offset = 2;
97 required int32 y_offset = 3;
98 required float opacity = 4;
99
100 enum ANCHOR {
101 TOP_LEFT = 0;
102 TOP = 1;
103 TOP_RIGHT = 2;
104 LEFT = 3;
105 CENTER = 4;
106 RIGHT = 5;
107 BOTTOM_LEFT = 6;
108 BOTTOM = 7;
109 BOTTOM_RIGHT = 8;
110 }
111
112 required ANCHOR anchor = 5;
113 }
114
115 message ImagesCanvas {
116 required int32 width = 1;
117 required int32 height = 2;
118 required OutputSettings output = 3;
119 optional int32 color = 4 [default=-1];
120 }
121
122 message ImagesCompositeRequest {
123 repeated ImageData image = 1;
124 repeated CompositeImageOptions options = 2;
125 required ImagesCanvas canvas = 3;
126 }
127
128 message ImagesCompositeResponse {
129 required ImageData image = 1;
130 }
131
132 message ImagesHistogramRequest {
133 required ImageData image = 1;
134 }
135
136 message ImagesHistogram {
137 repeated int32 red = 1;
138 repeated int32 green = 2;
139 repeated int32 blue = 3;
140 }
141
142 message ImagesHistogramResponse {
143 required ImagesHistogram histogram = 1;
144 }
145
146 message ImagesGetUrlBaseRequest {
147 required string blob_key = 1;
148
149 optional bool create_secure_url = 2 [default = false];
150 }
151
152 message ImagesGetUrlBaseResponse {
153 required string url = 1;
154 }
155
156 message ImagesDeleteUrlBaseRequest {
157 required string blob_key = 1;
158 }
159
160 message ImagesDeleteUrlBaseResponse {
161 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package internal provides support for package appengine.
5 //
6 // Programs should not use this package directly. Its API is not stable.
7 // Use packages appengine and appengine/* instead.
8 package internal
9
10 import (
11 "fmt"
12
13 "github.com/golang/protobuf/proto"
14
15 remotepb "google.golang.org/appengine/v2/internal/remote_api"
16 )
17
18 // errorCodeMaps is a map of service name to the error code map for the service.
19 var errorCodeMaps = make(map[string]map[int32]string)
20
21 // RegisterErrorCodeMap is called from API implementations to register their
22 // error code map. This should only be called from init functions.
23 func RegisterErrorCodeMap(service string, m map[int32]string) {
24 errorCodeMaps[service] = m
25 }
26
27 type timeoutCodeKey struct {
28 service string
29 code int32
30 }
31
32 // timeoutCodes is the set of service+code pairs that represent timeouts.
33 var timeoutCodes = make(map[timeoutCodeKey]bool)
34
35 func RegisterTimeoutErrorCode(service string, code int32) {
36 timeoutCodes[timeoutCodeKey{service, code}] = true
37 }
38
39 // APIError is the type returned by appengine.Context's Call method
40 // when an API call fails in an API-specific way. This may be, for instance,
41 // a taskqueue API call failing with TaskQueueServiceError::UNKNOWN_QUEUE.
42 type APIError struct {
43 Service string
44 Detail string
45 Code int32 // API-specific error code
46 }
47
48 func (e *APIError) Error() string {
49 if e.Code == 0 {
50 if e.Detail == "" {
51 return "APIError <empty>"
52 }
53 return e.Detail
54 }
55 s := fmt.Sprintf("API error %d", e.Code)
56 if m, ok := errorCodeMaps[e.Service]; ok {
57 s += " (" + e.Service + ": " + m[e.Code] + ")"
58 } else {
59 // Shouldn't happen, but provide a bit more detail if it does.
60 s = e.Service + " " + s
61 }
62 if e.Detail != "" {
63 s += ": " + e.Detail
64 }
65 return s
66 }
67
68 func (e *APIError) IsTimeout() bool {
69 return timeoutCodes[timeoutCodeKey{e.Service, e.Code}]
70 }
71
72 // CallError is the type returned by appengine.Context's Call method when an
73 // API call fails in a generic way, such as RpcError::CAPABILITY_DISABLED.
74 type CallError struct {
75 Detail string
76 Code int32
77 // TODO: Remove this if we get a distinguishable error code.
78 Timeout bool
79 }
80
81 func (e *CallError) Error() string {
82 var msg string
83 switch remotepb.RpcError_ErrorCode(e.Code) {
84 case remotepb.RpcError_UNKNOWN:
85 return e.Detail
86 case remotepb.RpcError_OVER_QUOTA:
87 msg = "Over quota"
88 case remotepb.RpcError_CAPABILITY_DISABLED:
89 msg = "Capability disabled"
90 case remotepb.RpcError_CANCELLED:
91 msg = "Canceled"
92 default:
93 msg = fmt.Sprintf("Call error %d", e.Code)
94 }
95 s := msg + ": " + e.Detail
96 if e.Timeout {
97 s += " (timeout)"
98 }
99 return s
100 }
101
102 func (e *CallError) IsTimeout() bool {
103 return e.Timeout
104 }
105
106 // NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace.
107 // The function should be prepared to be called on the same message more than once; it should only modify the
108 // RPC request the first time.
109 var NamespaceMods = make(map[string]func(m proto.Message, namespace string))
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "io"
8 "io/ioutil"
9 "net/http"
10 "net/http/httptest"
11 "testing"
12 )
13
14 func TestInstallingHealthChecker(t *testing.T) {
15 try := func(desc string, mux *http.ServeMux, wantCode int, wantBody string) {
16 installHealthChecker(mux)
17 srv := httptest.NewServer(mux)
18 defer srv.Close()
19
20 resp, err := http.Get(srv.URL + "/_ah/health")
21 if err != nil {
22 t.Errorf("%s: http.Get: %v", desc, err)
23 return
24 }
25 defer resp.Body.Close()
26 body, err := ioutil.ReadAll(resp.Body)
27 if err != nil {
28 t.Errorf("%s: reading body: %v", desc, err)
29 return
30 }
31
32 if resp.StatusCode != wantCode {
33 t.Errorf("%s: got HTTP %d, want %d", desc, resp.StatusCode, wantCode)
34 return
35 }
36 if wantBody != "" && string(body) != wantBody {
37 t.Errorf("%s: got HTTP body %q, want %q", desc, body, wantBody)
38 return
39 }
40 }
41
42 // If there's no handlers, or only a root handler, a health checker should be installed.
43 try("empty mux", http.NewServeMux(), 200, "ok")
44 mux := http.NewServeMux()
45 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
46 io.WriteString(w, "root handler")
47 })
48 try("mux with root handler", mux, 200, "ok")
49
50 // If there's a custom health check handler, one should not be installed.
51 mux = http.NewServeMux()
52 mux.HandleFunc("/_ah/health", func(w http.ResponseWriter, r *http.Request) {
53 w.WriteHeader(418)
54 io.WriteString(w, "I'm short and stout!")
55 })
56 try("mux with custom health checker", mux, 418, "I'm short and stout!")
57 }
0 // Copyright 2021 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "encoding/json"
8 "fmt"
9 "regexp"
10 "strings"
11 )
12
13 var (
14 logLevelName = map[int64]string{
15 0: "DEBUG",
16 1: "INFO",
17 2: "WARNING",
18 3: "ERROR",
19 4: "CRITICAL",
20 }
21 traceContextRe = regexp.MustCompile(`^(\w+)/(\d+)(?:;o=[01])?$`)
22
23 // maxLogMessage is the largest message that will be logged without chunking, reserving room for prefixes.
24 // See http://cloud/logging/quotas#log-limits
25 maxLogMessage = 255000
26 )
27
28 func logf(c *context, level int64, format string, args ...interface{}) {
29 if c == nil {
30 panic("not an App Engine context")
31 }
32
33 if !IsStandard() {
34 s := strings.TrimRight(fmt.Sprintf(format, args...), "\n")
35 now := timeNow().UTC()
36 timestamp := fmt.Sprintf("%d/%02d/%02d %02d:%02d:%02d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
37 fmt.Fprintf(logStream, "%s %s: %s\n", timestamp, logLevelName[level], s)
38 return
39 }
40
41 eol := func(s string) string {
42 if strings.HasSuffix(s, "\n") {
43 return ""
44 }
45 return "\n"
46 }
47
48 msg := fmt.Sprintf(format, args...)
49
50 if strings.HasPrefix(msg, "{") {
51 // Assume the message is already structured, leave as-is unless it is too long.
52 // Note: chunking destroys the structure; developers will have to ensure their structured log
53 // is small enough to fit in a single message.
54 for _, m := range chunkLog(msg) {
55 fmt.Fprint(logStream, m, eol(m))
56 }
57 return
58 }
59
60 // First chunk the message, then structure each chunk.
61 traceID, spanID := traceAndSpan(c)
62 for _, m := range chunkLog(msg) {
63 sl := structuredLog{
64 Message: m,
65 Severity: logLevelName[level],
66 TraceID: traceID,
67 SpanID: spanID,
68 }
69 if b, err := json.Marshal(sl); err != nil {
70 // Write raw message if error.
71 fmt.Fprint(logStream, m, eol(m))
72 } else {
73 s := string(b)
74 fmt.Fprint(logStream, s, eol(s))
75 }
76 }
77 }
78
79 type structuredLog struct {
80 Message string `json:"message"`
81 Severity string `json:"severity"`
82 TraceID string `json:"logging.googleapis.com/trace,omitempty"`
83 SpanID string `json:"logging.googleapis.com/spanId,omitempty"`
84 }
85
86 func chunkLog(msg string) []string {
87 if len(msg) <= maxLogMessage {
88 return []string{msg}
89 }
90 var chunks []string
91 i := 0
92 for {
93 if i == len(msg) {
94 break
95 }
96 if i+maxLogMessage > len(msg) {
97 chunks = append(chunks, msg[i:])
98 break
99 }
100 chunks = append(chunks, msg[i:i+maxLogMessage])
101 i += maxLogMessage
102 }
103 for i, c := range chunks {
104 chunks[i] = fmt.Sprintf("Part %d/%d: ", i+1, len(chunks)) + c
105 }
106 return chunks
107 }
108
109 func traceAndSpan(c *context) (string, string) {
110 headers := c.req.Header["X-Cloud-Trace-Context"]
111 if len(headers) < 1 {
112 return "", ""
113 }
114 matches := traceContextRe.FindAllStringSubmatch(headers[0], -1)
115 if len(matches) < 1 || len(matches[0]) < 3 {
116 return "", ""
117 }
118 traceID := matches[0][1]
119 spanID := matches[0][2]
120 projectID := projectID()
121 return fmt.Sprintf("projects/%s/traces/%s", projectID, traceID), spanID
122 }
0 // Copyright 2021 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "bytes"
8 "encoding/json"
9 "fmt"
10 "io"
11 "net/http"
12 "os"
13 "reflect"
14 "testing"
15 "time"
16 )
17
18 func TestLogf(t *testing.T) {
19 testCases := []struct {
20 name string
21 deployed bool
22 level int64
23 format string
24 header string
25 args []interface{}
26 maxLogMessage int
27 want string
28 wantJSON bool
29 }{
30 {
31 name: "local-debug",
32 level: 0,
33 format: "my %s %d",
34 args: []interface{}{"abc", 1},
35 want: "2021/05/12 16:09:52 DEBUG: my abc 1\n",
36 },
37 {
38 name: "local-info",
39 level: 1,
40 format: "my %s %d",
41 args: []interface{}{"abc", 1},
42 want: "2021/05/12 16:09:52 INFO: my abc 1\n",
43 },
44 {
45 name: "local-warning",
46 level: 2,
47 format: "my %s %d",
48 args: []interface{}{"abc", 1},
49 want: "2021/05/12 16:09:52 WARNING: my abc 1\n",
50 },
51 {
52 name: "local-error",
53 level: 3,
54 format: "my %s %d",
55 args: []interface{}{"abc", 1},
56 want: "2021/05/12 16:09:52 ERROR: my abc 1\n",
57 },
58 {
59 name: "local-critical",
60 level: 4,
61 format: "my %s %d",
62 args: []interface{}{"abc", 1},
63 want: "2021/05/12 16:09:52 CRITICAL: my abc 1\n",
64 },
65 {
66 name: "local-multiline",
67 level: 0,
68 format: "my \n multiline\n\n",
69 want: "2021/05/12 16:09:52 DEBUG: my \n multiline\n",
70 },
71 {
72 name: "local-long-lines-not-split",
73 maxLogMessage: 10,
74 format: "0123456789a123",
75 want: "2021/05/12 16:09:52 DEBUG: 0123456789a123\n",
76 },
77 {
78 name: "deployed-plain-debug",
79 deployed: true,
80 level: 0,
81 format: "my %s %d",
82 args: []interface{}{"abc", 1},
83 want: `{"message":"my abc 1","severity":"DEBUG"}` + "\n",
84 wantJSON: true,
85 },
86 {
87 name: "deployed-plain-info",
88 deployed: true,
89 level: 1,
90 format: "my %s %d",
91 args: []interface{}{"abc", 1},
92 want: `{"message":"my abc 1","severity":"INFO"}` + "\n",
93 wantJSON: true,
94 },
95 {
96 name: "deployed-plain-warning",
97 deployed: true,
98 level: 2,
99 format: "my %s %d",
100 args: []interface{}{"abc", 1},
101 want: `{"message":"my abc 1","severity":"WARNING"}` + "\n",
102 wantJSON: true,
103 },
104 {
105 name: "deployed-plain-error",
106 deployed: true,
107 level: 3,
108 format: "my %s %d",
109 args: []interface{}{"abc", 1},
110 want: `{"message":"my abc 1","severity":"ERROR"}` + "\n",
111 wantJSON: true,
112 },
113 {
114 name: "deployed-plain-critical",
115 deployed: true,
116 level: 4,
117 format: "my %s %d",
118 args: []interface{}{"abc", 1},
119 want: `{"message":"my abc 1","severity":"CRITICAL"}` + "\n",
120 wantJSON: true,
121 },
122 {
123 name: "deployed-plain-multiline",
124 deployed: true,
125 level: 0,
126 format: "my \n multiline\n\n",
127 want: "{\"message\":\"my \\n multiline\\n\\n\",\"severity\":\"DEBUG\"}\n",
128 wantJSON: true,
129 },
130 {
131 name: "deployed-plain-megaquote",
132 deployed: true,
133 level: 0,
134 format: `my "megaquote" %q`,
135 args: []interface{}{`internal "quote"`},
136 want: "{\"message\":\"my \\\"megaquote\\\" \\\"internal \\\\\\\"quote\\\\\\\"\\\"\",\"severity\":\"DEBUG\"}\n",
137 wantJSON: true,
138 },
139 {
140 name: "deployed-too-long",
141 deployed: true,
142 format: "0123456789a123",
143 maxLogMessage: 10,
144 want: "{\"message\":\"Part 1/2: 0123456789\",\"severity\":\"DEBUG\"}\n{\"message\":\"Part 2/2: a123\",\"severity\":\"DEBUG\"}\n",
145 },
146 {
147 name: "deployed-with-trace-header",
148 deployed: true,
149 format: "my message",
150 header: "abc123/1234",
151 want: "{\"message\":\"my message\",\"severity\":\"DEBUG\",\"logging.googleapis.com/trace\":\"projects/my-project/traces/abc123\",\"logging.googleapis.com/spanId\":\"1234\"}\n",
152 },
153 {
154 name: "deployed-structured-debug",
155 deployed: true,
156 level: 0,
157 format: `{"some": "message %s %d"}`,
158 args: []interface{}{"abc", 1},
159 want: `{"some": "message abc 1"}` + "\n",
160 },
161 {
162 name: "deployed-structured-info",
163 deployed: true,
164 level: 1,
165 format: `{"some": "message %s %d"}`,
166 args: []interface{}{"abc", 1},
167 want: `{"some": "message abc 1"}` + "\n",
168 },
169 {
170 name: "deployed-structured-warning",
171 deployed: true,
172 level: 2,
173 format: `{"some": "message %s %d"}`,
174 args: []interface{}{"abc", 1},
175 want: `{"some": "message abc 1"}` + "\n",
176 },
177 {
178 name: "deployed-structured-error",
179 deployed: true,
180 level: 3,
181 format: `{"some": "message %s %d"}`,
182 args: []interface{}{"abc", 1},
183 want: `{"some": "message abc 1"}` + "\n",
184 },
185 {
186 name: "deployed-structured-critical",
187 deployed: true,
188 level: 4,
189 format: `{"some": "message %s %d"}`,
190 args: []interface{}{"abc", 1},
191 want: `{"some": "message abc 1"}` + "\n",
192 },
193 {
194 // The leading "{" assumes this is already a structured log, so no alteration is performed.
195 name: "deployed-structured-multiline",
196 deployed: true,
197 level: 4,
198 // This is not even valid JSON; we don't attempt to validate and only use the first character.
199 format: "{\"some\": \"message\n%s %d\"",
200 args: []interface{}{"abc", 1},
201 want: "{\"some\": \"message\nabc 1\"\n",
202 },
203 {
204 name: "deployed-structured-too-long",
205 deployed: true,
206 format: `{"message": "abc", "severity": "DEBUG"}`,
207 maxLogMessage: 25,
208 // User-structured logs must manually chunk; here we can see the structured message is (knowingly) broken.
209 want: "Part 1/2: {\"message\": \"abc\", \"sever\nPart 2/2: ity\": \"DEBUG\"}\n",
210 },
211 {
212 name: "deployed-structured-with-trace-header",
213 deployed: true,
214 format: `{"message": "abc", "severity": "DEBUG"}`,
215 header: "abc123/1234",
216 want: "{\"message\": \"abc\", \"severity\": \"DEBUG\"}\n",
217 },
218 }
219
220 for _, tc := range testCases {
221 t.Run(tc.name, func(t *testing.T) {
222 env := ""
223 if tc.deployed {
224 env = "standard"
225 }
226 defer setEnvVar(t, "GAE_ENV", env)()
227 defer setEnvVar(t, "GOOGLE_CLOUD_PROJECT", "my-project")()
228 var buf bytes.Buffer
229 defer overrideLogStream(t, &buf)()
230 defer overrideTimeNow(t, time.Date(2021, 5, 12, 16, 9, 52, 0, time.UTC))()
231 if tc.maxLogMessage > 0 {
232 defer overrideMaxLogMessage(t, tc.maxLogMessage)()
233 }
234 var headers []string
235 if tc.header != "" {
236 headers = []string{tc.header}
237 }
238 c := buildContextWithTraceHeaders(t, headers)
239
240 logf(c, tc.level, tc.format, tc.args...)
241
242 if got, want := buf.String(), tc.want; got != want {
243 t.Errorf("incorrect log got=%q want=%q", got, want)
244 }
245
246 if tc.wantJSON {
247 var e struct {
248 Message string `json:"message"`
249 Severity string `json:"severity"`
250 }
251 if err := json.Unmarshal(buf.Bytes(), &e); err != nil {
252 t.Fatalf("invalid JSON: %v", err)
253 }
254 if gotMsg, wantMsg := e.Message, fmt.Sprintf(tc.format, tc.args...); gotMsg != wantMsg {
255 t.Errorf("JSON-encoded message incorrect got=%q want=%q", gotMsg, wantMsg)
256 }
257 if gotSev, wantSev := e.Severity, logLevelName[tc.level]; gotSev != wantSev {
258 t.Errorf("JSON-encoded severity incorrect got=%q want=%q", gotSev, wantSev)
259 }
260 }
261 })
262 }
263 }
264
265 func TestChunkLog(t *testing.T) {
266 testCases := []struct {
267 name string
268 msg string
269 want []string
270 }{
271 {
272 name: "empty",
273 msg: "",
274 want: []string{""},
275 },
276 {
277 name: "short",
278 msg: "short msg",
279 want: []string{"short msg"},
280 },
281 {
282 name: "exactly max",
283 msg: "0123456789",
284 want: []string{"0123456789"},
285 },
286 {
287 name: "too long",
288 msg: "0123456789a123",
289 want: []string{
290 "Part 1/2: 0123456789",
291 "Part 2/2: a123",
292 },
293 },
294 {
295 name: "too long exactly max",
296 msg: "0123456789a123456789",
297 want: []string{
298 "Part 1/2: 0123456789",
299 "Part 2/2: a123456789",
300 },
301 },
302 {
303 name: "longer",
304 msg: "0123456789a123456789b123456789c",
305 want: []string{
306 "Part 1/4: 0123456789",
307 "Part 2/4: a123456789",
308 "Part 3/4: b123456789",
309 "Part 4/4: c",
310 },
311 },
312 }
313
314 for _, tc := range testCases {
315 t.Run(tc.name, func(t *testing.T) {
316 defer overrideMaxLogMessage(t, 10)()
317
318 got := chunkLog(tc.msg)
319
320 if !reflect.DeepEqual(got, tc.want) {
321 t.Errorf("chunkLog() got=%q want=%q", got, tc.want)
322 }
323 })
324 }
325 }
326
327 func TestTraceAndSpan(t *testing.T) {
328 testCases := []struct {
329 name string
330 header []string
331 wantTraceID string
332 wantSpanID string
333 }{
334 {
335 name: "empty",
336 },
337 {
338 name: "header present, but empty",
339 header: []string{""},
340 },
341 {
342 name: "trace and span",
343 header: []string{"abc1234/456"},
344 wantTraceID: "projects/my-project/traces/abc1234",
345 wantSpanID: "456",
346 },
347 {
348 name: "trace and span with suffix",
349 header: []string{"abc1234/456;o=0"},
350 wantTraceID: "projects/my-project/traces/abc1234",
351 wantSpanID: "456",
352 },
353 {
354 name: "multiple headers, first taken",
355 header: []string{
356 "abc1234/456;o=1",
357 "zzzzzzz/999;o=0",
358 },
359 wantTraceID: "projects/my-project/traces/abc1234",
360 wantSpanID: "456",
361 },
362 {
363 name: "missing trace",
364 header: []string{"/456"},
365 },
366 {
367 name: "missing span",
368 header: []string{"abc1234/"},
369 },
370 {
371 name: "random",
372 header: []string{"somestring"},
373 },
374 }
375
376 for _, tc := range testCases {
377 t.Run(tc.name, func(t *testing.T) {
378 defer setEnvVar(t, "GOOGLE_CLOUD_PROJECT", "my-project")()
379 c := buildContextWithTraceHeaders(t, tc.header)
380
381 gotTraceID, gotSpanID := traceAndSpan(c)
382
383 if got, want := gotTraceID, tc.wantTraceID; got != want {
384 t.Errorf("Incorrect traceID got=%q want=%q", got, want)
385 }
386 if got, want := gotSpanID, tc.wantSpanID; got != want {
387 t.Errorf("Incorrect spanID got=%q want=%q", got, want)
388 }
389 })
390 }
391 }
392
393 func setEnvVar(t *testing.T, key, value string) func() {
394 t.Helper()
395 old, present := os.LookupEnv(key)
396 if err := os.Setenv(key, value); err != nil {
397 t.Fatal(err)
398 }
399 return func() {
400 if present {
401 if err := os.Setenv(key, old); err != nil {
402 t.Fatal(err)
403 }
404 if err := os.Unsetenv(key); err != nil {
405 t.Fatal(err)
406 }
407 }
408 }
409 }
410
411 func overrideLogStream(t *testing.T, writer io.Writer) func() {
412 t.Helper()
413 old := logStream
414 logStream = writer
415 return func() { logStream = old }
416 }
417
418 func overrideTimeNow(t *testing.T, now time.Time) func() {
419 t.Helper()
420 old := timeNow
421 timeNow = func() time.Time { return now }
422 return func() { timeNow = old }
423 }
424
425 func overrideMaxLogMessage(t *testing.T, max int) func() {
426 t.Helper()
427 old := maxLogMessage
428 maxLogMessage = max
429 return func() { maxLogMessage = old }
430 }
431
432 func buildContextWithTraceHeaders(t *testing.T, headers []string) *context {
433 t.Helper()
434 req, err := http.NewRequest("GET", "/", nil)
435 if err != nil {
436 t.Fatal(err)
437 }
438 for _, h := range headers {
439 req.Header.Add("X-Cloud-Trace-Context", h)
440 }
441 return fromContext(ContextForTesting(req))
442 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/mail/mail_service.proto
2
3 package mail
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type MailServiceError_ErrorCode int32
21
22 const (
23 MailServiceError_OK MailServiceError_ErrorCode = 0
24 MailServiceError_INTERNAL_ERROR MailServiceError_ErrorCode = 1
25 MailServiceError_BAD_REQUEST MailServiceError_ErrorCode = 2
26 MailServiceError_UNAUTHORIZED_SENDER MailServiceError_ErrorCode = 3
27 MailServiceError_INVALID_ATTACHMENT_TYPE MailServiceError_ErrorCode = 4
28 MailServiceError_INVALID_HEADER_NAME MailServiceError_ErrorCode = 5
29 MailServiceError_INVALID_CONTENT_ID MailServiceError_ErrorCode = 6
30 )
31
32 var MailServiceError_ErrorCode_name = map[int32]string{
33 0: "OK",
34 1: "INTERNAL_ERROR",
35 2: "BAD_REQUEST",
36 3: "UNAUTHORIZED_SENDER",
37 4: "INVALID_ATTACHMENT_TYPE",
38 5: "INVALID_HEADER_NAME",
39 6: "INVALID_CONTENT_ID",
40 }
41 var MailServiceError_ErrorCode_value = map[string]int32{
42 "OK": 0,
43 "INTERNAL_ERROR": 1,
44 "BAD_REQUEST": 2,
45 "UNAUTHORIZED_SENDER": 3,
46 "INVALID_ATTACHMENT_TYPE": 4,
47 "INVALID_HEADER_NAME": 5,
48 "INVALID_CONTENT_ID": 6,
49 }
50
51 func (x MailServiceError_ErrorCode) Enum() *MailServiceError_ErrorCode {
52 p := new(MailServiceError_ErrorCode)
53 *p = x
54 return p
55 }
56 func (x MailServiceError_ErrorCode) String() string {
57 return proto.EnumName(MailServiceError_ErrorCode_name, int32(x))
58 }
59 func (x *MailServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
60 value, err := proto.UnmarshalJSONEnum(MailServiceError_ErrorCode_value, data, "MailServiceError_ErrorCode")
61 if err != nil {
62 return err
63 }
64 *x = MailServiceError_ErrorCode(value)
65 return nil
66 }
67 func (MailServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
68 return fileDescriptor_mail_service_78722be3c4c01d17, []int{0, 0}
69 }
70
71 type MailServiceError struct {
72 XXX_NoUnkeyedLiteral struct{} `json:"-"`
73 XXX_unrecognized []byte `json:"-"`
74 XXX_sizecache int32 `json:"-"`
75 }
76
77 func (m *MailServiceError) Reset() { *m = MailServiceError{} }
78 func (m *MailServiceError) String() string { return proto.CompactTextString(m) }
79 func (*MailServiceError) ProtoMessage() {}
80 func (*MailServiceError) Descriptor() ([]byte, []int) {
81 return fileDescriptor_mail_service_78722be3c4c01d17, []int{0}
82 }
83 func (m *MailServiceError) XXX_Unmarshal(b []byte) error {
84 return xxx_messageInfo_MailServiceError.Unmarshal(m, b)
85 }
86 func (m *MailServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
87 return xxx_messageInfo_MailServiceError.Marshal(b, m, deterministic)
88 }
89 func (dst *MailServiceError) XXX_Merge(src proto.Message) {
90 xxx_messageInfo_MailServiceError.Merge(dst, src)
91 }
92 func (m *MailServiceError) XXX_Size() int {
93 return xxx_messageInfo_MailServiceError.Size(m)
94 }
95 func (m *MailServiceError) XXX_DiscardUnknown() {
96 xxx_messageInfo_MailServiceError.DiscardUnknown(m)
97 }
98
99 var xxx_messageInfo_MailServiceError proto.InternalMessageInfo
100
101 type MailAttachment struct {
102 FileName *string `protobuf:"bytes,1,req,name=FileName" json:"FileName,omitempty"`
103 Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data,omitempty"`
104 ContentID *string `protobuf:"bytes,3,opt,name=ContentID" json:"ContentID,omitempty"`
105 XXX_NoUnkeyedLiteral struct{} `json:"-"`
106 XXX_unrecognized []byte `json:"-"`
107 XXX_sizecache int32 `json:"-"`
108 }
109
110 func (m *MailAttachment) Reset() { *m = MailAttachment{} }
111 func (m *MailAttachment) String() string { return proto.CompactTextString(m) }
112 func (*MailAttachment) ProtoMessage() {}
113 func (*MailAttachment) Descriptor() ([]byte, []int) {
114 return fileDescriptor_mail_service_78722be3c4c01d17, []int{1}
115 }
116 func (m *MailAttachment) XXX_Unmarshal(b []byte) error {
117 return xxx_messageInfo_MailAttachment.Unmarshal(m, b)
118 }
119 func (m *MailAttachment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
120 return xxx_messageInfo_MailAttachment.Marshal(b, m, deterministic)
121 }
122 func (dst *MailAttachment) XXX_Merge(src proto.Message) {
123 xxx_messageInfo_MailAttachment.Merge(dst, src)
124 }
125 func (m *MailAttachment) XXX_Size() int {
126 return xxx_messageInfo_MailAttachment.Size(m)
127 }
128 func (m *MailAttachment) XXX_DiscardUnknown() {
129 xxx_messageInfo_MailAttachment.DiscardUnknown(m)
130 }
131
132 var xxx_messageInfo_MailAttachment proto.InternalMessageInfo
133
134 func (m *MailAttachment) GetFileName() string {
135 if m != nil && m.FileName != nil {
136 return *m.FileName
137 }
138 return ""
139 }
140
141 func (m *MailAttachment) GetData() []byte {
142 if m != nil {
143 return m.Data
144 }
145 return nil
146 }
147
148 func (m *MailAttachment) GetContentID() string {
149 if m != nil && m.ContentID != nil {
150 return *m.ContentID
151 }
152 return ""
153 }
154
155 type MailHeader struct {
156 Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
157 Value *string `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
158 XXX_NoUnkeyedLiteral struct{} `json:"-"`
159 XXX_unrecognized []byte `json:"-"`
160 XXX_sizecache int32 `json:"-"`
161 }
162
163 func (m *MailHeader) Reset() { *m = MailHeader{} }
164 func (m *MailHeader) String() string { return proto.CompactTextString(m) }
165 func (*MailHeader) ProtoMessage() {}
166 func (*MailHeader) Descriptor() ([]byte, []int) {
167 return fileDescriptor_mail_service_78722be3c4c01d17, []int{2}
168 }
169 func (m *MailHeader) XXX_Unmarshal(b []byte) error {
170 return xxx_messageInfo_MailHeader.Unmarshal(m, b)
171 }
172 func (m *MailHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
173 return xxx_messageInfo_MailHeader.Marshal(b, m, deterministic)
174 }
175 func (dst *MailHeader) XXX_Merge(src proto.Message) {
176 xxx_messageInfo_MailHeader.Merge(dst, src)
177 }
178 func (m *MailHeader) XXX_Size() int {
179 return xxx_messageInfo_MailHeader.Size(m)
180 }
181 func (m *MailHeader) XXX_DiscardUnknown() {
182 xxx_messageInfo_MailHeader.DiscardUnknown(m)
183 }
184
185 var xxx_messageInfo_MailHeader proto.InternalMessageInfo
186
187 func (m *MailHeader) GetName() string {
188 if m != nil && m.Name != nil {
189 return *m.Name
190 }
191 return ""
192 }
193
194 func (m *MailHeader) GetValue() string {
195 if m != nil && m.Value != nil {
196 return *m.Value
197 }
198 return ""
199 }
200
201 type MailMessage struct {
202 Sender *string `protobuf:"bytes,1,req,name=Sender" json:"Sender,omitempty"`
203 ReplyTo *string `protobuf:"bytes,2,opt,name=ReplyTo" json:"ReplyTo,omitempty"`
204 To []string `protobuf:"bytes,3,rep,name=To" json:"To,omitempty"`
205 Cc []string `protobuf:"bytes,4,rep,name=Cc" json:"Cc,omitempty"`
206 Bcc []string `protobuf:"bytes,5,rep,name=Bcc" json:"Bcc,omitempty"`
207 Subject *string `protobuf:"bytes,6,req,name=Subject" json:"Subject,omitempty"`
208 TextBody *string `protobuf:"bytes,7,opt,name=TextBody" json:"TextBody,omitempty"`
209 HtmlBody *string `protobuf:"bytes,8,opt,name=HtmlBody" json:"HtmlBody,omitempty"`
210 Attachment []*MailAttachment `protobuf:"bytes,9,rep,name=Attachment" json:"Attachment,omitempty"`
211 Header []*MailHeader `protobuf:"bytes,10,rep,name=Header" json:"Header,omitempty"`
212 XXX_NoUnkeyedLiteral struct{} `json:"-"`
213 XXX_unrecognized []byte `json:"-"`
214 XXX_sizecache int32 `json:"-"`
215 }
216
217 func (m *MailMessage) Reset() { *m = MailMessage{} }
218 func (m *MailMessage) String() string { return proto.CompactTextString(m) }
219 func (*MailMessage) ProtoMessage() {}
220 func (*MailMessage) Descriptor() ([]byte, []int) {
221 return fileDescriptor_mail_service_78722be3c4c01d17, []int{3}
222 }
223 func (m *MailMessage) XXX_Unmarshal(b []byte) error {
224 return xxx_messageInfo_MailMessage.Unmarshal(m, b)
225 }
226 func (m *MailMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
227 return xxx_messageInfo_MailMessage.Marshal(b, m, deterministic)
228 }
229 func (dst *MailMessage) XXX_Merge(src proto.Message) {
230 xxx_messageInfo_MailMessage.Merge(dst, src)
231 }
232 func (m *MailMessage) XXX_Size() int {
233 return xxx_messageInfo_MailMessage.Size(m)
234 }
235 func (m *MailMessage) XXX_DiscardUnknown() {
236 xxx_messageInfo_MailMessage.DiscardUnknown(m)
237 }
238
239 var xxx_messageInfo_MailMessage proto.InternalMessageInfo
240
241 func (m *MailMessage) GetSender() string {
242 if m != nil && m.Sender != nil {
243 return *m.Sender
244 }
245 return ""
246 }
247
248 func (m *MailMessage) GetReplyTo() string {
249 if m != nil && m.ReplyTo != nil {
250 return *m.ReplyTo
251 }
252 return ""
253 }
254
255 func (m *MailMessage) GetTo() []string {
256 if m != nil {
257 return m.To
258 }
259 return nil
260 }
261
262 func (m *MailMessage) GetCc() []string {
263 if m != nil {
264 return m.Cc
265 }
266 return nil
267 }
268
269 func (m *MailMessage) GetBcc() []string {
270 if m != nil {
271 return m.Bcc
272 }
273 return nil
274 }
275
276 func (m *MailMessage) GetSubject() string {
277 if m != nil && m.Subject != nil {
278 return *m.Subject
279 }
280 return ""
281 }
282
283 func (m *MailMessage) GetTextBody() string {
284 if m != nil && m.TextBody != nil {
285 return *m.TextBody
286 }
287 return ""
288 }
289
290 func (m *MailMessage) GetHtmlBody() string {
291 if m != nil && m.HtmlBody != nil {
292 return *m.HtmlBody
293 }
294 return ""
295 }
296
297 func (m *MailMessage) GetAttachment() []*MailAttachment {
298 if m != nil {
299 return m.Attachment
300 }
301 return nil
302 }
303
304 func (m *MailMessage) GetHeader() []*MailHeader {
305 if m != nil {
306 return m.Header
307 }
308 return nil
309 }
310
311 func init() {
312 proto.RegisterType((*MailServiceError)(nil), "appengine.MailServiceError")
313 proto.RegisterType((*MailAttachment)(nil), "appengine.MailAttachment")
314 proto.RegisterType((*MailHeader)(nil), "appengine.MailHeader")
315 proto.RegisterType((*MailMessage)(nil), "appengine.MailMessage")
316 }
317
318 func init() {
319 proto.RegisterFile("google.golang.org/appengine/v2/internal/mail/mail_service.proto", fileDescriptor_mail_service_78722be3c4c01d17)
320 }
321
322 var fileDescriptor_mail_service_78722be3c4c01d17 = []byte{
323 // 480 bytes of a gzipped FileDescriptorProto
324 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0xcf, 0x6e, 0xd3, 0x40,
325 0x10, 0xc6, 0x89, 0x9d, 0xb8, 0xf5, 0x04, 0x05, 0x6b, 0x81, 0x76, 0xf9, 0x73, 0x88, 0x72, 0xca,
326 0x85, 0x44, 0xe2, 0x80, 0x84, 0xc4, 0xc5, 0xb1, 0x17, 0xc5, 0xa2, 0x71, 0x60, 0xb3, 0x41, 0xa2,
327 0x07, 0xac, 0xc5, 0x19, 0x19, 0x23, 0xc7, 0x1b, 0x39, 0xdb, 0x8a, 0x3e, 0x0d, 0x4f, 0xc0, 0x8d,
328 0x07, 0x44, 0x6b, 0xc7, 0x09, 0xf4, 0x62, 0xcd, 0x6f, 0xbf, 0xf9, 0x66, 0xac, 0x4f, 0x03, 0xef,
329 0x32, 0xa5, 0xb2, 0x02, 0x27, 0x99, 0x2a, 0x64, 0x99, 0x4d, 0x54, 0x95, 0x4d, 0xe5, 0x6e, 0x87,
330 0x65, 0x96, 0x97, 0x38, 0xcd, 0x4b, 0x8d, 0x55, 0x29, 0x8b, 0xe9, 0x56, 0xe6, 0xcd, 0x27, 0xd9,
331 0x63, 0x75, 0x9b, 0xa7, 0x38, 0xd9, 0x55, 0x4a, 0x2b, 0xe2, 0x1e, 0x7b, 0x47, 0x7f, 0x3a, 0xe0,
332 0x2d, 0x64, 0x5e, 0xac, 0x9a, 0x06, 0x56, 0x55, 0xaa, 0x1a, 0xfd, 0xea, 0x80, 0x5b, 0x57, 0x81,
333 0xda, 0x20, 0x71, 0xc0, 0x5a, 0x7e, 0xf0, 0x1e, 0x10, 0x02, 0x83, 0x28, 0x16, 0x8c, 0xc7, 0xfe,
334 0x55, 0xc2, 0x38, 0x5f, 0x72, 0xaf, 0x43, 0x1e, 0x41, 0x7f, 0xe6, 0x87, 0x09, 0x67, 0x9f, 0xd6,
335 0x6c, 0x25, 0x3c, 0x8b, 0x5c, 0xc2, 0xe3, 0x75, 0xec, 0xaf, 0xc5, 0x7c, 0xc9, 0xa3, 0x6b, 0x16,
336 0x26, 0x2b, 0x16, 0x87, 0x8c, 0x7b, 0x36, 0x79, 0x01, 0x97, 0x51, 0xfc, 0xd9, 0xbf, 0x8a, 0xc2,
337 0xc4, 0x17, 0xc2, 0x0f, 0xe6, 0x0b, 0x16, 0x8b, 0x44, 0x7c, 0xf9, 0xc8, 0xbc, 0xae, 0x71, 0xb5,
338 0xe2, 0x9c, 0xf9, 0x21, 0xe3, 0x49, 0xec, 0x2f, 0x98, 0xd7, 0x23, 0x17, 0x40, 0x5a, 0x21, 0x58,
339 0xc6, 0xc2, 0x58, 0xa2, 0xd0, 0x73, 0x46, 0x5f, 0x61, 0x60, 0xfe, 0xda, 0xd7, 0x5a, 0xa6, 0xdf,
340 0xb7, 0x58, 0x6a, 0xf2, 0x1c, 0xce, 0xdf, 0xe7, 0x05, 0xc6, 0x72, 0x8b, 0xb4, 0x33, 0xb4, 0xc6,
341 0x2e, 0x3f, 0x32, 0x21, 0xd0, 0x0d, 0xa5, 0x96, 0xd4, 0x1a, 0x5a, 0xe3, 0x87, 0xbc, 0xae, 0xc9,
342 0x4b, 0x70, 0x03, 0x55, 0x6a, 0x2c, 0x75, 0x14, 0x52, 0x7b, 0xd8, 0x19, 0xbb, 0xfc, 0xf4, 0x30,
343 0x7a, 0x03, 0x60, 0xe6, 0xcf, 0x51, 0x6e, 0xb0, 0x32, 0xfe, 0xf2, 0x34, 0xb7, 0xae, 0xc9, 0x13,
344 0xe8, 0xdd, 0xca, 0xe2, 0x06, 0xeb, 0xa1, 0x2e, 0x6f, 0x60, 0xf4, 0xdb, 0x82, 0xbe, 0x31, 0x2e,
345 0x70, 0xbf, 0x97, 0x19, 0x92, 0x0b, 0x70, 0x56, 0x58, 0x6e, 0xb0, 0x3a, 0x78, 0x0f, 0x44, 0x28,
346 0x9c, 0x71, 0xdc, 0x15, 0x77, 0x42, 0x51, 0xab, 0xde, 0xdd, 0x22, 0x19, 0x80, 0x25, 0x14, 0xb5,
347 0x87, 0xf6, 0xd8, 0xe5, 0x56, 0xc3, 0x41, 0x4a, 0xbb, 0x0d, 0x07, 0x29, 0xf1, 0xc0, 0x9e, 0xa5,
348 0x29, 0xed, 0xd5, 0x0f, 0xa6, 0x34, 0xb3, 0x56, 0x37, 0xdf, 0x7e, 0x60, 0xaa, 0xa9, 0x53, 0x2f,
349 0x69, 0xd1, 0x64, 0x22, 0xf0, 0xa7, 0x9e, 0xa9, 0xcd, 0x1d, 0x3d, 0xab, 0xd7, 0x1c, 0xd9, 0x68,
350 0x73, 0xbd, 0x2d, 0x6a, 0xed, 0xbc, 0xd1, 0x5a, 0x26, 0x6f, 0x01, 0x4e, 0xc9, 0x52, 0x77, 0x68,
351 0x8f, 0xfb, 0xaf, 0x9f, 0x4d, 0x8e, 0x47, 0x33, 0xf9, 0x3f, 0x7a, 0xfe, 0x4f, 0x33, 0x79, 0x05,
352 0x4e, 0x13, 0x1a, 0x85, 0xda, 0xf6, 0xf4, 0x9e, 0xad, 0x11, 0xf9, 0xa1, 0x69, 0xe6, 0x5c, 0x77,
353 0xcd, 0x7d, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x4e, 0xd3, 0x01, 0x27, 0xd0, 0x02, 0x00, 0x00,
354 }
0 syntax = "proto2";
1 option go_package = "mail";
2
3 package appengine;
4
5 message MailServiceError {
6 enum ErrorCode {
7 OK = 0;
8 INTERNAL_ERROR = 1;
9 BAD_REQUEST = 2;
10 UNAUTHORIZED_SENDER = 3;
11 INVALID_ATTACHMENT_TYPE = 4;
12 INVALID_HEADER_NAME = 5;
13 INVALID_CONTENT_ID = 6;
14 }
15 }
16
17 message MailAttachment {
18 required string FileName = 1;
19 required bytes Data = 2;
20 optional string ContentID = 3;
21 }
22
23 message MailHeader {
24 required string name = 1;
25 required string value = 2;
26 }
27
28 message MailMessage {
29 required string Sender = 1;
30 optional string ReplyTo = 2;
31
32 repeated string To = 3;
33 repeated string Cc = 4;
34 repeated string Bcc = 5;
35
36 required string Subject = 6;
37
38 optional string TextBody = 7;
39 optional string HtmlBody = 8;
40
41 repeated MailAttachment Attachment = 9;
42
43 repeated MailHeader Header = 10;
44 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 "io"
8 "log"
9 "net/http"
10 "net/url"
11 "os"
12 "path/filepath"
13 "runtime"
14 )
15
16 // MainPath stores the file path of the main package.
17 var MainPath string
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, Middleware(http.DefaultServeMux)); 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 }
0 package internal
1
2 import (
3 "go/build"
4 "path/filepath"
5 "testing"
6 )
7
8 func TestFindMainPath(t *testing.T) {
9 // Tests won't have package main, instead they have testing.tRunner
10 want := filepath.Join(build.Default.GOROOT, "src", "testing", "testing.go")
11 got := findMainPath()
12 if want != got {
13 t.Errorf("findMainPath: want %s, got %s", want, got)
14 }
15 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/memcache/memcache_service.proto
2
3 package memcache
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type MemcacheServiceError_ErrorCode int32
21
22 const (
23 MemcacheServiceError_OK MemcacheServiceError_ErrorCode = 0
24 MemcacheServiceError_UNSPECIFIED_ERROR MemcacheServiceError_ErrorCode = 1
25 MemcacheServiceError_NAMESPACE_NOT_SET MemcacheServiceError_ErrorCode = 2
26 MemcacheServiceError_PERMISSION_DENIED MemcacheServiceError_ErrorCode = 3
27 MemcacheServiceError_INVALID_VALUE MemcacheServiceError_ErrorCode = 6
28 )
29
30 var MemcacheServiceError_ErrorCode_name = map[int32]string{
31 0: "OK",
32 1: "UNSPECIFIED_ERROR",
33 2: "NAMESPACE_NOT_SET",
34 3: "PERMISSION_DENIED",
35 6: "INVALID_VALUE",
36 }
37 var MemcacheServiceError_ErrorCode_value = map[string]int32{
38 "OK": 0,
39 "UNSPECIFIED_ERROR": 1,
40 "NAMESPACE_NOT_SET": 2,
41 "PERMISSION_DENIED": 3,
42 "INVALID_VALUE": 6,
43 }
44
45 func (x MemcacheServiceError_ErrorCode) Enum() *MemcacheServiceError_ErrorCode {
46 p := new(MemcacheServiceError_ErrorCode)
47 *p = x
48 return p
49 }
50 func (x MemcacheServiceError_ErrorCode) String() string {
51 return proto.EnumName(MemcacheServiceError_ErrorCode_name, int32(x))
52 }
53 func (x *MemcacheServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
54 value, err := proto.UnmarshalJSONEnum(MemcacheServiceError_ErrorCode_value, data, "MemcacheServiceError_ErrorCode")
55 if err != nil {
56 return err
57 }
58 *x = MemcacheServiceError_ErrorCode(value)
59 return nil
60 }
61 func (MemcacheServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
62 return fileDescriptor_memcache_service_e327a14e42649a60, []int{0, 0}
63 }
64
65 type MemcacheSetRequest_SetPolicy int32
66
67 const (
68 MemcacheSetRequest_SET MemcacheSetRequest_SetPolicy = 1
69 MemcacheSetRequest_ADD MemcacheSetRequest_SetPolicy = 2
70 MemcacheSetRequest_REPLACE MemcacheSetRequest_SetPolicy = 3
71 MemcacheSetRequest_CAS MemcacheSetRequest_SetPolicy = 4
72 )
73
74 var MemcacheSetRequest_SetPolicy_name = map[int32]string{
75 1: "SET",
76 2: "ADD",
77 3: "REPLACE",
78 4: "CAS",
79 }
80 var MemcacheSetRequest_SetPolicy_value = map[string]int32{
81 "SET": 1,
82 "ADD": 2,
83 "REPLACE": 3,
84 "CAS": 4,
85 }
86
87 func (x MemcacheSetRequest_SetPolicy) Enum() *MemcacheSetRequest_SetPolicy {
88 p := new(MemcacheSetRequest_SetPolicy)
89 *p = x
90 return p
91 }
92 func (x MemcacheSetRequest_SetPolicy) String() string {
93 return proto.EnumName(MemcacheSetRequest_SetPolicy_name, int32(x))
94 }
95 func (x *MemcacheSetRequest_SetPolicy) UnmarshalJSON(data []byte) error {
96 value, err := proto.UnmarshalJSONEnum(MemcacheSetRequest_SetPolicy_value, data, "MemcacheSetRequest_SetPolicy")
97 if err != nil {
98 return err
99 }
100 *x = MemcacheSetRequest_SetPolicy(value)
101 return nil
102 }
103 func (MemcacheSetRequest_SetPolicy) EnumDescriptor() ([]byte, []int) {
104 return fileDescriptor_memcache_service_e327a14e42649a60, []int{4, 0}
105 }
106
107 type MemcacheSetResponse_SetStatusCode int32
108
109 const (
110 MemcacheSetResponse_STORED MemcacheSetResponse_SetStatusCode = 1
111 MemcacheSetResponse_NOT_STORED MemcacheSetResponse_SetStatusCode = 2
112 MemcacheSetResponse_ERROR MemcacheSetResponse_SetStatusCode = 3
113 MemcacheSetResponse_EXISTS MemcacheSetResponse_SetStatusCode = 4
114 )
115
116 var MemcacheSetResponse_SetStatusCode_name = map[int32]string{
117 1: "STORED",
118 2: "NOT_STORED",
119 3: "ERROR",
120 4: "EXISTS",
121 }
122 var MemcacheSetResponse_SetStatusCode_value = map[string]int32{
123 "STORED": 1,
124 "NOT_STORED": 2,
125 "ERROR": 3,
126 "EXISTS": 4,
127 }
128
129 func (x MemcacheSetResponse_SetStatusCode) Enum() *MemcacheSetResponse_SetStatusCode {
130 p := new(MemcacheSetResponse_SetStatusCode)
131 *p = x
132 return p
133 }
134 func (x MemcacheSetResponse_SetStatusCode) String() string {
135 return proto.EnumName(MemcacheSetResponse_SetStatusCode_name, int32(x))
136 }
137 func (x *MemcacheSetResponse_SetStatusCode) UnmarshalJSON(data []byte) error {
138 value, err := proto.UnmarshalJSONEnum(MemcacheSetResponse_SetStatusCode_value, data, "MemcacheSetResponse_SetStatusCode")
139 if err != nil {
140 return err
141 }
142 *x = MemcacheSetResponse_SetStatusCode(value)
143 return nil
144 }
145 func (MemcacheSetResponse_SetStatusCode) EnumDescriptor() ([]byte, []int) {
146 return fileDescriptor_memcache_service_e327a14e42649a60, []int{5, 0}
147 }
148
149 type MemcacheDeleteResponse_DeleteStatusCode int32
150
151 const (
152 MemcacheDeleteResponse_DELETED MemcacheDeleteResponse_DeleteStatusCode = 1
153 MemcacheDeleteResponse_NOT_FOUND MemcacheDeleteResponse_DeleteStatusCode = 2
154 )
155
156 var MemcacheDeleteResponse_DeleteStatusCode_name = map[int32]string{
157 1: "DELETED",
158 2: "NOT_FOUND",
159 }
160 var MemcacheDeleteResponse_DeleteStatusCode_value = map[string]int32{
161 "DELETED": 1,
162 "NOT_FOUND": 2,
163 }
164
165 func (x MemcacheDeleteResponse_DeleteStatusCode) Enum() *MemcacheDeleteResponse_DeleteStatusCode {
166 p := new(MemcacheDeleteResponse_DeleteStatusCode)
167 *p = x
168 return p
169 }
170 func (x MemcacheDeleteResponse_DeleteStatusCode) String() string {
171 return proto.EnumName(MemcacheDeleteResponse_DeleteStatusCode_name, int32(x))
172 }
173 func (x *MemcacheDeleteResponse_DeleteStatusCode) UnmarshalJSON(data []byte) error {
174 value, err := proto.UnmarshalJSONEnum(MemcacheDeleteResponse_DeleteStatusCode_value, data, "MemcacheDeleteResponse_DeleteStatusCode")
175 if err != nil {
176 return err
177 }
178 *x = MemcacheDeleteResponse_DeleteStatusCode(value)
179 return nil
180 }
181 func (MemcacheDeleteResponse_DeleteStatusCode) EnumDescriptor() ([]byte, []int) {
182 return fileDescriptor_memcache_service_e327a14e42649a60, []int{7, 0}
183 }
184
185 type MemcacheIncrementRequest_Direction int32
186
187 const (
188 MemcacheIncrementRequest_INCREMENT MemcacheIncrementRequest_Direction = 1
189 MemcacheIncrementRequest_DECREMENT MemcacheIncrementRequest_Direction = 2
190 )
191
192 var MemcacheIncrementRequest_Direction_name = map[int32]string{
193 1: "INCREMENT",
194 2: "DECREMENT",
195 }
196 var MemcacheIncrementRequest_Direction_value = map[string]int32{
197 "INCREMENT": 1,
198 "DECREMENT": 2,
199 }
200
201 func (x MemcacheIncrementRequest_Direction) Enum() *MemcacheIncrementRequest_Direction {
202 p := new(MemcacheIncrementRequest_Direction)
203 *p = x
204 return p
205 }
206 func (x MemcacheIncrementRequest_Direction) String() string {
207 return proto.EnumName(MemcacheIncrementRequest_Direction_name, int32(x))
208 }
209 func (x *MemcacheIncrementRequest_Direction) UnmarshalJSON(data []byte) error {
210 value, err := proto.UnmarshalJSONEnum(MemcacheIncrementRequest_Direction_value, data, "MemcacheIncrementRequest_Direction")
211 if err != nil {
212 return err
213 }
214 *x = MemcacheIncrementRequest_Direction(value)
215 return nil
216 }
217 func (MemcacheIncrementRequest_Direction) EnumDescriptor() ([]byte, []int) {
218 return fileDescriptor_memcache_service_e327a14e42649a60, []int{8, 0}
219 }
220
221 type MemcacheIncrementResponse_IncrementStatusCode int32
222
223 const (
224 MemcacheIncrementResponse_OK MemcacheIncrementResponse_IncrementStatusCode = 1
225 MemcacheIncrementResponse_NOT_CHANGED MemcacheIncrementResponse_IncrementStatusCode = 2
226 MemcacheIncrementResponse_ERROR MemcacheIncrementResponse_IncrementStatusCode = 3
227 )
228
229 var MemcacheIncrementResponse_IncrementStatusCode_name = map[int32]string{
230 1: "OK",
231 2: "NOT_CHANGED",
232 3: "ERROR",
233 }
234 var MemcacheIncrementResponse_IncrementStatusCode_value = map[string]int32{
235 "OK": 1,
236 "NOT_CHANGED": 2,
237 "ERROR": 3,
238 }
239
240 func (x MemcacheIncrementResponse_IncrementStatusCode) Enum() *MemcacheIncrementResponse_IncrementStatusCode {
241 p := new(MemcacheIncrementResponse_IncrementStatusCode)
242 *p = x
243 return p
244 }
245 func (x MemcacheIncrementResponse_IncrementStatusCode) String() string {
246 return proto.EnumName(MemcacheIncrementResponse_IncrementStatusCode_name, int32(x))
247 }
248 func (x *MemcacheIncrementResponse_IncrementStatusCode) UnmarshalJSON(data []byte) error {
249 value, err := proto.UnmarshalJSONEnum(MemcacheIncrementResponse_IncrementStatusCode_value, data, "MemcacheIncrementResponse_IncrementStatusCode")
250 if err != nil {
251 return err
252 }
253 *x = MemcacheIncrementResponse_IncrementStatusCode(value)
254 return nil
255 }
256 func (MemcacheIncrementResponse_IncrementStatusCode) EnumDescriptor() ([]byte, []int) {
257 return fileDescriptor_memcache_service_e327a14e42649a60, []int{9, 0}
258 }
259
260 type MemcacheServiceError struct {
261 XXX_NoUnkeyedLiteral struct{} `json:"-"`
262 XXX_unrecognized []byte `json:"-"`
263 XXX_sizecache int32 `json:"-"`
264 }
265
266 func (m *MemcacheServiceError) Reset() { *m = MemcacheServiceError{} }
267 func (m *MemcacheServiceError) String() string { return proto.CompactTextString(m) }
268 func (*MemcacheServiceError) ProtoMessage() {}
269 func (*MemcacheServiceError) Descriptor() ([]byte, []int) {
270 return fileDescriptor_memcache_service_e327a14e42649a60, []int{0}
271 }
272 func (m *MemcacheServiceError) XXX_Unmarshal(b []byte) error {
273 return xxx_messageInfo_MemcacheServiceError.Unmarshal(m, b)
274 }
275 func (m *MemcacheServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
276 return xxx_messageInfo_MemcacheServiceError.Marshal(b, m, deterministic)
277 }
278 func (dst *MemcacheServiceError) XXX_Merge(src proto.Message) {
279 xxx_messageInfo_MemcacheServiceError.Merge(dst, src)
280 }
281 func (m *MemcacheServiceError) XXX_Size() int {
282 return xxx_messageInfo_MemcacheServiceError.Size(m)
283 }
284 func (m *MemcacheServiceError) XXX_DiscardUnknown() {
285 xxx_messageInfo_MemcacheServiceError.DiscardUnknown(m)
286 }
287
288 var xxx_messageInfo_MemcacheServiceError proto.InternalMessageInfo
289
290 type AppOverride struct {
291 AppId *string `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
292 NumMemcachegBackends *int32 `protobuf:"varint,2,opt,name=num_memcacheg_backends,json=numMemcachegBackends" json:"num_memcacheg_backends,omitempty"` // Deprecated: Do not use.
293 IgnoreShardlock *bool `protobuf:"varint,3,opt,name=ignore_shardlock,json=ignoreShardlock" json:"ignore_shardlock,omitempty"` // Deprecated: Do not use.
294 MemcachePoolHint *string `protobuf:"bytes,4,opt,name=memcache_pool_hint,json=memcachePoolHint" json:"memcache_pool_hint,omitempty"` // Deprecated: Do not use.
295 MemcacheShardingStrategy []byte `protobuf:"bytes,5,opt,name=memcache_sharding_strategy,json=memcacheShardingStrategy" json:"memcache_sharding_strategy,omitempty"` // Deprecated: Do not use.
296 XXX_NoUnkeyedLiteral struct{} `json:"-"`
297 XXX_unrecognized []byte `json:"-"`
298 XXX_sizecache int32 `json:"-"`
299 }
300
301 func (m *AppOverride) Reset() { *m = AppOverride{} }
302 func (m *AppOverride) String() string { return proto.CompactTextString(m) }
303 func (*AppOverride) ProtoMessage() {}
304 func (*AppOverride) Descriptor() ([]byte, []int) {
305 return fileDescriptor_memcache_service_e327a14e42649a60, []int{1}
306 }
307 func (m *AppOverride) XXX_Unmarshal(b []byte) error {
308 return xxx_messageInfo_AppOverride.Unmarshal(m, b)
309 }
310 func (m *AppOverride) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
311 return xxx_messageInfo_AppOverride.Marshal(b, m, deterministic)
312 }
313 func (dst *AppOverride) XXX_Merge(src proto.Message) {
314 xxx_messageInfo_AppOverride.Merge(dst, src)
315 }
316 func (m *AppOverride) XXX_Size() int {
317 return xxx_messageInfo_AppOverride.Size(m)
318 }
319 func (m *AppOverride) XXX_DiscardUnknown() {
320 xxx_messageInfo_AppOverride.DiscardUnknown(m)
321 }
322
323 var xxx_messageInfo_AppOverride proto.InternalMessageInfo
324
325 func (m *AppOverride) GetAppId() string {
326 if m != nil && m.AppId != nil {
327 return *m.AppId
328 }
329 return ""
330 }
331
332 // Deprecated: Do not use.
333 func (m *AppOverride) GetNumMemcachegBackends() int32 {
334 if m != nil && m.NumMemcachegBackends != nil {
335 return *m.NumMemcachegBackends
336 }
337 return 0
338 }
339
340 // Deprecated: Do not use.
341 func (m *AppOverride) GetIgnoreShardlock() bool {
342 if m != nil && m.IgnoreShardlock != nil {
343 return *m.IgnoreShardlock
344 }
345 return false
346 }
347
348 // Deprecated: Do not use.
349 func (m *AppOverride) GetMemcachePoolHint() string {
350 if m != nil && m.MemcachePoolHint != nil {
351 return *m.MemcachePoolHint
352 }
353 return ""
354 }
355
356 // Deprecated: Do not use.
357 func (m *AppOverride) GetMemcacheShardingStrategy() []byte {
358 if m != nil {
359 return m.MemcacheShardingStrategy
360 }
361 return nil
362 }
363
364 type MemcacheGetRequest struct {
365 Key [][]byte `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"`
366 NameSpace *string `protobuf:"bytes,2,opt,name=name_space,json=nameSpace,def=" json:"name_space,omitempty"`
367 ForCas *bool `protobuf:"varint,4,opt,name=for_cas,json=forCas" json:"for_cas,omitempty"`
368 Override *AppOverride `protobuf:"bytes,5,opt,name=override" json:"override,omitempty"`
369 XXX_NoUnkeyedLiteral struct{} `json:"-"`
370 XXX_unrecognized []byte `json:"-"`
371 XXX_sizecache int32 `json:"-"`
372 }
373
374 func (m *MemcacheGetRequest) Reset() { *m = MemcacheGetRequest{} }
375 func (m *MemcacheGetRequest) String() string { return proto.CompactTextString(m) }
376 func (*MemcacheGetRequest) ProtoMessage() {}
377 func (*MemcacheGetRequest) Descriptor() ([]byte, []int) {
378 return fileDescriptor_memcache_service_e327a14e42649a60, []int{2}
379 }
380 func (m *MemcacheGetRequest) XXX_Unmarshal(b []byte) error {
381 return xxx_messageInfo_MemcacheGetRequest.Unmarshal(m, b)
382 }
383 func (m *MemcacheGetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
384 return xxx_messageInfo_MemcacheGetRequest.Marshal(b, m, deterministic)
385 }
386 func (dst *MemcacheGetRequest) XXX_Merge(src proto.Message) {
387 xxx_messageInfo_MemcacheGetRequest.Merge(dst, src)
388 }
389 func (m *MemcacheGetRequest) XXX_Size() int {
390 return xxx_messageInfo_MemcacheGetRequest.Size(m)
391 }
392 func (m *MemcacheGetRequest) XXX_DiscardUnknown() {
393 xxx_messageInfo_MemcacheGetRequest.DiscardUnknown(m)
394 }
395
396 var xxx_messageInfo_MemcacheGetRequest proto.InternalMessageInfo
397
398 func (m *MemcacheGetRequest) GetKey() [][]byte {
399 if m != nil {
400 return m.Key
401 }
402 return nil
403 }
404
405 func (m *MemcacheGetRequest) GetNameSpace() string {
406 if m != nil && m.NameSpace != nil {
407 return *m.NameSpace
408 }
409 return ""
410 }
411
412 func (m *MemcacheGetRequest) GetForCas() bool {
413 if m != nil && m.ForCas != nil {
414 return *m.ForCas
415 }
416 return false
417 }
418
419 func (m *MemcacheGetRequest) GetOverride() *AppOverride {
420 if m != nil {
421 return m.Override
422 }
423 return nil
424 }
425
426 type MemcacheGetResponse struct {
427 Item []*MemcacheGetResponse_Item `protobuf:"group,1,rep,name=Item,json=item" json:"item,omitempty"`
428 XXX_NoUnkeyedLiteral struct{} `json:"-"`
429 XXX_unrecognized []byte `json:"-"`
430 XXX_sizecache int32 `json:"-"`
431 }
432
433 func (m *MemcacheGetResponse) Reset() { *m = MemcacheGetResponse{} }
434 func (m *MemcacheGetResponse) String() string { return proto.CompactTextString(m) }
435 func (*MemcacheGetResponse) ProtoMessage() {}
436 func (*MemcacheGetResponse) Descriptor() ([]byte, []int) {
437 return fileDescriptor_memcache_service_e327a14e42649a60, []int{3}
438 }
439 func (m *MemcacheGetResponse) XXX_Unmarshal(b []byte) error {
440 return xxx_messageInfo_MemcacheGetResponse.Unmarshal(m, b)
441 }
442 func (m *MemcacheGetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
443 return xxx_messageInfo_MemcacheGetResponse.Marshal(b, m, deterministic)
444 }
445 func (dst *MemcacheGetResponse) XXX_Merge(src proto.Message) {
446 xxx_messageInfo_MemcacheGetResponse.Merge(dst, src)
447 }
448 func (m *MemcacheGetResponse) XXX_Size() int {
449 return xxx_messageInfo_MemcacheGetResponse.Size(m)
450 }
451 func (m *MemcacheGetResponse) XXX_DiscardUnknown() {
452 xxx_messageInfo_MemcacheGetResponse.DiscardUnknown(m)
453 }
454
455 var xxx_messageInfo_MemcacheGetResponse proto.InternalMessageInfo
456
457 func (m *MemcacheGetResponse) GetItem() []*MemcacheGetResponse_Item {
458 if m != nil {
459 return m.Item
460 }
461 return nil
462 }
463
464 type MemcacheGetResponse_Item struct {
465 Key []byte `protobuf:"bytes,2,req,name=key" json:"key,omitempty"`
466 Value []byte `protobuf:"bytes,3,req,name=value" json:"value,omitempty"`
467 Flags *uint32 `protobuf:"fixed32,4,opt,name=flags" json:"flags,omitempty"`
468 CasId *uint64 `protobuf:"fixed64,5,opt,name=cas_id,json=casId" json:"cas_id,omitempty"`
469 ExpiresInSeconds *int32 `protobuf:"varint,6,opt,name=expires_in_seconds,json=expiresInSeconds" json:"expires_in_seconds,omitempty"`
470 XXX_NoUnkeyedLiteral struct{} `json:"-"`
471 XXX_unrecognized []byte `json:"-"`
472 XXX_sizecache int32 `json:"-"`
473 }
474
475 func (m *MemcacheGetResponse_Item) Reset() { *m = MemcacheGetResponse_Item{} }
476 func (m *MemcacheGetResponse_Item) String() string { return proto.CompactTextString(m) }
477 func (*MemcacheGetResponse_Item) ProtoMessage() {}
478 func (*MemcacheGetResponse_Item) Descriptor() ([]byte, []int) {
479 return fileDescriptor_memcache_service_e327a14e42649a60, []int{3, 0}
480 }
481 func (m *MemcacheGetResponse_Item) XXX_Unmarshal(b []byte) error {
482 return xxx_messageInfo_MemcacheGetResponse_Item.Unmarshal(m, b)
483 }
484 func (m *MemcacheGetResponse_Item) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
485 return xxx_messageInfo_MemcacheGetResponse_Item.Marshal(b, m, deterministic)
486 }
487 func (dst *MemcacheGetResponse_Item) XXX_Merge(src proto.Message) {
488 xxx_messageInfo_MemcacheGetResponse_Item.Merge(dst, src)
489 }
490 func (m *MemcacheGetResponse_Item) XXX_Size() int {
491 return xxx_messageInfo_MemcacheGetResponse_Item.Size(m)
492 }
493 func (m *MemcacheGetResponse_Item) XXX_DiscardUnknown() {
494 xxx_messageInfo_MemcacheGetResponse_Item.DiscardUnknown(m)
495 }
496
497 var xxx_messageInfo_MemcacheGetResponse_Item proto.InternalMessageInfo
498
499 func (m *MemcacheGetResponse_Item) GetKey() []byte {
500 if m != nil {
501 return m.Key
502 }
503 return nil
504 }
505
506 func (m *MemcacheGetResponse_Item) GetValue() []byte {
507 if m != nil {
508 return m.Value
509 }
510 return nil
511 }
512
513 func (m *MemcacheGetResponse_Item) GetFlags() uint32 {
514 if m != nil && m.Flags != nil {
515 return *m.Flags
516 }
517 return 0
518 }
519
520 func (m *MemcacheGetResponse_Item) GetCasId() uint64 {
521 if m != nil && m.CasId != nil {
522 return *m.CasId
523 }
524 return 0
525 }
526
527 func (m *MemcacheGetResponse_Item) GetExpiresInSeconds() int32 {
528 if m != nil && m.ExpiresInSeconds != nil {
529 return *m.ExpiresInSeconds
530 }
531 return 0
532 }
533
534 type MemcacheSetRequest struct {
535 Item []*MemcacheSetRequest_Item `protobuf:"group,1,rep,name=Item,json=item" json:"item,omitempty"`
536 NameSpace *string `protobuf:"bytes,7,opt,name=name_space,json=nameSpace,def=" json:"name_space,omitempty"`
537 Override *AppOverride `protobuf:"bytes,10,opt,name=override" json:"override,omitempty"`
538 XXX_NoUnkeyedLiteral struct{} `json:"-"`
539 XXX_unrecognized []byte `json:"-"`
540 XXX_sizecache int32 `json:"-"`
541 }
542
543 func (m *MemcacheSetRequest) Reset() { *m = MemcacheSetRequest{} }
544 func (m *MemcacheSetRequest) String() string { return proto.CompactTextString(m) }
545 func (*MemcacheSetRequest) ProtoMessage() {}
546 func (*MemcacheSetRequest) Descriptor() ([]byte, []int) {
547 return fileDescriptor_memcache_service_e327a14e42649a60, []int{4}
548 }
549 func (m *MemcacheSetRequest) XXX_Unmarshal(b []byte) error {
550 return xxx_messageInfo_MemcacheSetRequest.Unmarshal(m, b)
551 }
552 func (m *MemcacheSetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
553 return xxx_messageInfo_MemcacheSetRequest.Marshal(b, m, deterministic)
554 }
555 func (dst *MemcacheSetRequest) XXX_Merge(src proto.Message) {
556 xxx_messageInfo_MemcacheSetRequest.Merge(dst, src)
557 }
558 func (m *MemcacheSetRequest) XXX_Size() int {
559 return xxx_messageInfo_MemcacheSetRequest.Size(m)
560 }
561 func (m *MemcacheSetRequest) XXX_DiscardUnknown() {
562 xxx_messageInfo_MemcacheSetRequest.DiscardUnknown(m)
563 }
564
565 var xxx_messageInfo_MemcacheSetRequest proto.InternalMessageInfo
566
567 func (m *MemcacheSetRequest) GetItem() []*MemcacheSetRequest_Item {
568 if m != nil {
569 return m.Item
570 }
571 return nil
572 }
573
574 func (m *MemcacheSetRequest) GetNameSpace() string {
575 if m != nil && m.NameSpace != nil {
576 return *m.NameSpace
577 }
578 return ""
579 }
580
581 func (m *MemcacheSetRequest) GetOverride() *AppOverride {
582 if m != nil {
583 return m.Override
584 }
585 return nil
586 }
587
588 type MemcacheSetRequest_Item struct {
589 Key []byte `protobuf:"bytes,2,req,name=key" json:"key,omitempty"`
590 Value []byte `protobuf:"bytes,3,req,name=value" json:"value,omitempty"`
591 Flags *uint32 `protobuf:"fixed32,4,opt,name=flags" json:"flags,omitempty"`
592 SetPolicy *MemcacheSetRequest_SetPolicy `protobuf:"varint,5,opt,name=set_policy,json=setPolicy,enum=appengine.MemcacheSetRequest_SetPolicy,def=1" json:"set_policy,omitempty"`
593 ExpirationTime *uint32 `protobuf:"fixed32,6,opt,name=expiration_time,json=expirationTime,def=0" json:"expiration_time,omitempty"`
594 CasId *uint64 `protobuf:"fixed64,8,opt,name=cas_id,json=casId" json:"cas_id,omitempty"`
595 ForCas *bool `protobuf:"varint,9,opt,name=for_cas,json=forCas" json:"for_cas,omitempty"`
596 XXX_NoUnkeyedLiteral struct{} `json:"-"`
597 XXX_unrecognized []byte `json:"-"`
598 XXX_sizecache int32 `json:"-"`
599 }
600
601 func (m *MemcacheSetRequest_Item) Reset() { *m = MemcacheSetRequest_Item{} }
602 func (m *MemcacheSetRequest_Item) String() string { return proto.CompactTextString(m) }
603 func (*MemcacheSetRequest_Item) ProtoMessage() {}
604 func (*MemcacheSetRequest_Item) Descriptor() ([]byte, []int) {
605 return fileDescriptor_memcache_service_e327a14e42649a60, []int{4, 0}
606 }
607 func (m *MemcacheSetRequest_Item) XXX_Unmarshal(b []byte) error {
608 return xxx_messageInfo_MemcacheSetRequest_Item.Unmarshal(m, b)
609 }
610 func (m *MemcacheSetRequest_Item) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
611 return xxx_messageInfo_MemcacheSetRequest_Item.Marshal(b, m, deterministic)
612 }
613 func (dst *MemcacheSetRequest_Item) XXX_Merge(src proto.Message) {
614 xxx_messageInfo_MemcacheSetRequest_Item.Merge(dst, src)
615 }
616 func (m *MemcacheSetRequest_Item) XXX_Size() int {
617 return xxx_messageInfo_MemcacheSetRequest_Item.Size(m)
618 }
619 func (m *MemcacheSetRequest_Item) XXX_DiscardUnknown() {
620 xxx_messageInfo_MemcacheSetRequest_Item.DiscardUnknown(m)
621 }
622
623 var xxx_messageInfo_MemcacheSetRequest_Item proto.InternalMessageInfo
624
625 const Default_MemcacheSetRequest_Item_SetPolicy MemcacheSetRequest_SetPolicy = MemcacheSetRequest_SET
626 const Default_MemcacheSetRequest_Item_ExpirationTime uint32 = 0
627
628 func (m *MemcacheSetRequest_Item) GetKey() []byte {
629 if m != nil {
630 return m.Key
631 }
632 return nil
633 }
634
635 func (m *MemcacheSetRequest_Item) GetValue() []byte {
636 if m != nil {
637 return m.Value
638 }
639 return nil
640 }
641
642 func (m *MemcacheSetRequest_Item) GetFlags() uint32 {
643 if m != nil && m.Flags != nil {
644 return *m.Flags
645 }
646 return 0
647 }
648
649 func (m *MemcacheSetRequest_Item) GetSetPolicy() MemcacheSetRequest_SetPolicy {
650 if m != nil && m.SetPolicy != nil {
651 return *m.SetPolicy
652 }
653 return Default_MemcacheSetRequest_Item_SetPolicy
654 }
655
656 func (m *MemcacheSetRequest_Item) GetExpirationTime() uint32 {
657 if m != nil && m.ExpirationTime != nil {
658 return *m.ExpirationTime
659 }
660 return Default_MemcacheSetRequest_Item_ExpirationTime
661 }
662
663 func (m *MemcacheSetRequest_Item) GetCasId() uint64 {
664 if m != nil && m.CasId != nil {
665 return *m.CasId
666 }
667 return 0
668 }
669
670 func (m *MemcacheSetRequest_Item) GetForCas() bool {
671 if m != nil && m.ForCas != nil {
672 return *m.ForCas
673 }
674 return false
675 }
676
677 type MemcacheSetResponse struct {
678 SetStatus []MemcacheSetResponse_SetStatusCode `protobuf:"varint,1,rep,name=set_status,json=setStatus,enum=appengine.MemcacheSetResponse_SetStatusCode" json:"set_status,omitempty"`
679 XXX_NoUnkeyedLiteral struct{} `json:"-"`
680 XXX_unrecognized []byte `json:"-"`
681 XXX_sizecache int32 `json:"-"`
682 }
683
684 func (m *MemcacheSetResponse) Reset() { *m = MemcacheSetResponse{} }
685 func (m *MemcacheSetResponse) String() string { return proto.CompactTextString(m) }
686 func (*MemcacheSetResponse) ProtoMessage() {}
687 func (*MemcacheSetResponse) Descriptor() ([]byte, []int) {
688 return fileDescriptor_memcache_service_e327a14e42649a60, []int{5}
689 }
690 func (m *MemcacheSetResponse) XXX_Unmarshal(b []byte) error {
691 return xxx_messageInfo_MemcacheSetResponse.Unmarshal(m, b)
692 }
693 func (m *MemcacheSetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
694 return xxx_messageInfo_MemcacheSetResponse.Marshal(b, m, deterministic)
695 }
696 func (dst *MemcacheSetResponse) XXX_Merge(src proto.Message) {
697 xxx_messageInfo_MemcacheSetResponse.Merge(dst, src)
698 }
699 func (m *MemcacheSetResponse) XXX_Size() int {
700 return xxx_messageInfo_MemcacheSetResponse.Size(m)
701 }
702 func (m *MemcacheSetResponse) XXX_DiscardUnknown() {
703 xxx_messageInfo_MemcacheSetResponse.DiscardUnknown(m)
704 }
705
706 var xxx_messageInfo_MemcacheSetResponse proto.InternalMessageInfo
707
708 func (m *MemcacheSetResponse) GetSetStatus() []MemcacheSetResponse_SetStatusCode {
709 if m != nil {
710 return m.SetStatus
711 }
712 return nil
713 }
714
715 type MemcacheDeleteRequest struct {
716 Item []*MemcacheDeleteRequest_Item `protobuf:"group,1,rep,name=Item,json=item" json:"item,omitempty"`
717 NameSpace *string `protobuf:"bytes,4,opt,name=name_space,json=nameSpace,def=" json:"name_space,omitempty"`
718 Override *AppOverride `protobuf:"bytes,5,opt,name=override" json:"override,omitempty"`
719 XXX_NoUnkeyedLiteral struct{} `json:"-"`
720 XXX_unrecognized []byte `json:"-"`
721 XXX_sizecache int32 `json:"-"`
722 }
723
724 func (m *MemcacheDeleteRequest) Reset() { *m = MemcacheDeleteRequest{} }
725 func (m *MemcacheDeleteRequest) String() string { return proto.CompactTextString(m) }
726 func (*MemcacheDeleteRequest) ProtoMessage() {}
727 func (*MemcacheDeleteRequest) Descriptor() ([]byte, []int) {
728 return fileDescriptor_memcache_service_e327a14e42649a60, []int{6}
729 }
730 func (m *MemcacheDeleteRequest) XXX_Unmarshal(b []byte) error {
731 return xxx_messageInfo_MemcacheDeleteRequest.Unmarshal(m, b)
732 }
733 func (m *MemcacheDeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
734 return xxx_messageInfo_MemcacheDeleteRequest.Marshal(b, m, deterministic)
735 }
736 func (dst *MemcacheDeleteRequest) XXX_Merge(src proto.Message) {
737 xxx_messageInfo_MemcacheDeleteRequest.Merge(dst, src)
738 }
739 func (m *MemcacheDeleteRequest) XXX_Size() int {
740 return xxx_messageInfo_MemcacheDeleteRequest.Size(m)
741 }
742 func (m *MemcacheDeleteRequest) XXX_DiscardUnknown() {
743 xxx_messageInfo_MemcacheDeleteRequest.DiscardUnknown(m)
744 }
745
746 var xxx_messageInfo_MemcacheDeleteRequest proto.InternalMessageInfo
747
748 func (m *MemcacheDeleteRequest) GetItem() []*MemcacheDeleteRequest_Item {
749 if m != nil {
750 return m.Item
751 }
752 return nil
753 }
754
755 func (m *MemcacheDeleteRequest) GetNameSpace() string {
756 if m != nil && m.NameSpace != nil {
757 return *m.NameSpace
758 }
759 return ""
760 }
761
762 func (m *MemcacheDeleteRequest) GetOverride() *AppOverride {
763 if m != nil {
764 return m.Override
765 }
766 return nil
767 }
768
769 type MemcacheDeleteRequest_Item struct {
770 Key []byte `protobuf:"bytes,2,req,name=key" json:"key,omitempty"`
771 DeleteTime *uint32 `protobuf:"fixed32,3,opt,name=delete_time,json=deleteTime,def=0" json:"delete_time,omitempty"`
772 XXX_NoUnkeyedLiteral struct{} `json:"-"`
773 XXX_unrecognized []byte `json:"-"`
774 XXX_sizecache int32 `json:"-"`
775 }
776
777 func (m *MemcacheDeleteRequest_Item) Reset() { *m = MemcacheDeleteRequest_Item{} }
778 func (m *MemcacheDeleteRequest_Item) String() string { return proto.CompactTextString(m) }
779 func (*MemcacheDeleteRequest_Item) ProtoMessage() {}
780 func (*MemcacheDeleteRequest_Item) Descriptor() ([]byte, []int) {
781 return fileDescriptor_memcache_service_e327a14e42649a60, []int{6, 0}
782 }
783 func (m *MemcacheDeleteRequest_Item) XXX_Unmarshal(b []byte) error {
784 return xxx_messageInfo_MemcacheDeleteRequest_Item.Unmarshal(m, b)
785 }
786 func (m *MemcacheDeleteRequest_Item) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
787 return xxx_messageInfo_MemcacheDeleteRequest_Item.Marshal(b, m, deterministic)
788 }
789 func (dst *MemcacheDeleteRequest_Item) XXX_Merge(src proto.Message) {
790 xxx_messageInfo_MemcacheDeleteRequest_Item.Merge(dst, src)
791 }
792 func (m *MemcacheDeleteRequest_Item) XXX_Size() int {
793 return xxx_messageInfo_MemcacheDeleteRequest_Item.Size(m)
794 }
795 func (m *MemcacheDeleteRequest_Item) XXX_DiscardUnknown() {
796 xxx_messageInfo_MemcacheDeleteRequest_Item.DiscardUnknown(m)
797 }
798
799 var xxx_messageInfo_MemcacheDeleteRequest_Item proto.InternalMessageInfo
800
801 const Default_MemcacheDeleteRequest_Item_DeleteTime uint32 = 0
802
803 func (m *MemcacheDeleteRequest_Item) GetKey() []byte {
804 if m != nil {
805 return m.Key
806 }
807 return nil
808 }
809
810 func (m *MemcacheDeleteRequest_Item) GetDeleteTime() uint32 {
811 if m != nil && m.DeleteTime != nil {
812 return *m.DeleteTime
813 }
814 return Default_MemcacheDeleteRequest_Item_DeleteTime
815 }
816
817 type MemcacheDeleteResponse struct {
818 DeleteStatus []MemcacheDeleteResponse_DeleteStatusCode `protobuf:"varint,1,rep,name=delete_status,json=deleteStatus,enum=appengine.MemcacheDeleteResponse_DeleteStatusCode" json:"delete_status,omitempty"`
819 XXX_NoUnkeyedLiteral struct{} `json:"-"`
820 XXX_unrecognized []byte `json:"-"`
821 XXX_sizecache int32 `json:"-"`
822 }
823
824 func (m *MemcacheDeleteResponse) Reset() { *m = MemcacheDeleteResponse{} }
825 func (m *MemcacheDeleteResponse) String() string { return proto.CompactTextString(m) }
826 func (*MemcacheDeleteResponse) ProtoMessage() {}
827 func (*MemcacheDeleteResponse) Descriptor() ([]byte, []int) {
828 return fileDescriptor_memcache_service_e327a14e42649a60, []int{7}
829 }
830 func (m *MemcacheDeleteResponse) XXX_Unmarshal(b []byte) error {
831 return xxx_messageInfo_MemcacheDeleteResponse.Unmarshal(m, b)
832 }
833 func (m *MemcacheDeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
834 return xxx_messageInfo_MemcacheDeleteResponse.Marshal(b, m, deterministic)
835 }
836 func (dst *MemcacheDeleteResponse) XXX_Merge(src proto.Message) {
837 xxx_messageInfo_MemcacheDeleteResponse.Merge(dst, src)
838 }
839 func (m *MemcacheDeleteResponse) XXX_Size() int {
840 return xxx_messageInfo_MemcacheDeleteResponse.Size(m)
841 }
842 func (m *MemcacheDeleteResponse) XXX_DiscardUnknown() {
843 xxx_messageInfo_MemcacheDeleteResponse.DiscardUnknown(m)
844 }
845
846 var xxx_messageInfo_MemcacheDeleteResponse proto.InternalMessageInfo
847
848 func (m *MemcacheDeleteResponse) GetDeleteStatus() []MemcacheDeleteResponse_DeleteStatusCode {
849 if m != nil {
850 return m.DeleteStatus
851 }
852 return nil
853 }
854
855 type MemcacheIncrementRequest struct {
856 Key []byte `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
857 NameSpace *string `protobuf:"bytes,4,opt,name=name_space,json=nameSpace,def=" json:"name_space,omitempty"`
858 Delta *uint64 `protobuf:"varint,2,opt,name=delta,def=1" json:"delta,omitempty"`
859 Direction *MemcacheIncrementRequest_Direction `protobuf:"varint,3,opt,name=direction,enum=appengine.MemcacheIncrementRequest_Direction,def=1" json:"direction,omitempty"`
860 InitialValue *uint64 `protobuf:"varint,5,opt,name=initial_value,json=initialValue" json:"initial_value,omitempty"`
861 InitialFlags *uint32 `protobuf:"fixed32,6,opt,name=initial_flags,json=initialFlags" json:"initial_flags,omitempty"`
862 Override *AppOverride `protobuf:"bytes,7,opt,name=override" json:"override,omitempty"`
863 XXX_NoUnkeyedLiteral struct{} `json:"-"`
864 XXX_unrecognized []byte `json:"-"`
865 XXX_sizecache int32 `json:"-"`
866 }
867
868 func (m *MemcacheIncrementRequest) Reset() { *m = MemcacheIncrementRequest{} }
869 func (m *MemcacheIncrementRequest) String() string { return proto.CompactTextString(m) }
870 func (*MemcacheIncrementRequest) ProtoMessage() {}
871 func (*MemcacheIncrementRequest) Descriptor() ([]byte, []int) {
872 return fileDescriptor_memcache_service_e327a14e42649a60, []int{8}
873 }
874 func (m *MemcacheIncrementRequest) XXX_Unmarshal(b []byte) error {
875 return xxx_messageInfo_MemcacheIncrementRequest.Unmarshal(m, b)
876 }
877 func (m *MemcacheIncrementRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
878 return xxx_messageInfo_MemcacheIncrementRequest.Marshal(b, m, deterministic)
879 }
880 func (dst *MemcacheIncrementRequest) XXX_Merge(src proto.Message) {
881 xxx_messageInfo_MemcacheIncrementRequest.Merge(dst, src)
882 }
883 func (m *MemcacheIncrementRequest) XXX_Size() int {
884 return xxx_messageInfo_MemcacheIncrementRequest.Size(m)
885 }
886 func (m *MemcacheIncrementRequest) XXX_DiscardUnknown() {
887 xxx_messageInfo_MemcacheIncrementRequest.DiscardUnknown(m)
888 }
889
890 var xxx_messageInfo_MemcacheIncrementRequest proto.InternalMessageInfo
891
892 const Default_MemcacheIncrementRequest_Delta uint64 = 1
893 const Default_MemcacheIncrementRequest_Direction MemcacheIncrementRequest_Direction = MemcacheIncrementRequest_INCREMENT
894
895 func (m *MemcacheIncrementRequest) GetKey() []byte {
896 if m != nil {
897 return m.Key
898 }
899 return nil
900 }
901
902 func (m *MemcacheIncrementRequest) GetNameSpace() string {
903 if m != nil && m.NameSpace != nil {
904 return *m.NameSpace
905 }
906 return ""
907 }
908
909 func (m *MemcacheIncrementRequest) GetDelta() uint64 {
910 if m != nil && m.Delta != nil {
911 return *m.Delta
912 }
913 return Default_MemcacheIncrementRequest_Delta
914 }
915
916 func (m *MemcacheIncrementRequest) GetDirection() MemcacheIncrementRequest_Direction {
917 if m != nil && m.Direction != nil {
918 return *m.Direction
919 }
920 return Default_MemcacheIncrementRequest_Direction
921 }
922
923 func (m *MemcacheIncrementRequest) GetInitialValue() uint64 {
924 if m != nil && m.InitialValue != nil {
925 return *m.InitialValue
926 }
927 return 0
928 }
929
930 func (m *MemcacheIncrementRequest) GetInitialFlags() uint32 {
931 if m != nil && m.InitialFlags != nil {
932 return *m.InitialFlags
933 }
934 return 0
935 }
936
937 func (m *MemcacheIncrementRequest) GetOverride() *AppOverride {
938 if m != nil {
939 return m.Override
940 }
941 return nil
942 }
943
944 type MemcacheIncrementResponse struct {
945 NewValue *uint64 `protobuf:"varint,1,opt,name=new_value,json=newValue" json:"new_value,omitempty"`
946 IncrementStatus *MemcacheIncrementResponse_IncrementStatusCode `protobuf:"varint,2,opt,name=increment_status,json=incrementStatus,enum=appengine.MemcacheIncrementResponse_IncrementStatusCode" json:"increment_status,omitempty"`
947 XXX_NoUnkeyedLiteral struct{} `json:"-"`
948 XXX_unrecognized []byte `json:"-"`
949 XXX_sizecache int32 `json:"-"`
950 }
951
952 func (m *MemcacheIncrementResponse) Reset() { *m = MemcacheIncrementResponse{} }
953 func (m *MemcacheIncrementResponse) String() string { return proto.CompactTextString(m) }
954 func (*MemcacheIncrementResponse) ProtoMessage() {}
955 func (*MemcacheIncrementResponse) Descriptor() ([]byte, []int) {
956 return fileDescriptor_memcache_service_e327a14e42649a60, []int{9}
957 }
958 func (m *MemcacheIncrementResponse) XXX_Unmarshal(b []byte) error {
959 return xxx_messageInfo_MemcacheIncrementResponse.Unmarshal(m, b)
960 }
961 func (m *MemcacheIncrementResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
962 return xxx_messageInfo_MemcacheIncrementResponse.Marshal(b, m, deterministic)
963 }
964 func (dst *MemcacheIncrementResponse) XXX_Merge(src proto.Message) {
965 xxx_messageInfo_MemcacheIncrementResponse.Merge(dst, src)
966 }
967 func (m *MemcacheIncrementResponse) XXX_Size() int {
968 return xxx_messageInfo_MemcacheIncrementResponse.Size(m)
969 }
970 func (m *MemcacheIncrementResponse) XXX_DiscardUnknown() {
971 xxx_messageInfo_MemcacheIncrementResponse.DiscardUnknown(m)
972 }
973
974 var xxx_messageInfo_MemcacheIncrementResponse proto.InternalMessageInfo
975
976 func (m *MemcacheIncrementResponse) GetNewValue() uint64 {
977 if m != nil && m.NewValue != nil {
978 return *m.NewValue
979 }
980 return 0
981 }
982
983 func (m *MemcacheIncrementResponse) GetIncrementStatus() MemcacheIncrementResponse_IncrementStatusCode {
984 if m != nil && m.IncrementStatus != nil {
985 return *m.IncrementStatus
986 }
987 return MemcacheIncrementResponse_OK
988 }
989
990 type MemcacheBatchIncrementRequest struct {
991 NameSpace *string `protobuf:"bytes,1,opt,name=name_space,json=nameSpace,def=" json:"name_space,omitempty"`
992 Item []*MemcacheIncrementRequest `protobuf:"bytes,2,rep,name=item" json:"item,omitempty"`
993 Override *AppOverride `protobuf:"bytes,3,opt,name=override" json:"override,omitempty"`
994 XXX_NoUnkeyedLiteral struct{} `json:"-"`
995 XXX_unrecognized []byte `json:"-"`
996 XXX_sizecache int32 `json:"-"`
997 }
998
999 func (m *MemcacheBatchIncrementRequest) Reset() { *m = MemcacheBatchIncrementRequest{} }
1000 func (m *MemcacheBatchIncrementRequest) String() string { return proto.CompactTextString(m) }
1001 func (*MemcacheBatchIncrementRequest) ProtoMessage() {}
1002 func (*MemcacheBatchIncrementRequest) Descriptor() ([]byte, []int) {
1003 return fileDescriptor_memcache_service_e327a14e42649a60, []int{10}
1004 }
1005 func (m *MemcacheBatchIncrementRequest) XXX_Unmarshal(b []byte) error {
1006 return xxx_messageInfo_MemcacheBatchIncrementRequest.Unmarshal(m, b)
1007 }
1008 func (m *MemcacheBatchIncrementRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1009 return xxx_messageInfo_MemcacheBatchIncrementRequest.Marshal(b, m, deterministic)
1010 }
1011 func (dst *MemcacheBatchIncrementRequest) XXX_Merge(src proto.Message) {
1012 xxx_messageInfo_MemcacheBatchIncrementRequest.Merge(dst, src)
1013 }
1014 func (m *MemcacheBatchIncrementRequest) XXX_Size() int {
1015 return xxx_messageInfo_MemcacheBatchIncrementRequest.Size(m)
1016 }
1017 func (m *MemcacheBatchIncrementRequest) XXX_DiscardUnknown() {
1018 xxx_messageInfo_MemcacheBatchIncrementRequest.DiscardUnknown(m)
1019 }
1020
1021 var xxx_messageInfo_MemcacheBatchIncrementRequest proto.InternalMessageInfo
1022
1023 func (m *MemcacheBatchIncrementRequest) GetNameSpace() string {
1024 if m != nil && m.NameSpace != nil {
1025 return *m.NameSpace
1026 }
1027 return ""
1028 }
1029
1030 func (m *MemcacheBatchIncrementRequest) GetItem() []*MemcacheIncrementRequest {
1031 if m != nil {
1032 return m.Item
1033 }
1034 return nil
1035 }
1036
1037 func (m *MemcacheBatchIncrementRequest) GetOverride() *AppOverride {
1038 if m != nil {
1039 return m.Override
1040 }
1041 return nil
1042 }
1043
1044 type MemcacheBatchIncrementResponse struct {
1045 Item []*MemcacheIncrementResponse `protobuf:"bytes,1,rep,name=item" json:"item,omitempty"`
1046 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1047 XXX_unrecognized []byte `json:"-"`
1048 XXX_sizecache int32 `json:"-"`
1049 }
1050
1051 func (m *MemcacheBatchIncrementResponse) Reset() { *m = MemcacheBatchIncrementResponse{} }
1052 func (m *MemcacheBatchIncrementResponse) String() string { return proto.CompactTextString(m) }
1053 func (*MemcacheBatchIncrementResponse) ProtoMessage() {}
1054 func (*MemcacheBatchIncrementResponse) Descriptor() ([]byte, []int) {
1055 return fileDescriptor_memcache_service_e327a14e42649a60, []int{11}
1056 }
1057 func (m *MemcacheBatchIncrementResponse) XXX_Unmarshal(b []byte) error {
1058 return xxx_messageInfo_MemcacheBatchIncrementResponse.Unmarshal(m, b)
1059 }
1060 func (m *MemcacheBatchIncrementResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1061 return xxx_messageInfo_MemcacheBatchIncrementResponse.Marshal(b, m, deterministic)
1062 }
1063 func (dst *MemcacheBatchIncrementResponse) XXX_Merge(src proto.Message) {
1064 xxx_messageInfo_MemcacheBatchIncrementResponse.Merge(dst, src)
1065 }
1066 func (m *MemcacheBatchIncrementResponse) XXX_Size() int {
1067 return xxx_messageInfo_MemcacheBatchIncrementResponse.Size(m)
1068 }
1069 func (m *MemcacheBatchIncrementResponse) XXX_DiscardUnknown() {
1070 xxx_messageInfo_MemcacheBatchIncrementResponse.DiscardUnknown(m)
1071 }
1072
1073 var xxx_messageInfo_MemcacheBatchIncrementResponse proto.InternalMessageInfo
1074
1075 func (m *MemcacheBatchIncrementResponse) GetItem() []*MemcacheIncrementResponse {
1076 if m != nil {
1077 return m.Item
1078 }
1079 return nil
1080 }
1081
1082 type MemcacheFlushRequest struct {
1083 Override *AppOverride `protobuf:"bytes,1,opt,name=override" json:"override,omitempty"`
1084 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1085 XXX_unrecognized []byte `json:"-"`
1086 XXX_sizecache int32 `json:"-"`
1087 }
1088
1089 func (m *MemcacheFlushRequest) Reset() { *m = MemcacheFlushRequest{} }
1090 func (m *MemcacheFlushRequest) String() string { return proto.CompactTextString(m) }
1091 func (*MemcacheFlushRequest) ProtoMessage() {}
1092 func (*MemcacheFlushRequest) Descriptor() ([]byte, []int) {
1093 return fileDescriptor_memcache_service_e327a14e42649a60, []int{12}
1094 }
1095 func (m *MemcacheFlushRequest) XXX_Unmarshal(b []byte) error {
1096 return xxx_messageInfo_MemcacheFlushRequest.Unmarshal(m, b)
1097 }
1098 func (m *MemcacheFlushRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1099 return xxx_messageInfo_MemcacheFlushRequest.Marshal(b, m, deterministic)
1100 }
1101 func (dst *MemcacheFlushRequest) XXX_Merge(src proto.Message) {
1102 xxx_messageInfo_MemcacheFlushRequest.Merge(dst, src)
1103 }
1104 func (m *MemcacheFlushRequest) XXX_Size() int {
1105 return xxx_messageInfo_MemcacheFlushRequest.Size(m)
1106 }
1107 func (m *MemcacheFlushRequest) XXX_DiscardUnknown() {
1108 xxx_messageInfo_MemcacheFlushRequest.DiscardUnknown(m)
1109 }
1110
1111 var xxx_messageInfo_MemcacheFlushRequest proto.InternalMessageInfo
1112
1113 func (m *MemcacheFlushRequest) GetOverride() *AppOverride {
1114 if m != nil {
1115 return m.Override
1116 }
1117 return nil
1118 }
1119
1120 type MemcacheFlushResponse struct {
1121 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1122 XXX_unrecognized []byte `json:"-"`
1123 XXX_sizecache int32 `json:"-"`
1124 }
1125
1126 func (m *MemcacheFlushResponse) Reset() { *m = MemcacheFlushResponse{} }
1127 func (m *MemcacheFlushResponse) String() string { return proto.CompactTextString(m) }
1128 func (*MemcacheFlushResponse) ProtoMessage() {}
1129 func (*MemcacheFlushResponse) Descriptor() ([]byte, []int) {
1130 return fileDescriptor_memcache_service_e327a14e42649a60, []int{13}
1131 }
1132 func (m *MemcacheFlushResponse) XXX_Unmarshal(b []byte) error {
1133 return xxx_messageInfo_MemcacheFlushResponse.Unmarshal(m, b)
1134 }
1135 func (m *MemcacheFlushResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1136 return xxx_messageInfo_MemcacheFlushResponse.Marshal(b, m, deterministic)
1137 }
1138 func (dst *MemcacheFlushResponse) XXX_Merge(src proto.Message) {
1139 xxx_messageInfo_MemcacheFlushResponse.Merge(dst, src)
1140 }
1141 func (m *MemcacheFlushResponse) XXX_Size() int {
1142 return xxx_messageInfo_MemcacheFlushResponse.Size(m)
1143 }
1144 func (m *MemcacheFlushResponse) XXX_DiscardUnknown() {
1145 xxx_messageInfo_MemcacheFlushResponse.DiscardUnknown(m)
1146 }
1147
1148 var xxx_messageInfo_MemcacheFlushResponse proto.InternalMessageInfo
1149
1150 type MemcacheStatsRequest struct {
1151 Override *AppOverride `protobuf:"bytes,1,opt,name=override" json:"override,omitempty"`
1152 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1153 XXX_unrecognized []byte `json:"-"`
1154 XXX_sizecache int32 `json:"-"`
1155 }
1156
1157 func (m *MemcacheStatsRequest) Reset() { *m = MemcacheStatsRequest{} }
1158 func (m *MemcacheStatsRequest) String() string { return proto.CompactTextString(m) }
1159 func (*MemcacheStatsRequest) ProtoMessage() {}
1160 func (*MemcacheStatsRequest) Descriptor() ([]byte, []int) {
1161 return fileDescriptor_memcache_service_e327a14e42649a60, []int{14}
1162 }
1163 func (m *MemcacheStatsRequest) XXX_Unmarshal(b []byte) error {
1164 return xxx_messageInfo_MemcacheStatsRequest.Unmarshal(m, b)
1165 }
1166 func (m *MemcacheStatsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1167 return xxx_messageInfo_MemcacheStatsRequest.Marshal(b, m, deterministic)
1168 }
1169 func (dst *MemcacheStatsRequest) XXX_Merge(src proto.Message) {
1170 xxx_messageInfo_MemcacheStatsRequest.Merge(dst, src)
1171 }
1172 func (m *MemcacheStatsRequest) XXX_Size() int {
1173 return xxx_messageInfo_MemcacheStatsRequest.Size(m)
1174 }
1175 func (m *MemcacheStatsRequest) XXX_DiscardUnknown() {
1176 xxx_messageInfo_MemcacheStatsRequest.DiscardUnknown(m)
1177 }
1178
1179 var xxx_messageInfo_MemcacheStatsRequest proto.InternalMessageInfo
1180
1181 func (m *MemcacheStatsRequest) GetOverride() *AppOverride {
1182 if m != nil {
1183 return m.Override
1184 }
1185 return nil
1186 }
1187
1188 type MergedNamespaceStats struct {
1189 Hits *uint64 `protobuf:"varint,1,req,name=hits" json:"hits,omitempty"`
1190 Misses *uint64 `protobuf:"varint,2,req,name=misses" json:"misses,omitempty"`
1191 ByteHits *uint64 `protobuf:"varint,3,req,name=byte_hits,json=byteHits" json:"byte_hits,omitempty"`
1192 Items *uint64 `protobuf:"varint,4,req,name=items" json:"items,omitempty"`
1193 Bytes *uint64 `protobuf:"varint,5,req,name=bytes" json:"bytes,omitempty"`
1194 OldestItemAge *uint32 `protobuf:"fixed32,6,req,name=oldest_item_age,json=oldestItemAge" json:"oldest_item_age,omitempty"`
1195 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1196 XXX_unrecognized []byte `json:"-"`
1197 XXX_sizecache int32 `json:"-"`
1198 }
1199
1200 func (m *MergedNamespaceStats) Reset() { *m = MergedNamespaceStats{} }
1201 func (m *MergedNamespaceStats) String() string { return proto.CompactTextString(m) }
1202 func (*MergedNamespaceStats) ProtoMessage() {}
1203 func (*MergedNamespaceStats) Descriptor() ([]byte, []int) {
1204 return fileDescriptor_memcache_service_e327a14e42649a60, []int{15}
1205 }
1206 func (m *MergedNamespaceStats) XXX_Unmarshal(b []byte) error {
1207 return xxx_messageInfo_MergedNamespaceStats.Unmarshal(m, b)
1208 }
1209 func (m *MergedNamespaceStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1210 return xxx_messageInfo_MergedNamespaceStats.Marshal(b, m, deterministic)
1211 }
1212 func (dst *MergedNamespaceStats) XXX_Merge(src proto.Message) {
1213 xxx_messageInfo_MergedNamespaceStats.Merge(dst, src)
1214 }
1215 func (m *MergedNamespaceStats) XXX_Size() int {
1216 return xxx_messageInfo_MergedNamespaceStats.Size(m)
1217 }
1218 func (m *MergedNamespaceStats) XXX_DiscardUnknown() {
1219 xxx_messageInfo_MergedNamespaceStats.DiscardUnknown(m)
1220 }
1221
1222 var xxx_messageInfo_MergedNamespaceStats proto.InternalMessageInfo
1223
1224 func (m *MergedNamespaceStats) GetHits() uint64 {
1225 if m != nil && m.Hits != nil {
1226 return *m.Hits
1227 }
1228 return 0
1229 }
1230
1231 func (m *MergedNamespaceStats) GetMisses() uint64 {
1232 if m != nil && m.Misses != nil {
1233 return *m.Misses
1234 }
1235 return 0
1236 }
1237
1238 func (m *MergedNamespaceStats) GetByteHits() uint64 {
1239 if m != nil && m.ByteHits != nil {
1240 return *m.ByteHits
1241 }
1242 return 0
1243 }
1244
1245 func (m *MergedNamespaceStats) GetItems() uint64 {
1246 if m != nil && m.Items != nil {
1247 return *m.Items
1248 }
1249 return 0
1250 }
1251
1252 func (m *MergedNamespaceStats) GetBytes() uint64 {
1253 if m != nil && m.Bytes != nil {
1254 return *m.Bytes
1255 }
1256 return 0
1257 }
1258
1259 func (m *MergedNamespaceStats) GetOldestItemAge() uint32 {
1260 if m != nil && m.OldestItemAge != nil {
1261 return *m.OldestItemAge
1262 }
1263 return 0
1264 }
1265
1266 type MemcacheStatsResponse struct {
1267 Stats *MergedNamespaceStats `protobuf:"bytes,1,opt,name=stats" json:"stats,omitempty"`
1268 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1269 XXX_unrecognized []byte `json:"-"`
1270 XXX_sizecache int32 `json:"-"`
1271 }
1272
1273 func (m *MemcacheStatsResponse) Reset() { *m = MemcacheStatsResponse{} }
1274 func (m *MemcacheStatsResponse) String() string { return proto.CompactTextString(m) }
1275 func (*MemcacheStatsResponse) ProtoMessage() {}
1276 func (*MemcacheStatsResponse) Descriptor() ([]byte, []int) {
1277 return fileDescriptor_memcache_service_e327a14e42649a60, []int{16}
1278 }
1279 func (m *MemcacheStatsResponse) XXX_Unmarshal(b []byte) error {
1280 return xxx_messageInfo_MemcacheStatsResponse.Unmarshal(m, b)
1281 }
1282 func (m *MemcacheStatsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1283 return xxx_messageInfo_MemcacheStatsResponse.Marshal(b, m, deterministic)
1284 }
1285 func (dst *MemcacheStatsResponse) XXX_Merge(src proto.Message) {
1286 xxx_messageInfo_MemcacheStatsResponse.Merge(dst, src)
1287 }
1288 func (m *MemcacheStatsResponse) XXX_Size() int {
1289 return xxx_messageInfo_MemcacheStatsResponse.Size(m)
1290 }
1291 func (m *MemcacheStatsResponse) XXX_DiscardUnknown() {
1292 xxx_messageInfo_MemcacheStatsResponse.DiscardUnknown(m)
1293 }
1294
1295 var xxx_messageInfo_MemcacheStatsResponse proto.InternalMessageInfo
1296
1297 func (m *MemcacheStatsResponse) GetStats() *MergedNamespaceStats {
1298 if m != nil {
1299 return m.Stats
1300 }
1301 return nil
1302 }
1303
1304 type MemcacheGrabTailRequest struct {
1305 ItemCount *int32 `protobuf:"varint,1,req,name=item_count,json=itemCount" json:"item_count,omitempty"`
1306 NameSpace *string `protobuf:"bytes,2,opt,name=name_space,json=nameSpace,def=" json:"name_space,omitempty"`
1307 Override *AppOverride `protobuf:"bytes,3,opt,name=override" json:"override,omitempty"`
1308 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1309 XXX_unrecognized []byte `json:"-"`
1310 XXX_sizecache int32 `json:"-"`
1311 }
1312
1313 func (m *MemcacheGrabTailRequest) Reset() { *m = MemcacheGrabTailRequest{} }
1314 func (m *MemcacheGrabTailRequest) String() string { return proto.CompactTextString(m) }
1315 func (*MemcacheGrabTailRequest) ProtoMessage() {}
1316 func (*MemcacheGrabTailRequest) Descriptor() ([]byte, []int) {
1317 return fileDescriptor_memcache_service_e327a14e42649a60, []int{17}
1318 }
1319 func (m *MemcacheGrabTailRequest) XXX_Unmarshal(b []byte) error {
1320 return xxx_messageInfo_MemcacheGrabTailRequest.Unmarshal(m, b)
1321 }
1322 func (m *MemcacheGrabTailRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1323 return xxx_messageInfo_MemcacheGrabTailRequest.Marshal(b, m, deterministic)
1324 }
1325 func (dst *MemcacheGrabTailRequest) XXX_Merge(src proto.Message) {
1326 xxx_messageInfo_MemcacheGrabTailRequest.Merge(dst, src)
1327 }
1328 func (m *MemcacheGrabTailRequest) XXX_Size() int {
1329 return xxx_messageInfo_MemcacheGrabTailRequest.Size(m)
1330 }
1331 func (m *MemcacheGrabTailRequest) XXX_DiscardUnknown() {
1332 xxx_messageInfo_MemcacheGrabTailRequest.DiscardUnknown(m)
1333 }
1334
1335 var xxx_messageInfo_MemcacheGrabTailRequest proto.InternalMessageInfo
1336
1337 func (m *MemcacheGrabTailRequest) GetItemCount() int32 {
1338 if m != nil && m.ItemCount != nil {
1339 return *m.ItemCount
1340 }
1341 return 0
1342 }
1343
1344 func (m *MemcacheGrabTailRequest) GetNameSpace() string {
1345 if m != nil && m.NameSpace != nil {
1346 return *m.NameSpace
1347 }
1348 return ""
1349 }
1350
1351 func (m *MemcacheGrabTailRequest) GetOverride() *AppOverride {
1352 if m != nil {
1353 return m.Override
1354 }
1355 return nil
1356 }
1357
1358 type MemcacheGrabTailResponse struct {
1359 Item []*MemcacheGrabTailResponse_Item `protobuf:"group,1,rep,name=Item,json=item" json:"item,omitempty"`
1360 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1361 XXX_unrecognized []byte `json:"-"`
1362 XXX_sizecache int32 `json:"-"`
1363 }
1364
1365 func (m *MemcacheGrabTailResponse) Reset() { *m = MemcacheGrabTailResponse{} }
1366 func (m *MemcacheGrabTailResponse) String() string { return proto.CompactTextString(m) }
1367 func (*MemcacheGrabTailResponse) ProtoMessage() {}
1368 func (*MemcacheGrabTailResponse) Descriptor() ([]byte, []int) {
1369 return fileDescriptor_memcache_service_e327a14e42649a60, []int{18}
1370 }
1371 func (m *MemcacheGrabTailResponse) XXX_Unmarshal(b []byte) error {
1372 return xxx_messageInfo_MemcacheGrabTailResponse.Unmarshal(m, b)
1373 }
1374 func (m *MemcacheGrabTailResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1375 return xxx_messageInfo_MemcacheGrabTailResponse.Marshal(b, m, deterministic)
1376 }
1377 func (dst *MemcacheGrabTailResponse) XXX_Merge(src proto.Message) {
1378 xxx_messageInfo_MemcacheGrabTailResponse.Merge(dst, src)
1379 }
1380 func (m *MemcacheGrabTailResponse) XXX_Size() int {
1381 return xxx_messageInfo_MemcacheGrabTailResponse.Size(m)
1382 }
1383 func (m *MemcacheGrabTailResponse) XXX_DiscardUnknown() {
1384 xxx_messageInfo_MemcacheGrabTailResponse.DiscardUnknown(m)
1385 }
1386
1387 var xxx_messageInfo_MemcacheGrabTailResponse proto.InternalMessageInfo
1388
1389 func (m *MemcacheGrabTailResponse) GetItem() []*MemcacheGrabTailResponse_Item {
1390 if m != nil {
1391 return m.Item
1392 }
1393 return nil
1394 }
1395
1396 type MemcacheGrabTailResponse_Item struct {
1397 Value []byte `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
1398 Flags *uint32 `protobuf:"fixed32,3,opt,name=flags" json:"flags,omitempty"`
1399 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1400 XXX_unrecognized []byte `json:"-"`
1401 XXX_sizecache int32 `json:"-"`
1402 }
1403
1404 func (m *MemcacheGrabTailResponse_Item) Reset() { *m = MemcacheGrabTailResponse_Item{} }
1405 func (m *MemcacheGrabTailResponse_Item) String() string { return proto.CompactTextString(m) }
1406 func (*MemcacheGrabTailResponse_Item) ProtoMessage() {}
1407 func (*MemcacheGrabTailResponse_Item) Descriptor() ([]byte, []int) {
1408 return fileDescriptor_memcache_service_e327a14e42649a60, []int{18, 0}
1409 }
1410 func (m *MemcacheGrabTailResponse_Item) XXX_Unmarshal(b []byte) error {
1411 return xxx_messageInfo_MemcacheGrabTailResponse_Item.Unmarshal(m, b)
1412 }
1413 func (m *MemcacheGrabTailResponse_Item) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1414 return xxx_messageInfo_MemcacheGrabTailResponse_Item.Marshal(b, m, deterministic)
1415 }
1416 func (dst *MemcacheGrabTailResponse_Item) XXX_Merge(src proto.Message) {
1417 xxx_messageInfo_MemcacheGrabTailResponse_Item.Merge(dst, src)
1418 }
1419 func (m *MemcacheGrabTailResponse_Item) XXX_Size() int {
1420 return xxx_messageInfo_MemcacheGrabTailResponse_Item.Size(m)
1421 }
1422 func (m *MemcacheGrabTailResponse_Item) XXX_DiscardUnknown() {
1423 xxx_messageInfo_MemcacheGrabTailResponse_Item.DiscardUnknown(m)
1424 }
1425
1426 var xxx_messageInfo_MemcacheGrabTailResponse_Item proto.InternalMessageInfo
1427
1428 func (m *MemcacheGrabTailResponse_Item) GetValue() []byte {
1429 if m != nil {
1430 return m.Value
1431 }
1432 return nil
1433 }
1434
1435 func (m *MemcacheGrabTailResponse_Item) GetFlags() uint32 {
1436 if m != nil && m.Flags != nil {
1437 return *m.Flags
1438 }
1439 return 0
1440 }
1441
1442 func init() {
1443 proto.RegisterType((*MemcacheServiceError)(nil), "appengine.MemcacheServiceError")
1444 proto.RegisterType((*AppOverride)(nil), "appengine.AppOverride")
1445 proto.RegisterType((*MemcacheGetRequest)(nil), "appengine.MemcacheGetRequest")
1446 proto.RegisterType((*MemcacheGetResponse)(nil), "appengine.MemcacheGetResponse")
1447 proto.RegisterType((*MemcacheGetResponse_Item)(nil), "appengine.MemcacheGetResponse.Item")
1448 proto.RegisterType((*MemcacheSetRequest)(nil), "appengine.MemcacheSetRequest")
1449 proto.RegisterType((*MemcacheSetRequest_Item)(nil), "appengine.MemcacheSetRequest.Item")
1450 proto.RegisterType((*MemcacheSetResponse)(nil), "appengine.MemcacheSetResponse")
1451 proto.RegisterType((*MemcacheDeleteRequest)(nil), "appengine.MemcacheDeleteRequest")
1452 proto.RegisterType((*MemcacheDeleteRequest_Item)(nil), "appengine.MemcacheDeleteRequest.Item")
1453 proto.RegisterType((*MemcacheDeleteResponse)(nil), "appengine.MemcacheDeleteResponse")
1454 proto.RegisterType((*MemcacheIncrementRequest)(nil), "appengine.MemcacheIncrementRequest")
1455 proto.RegisterType((*MemcacheIncrementResponse)(nil), "appengine.MemcacheIncrementResponse")
1456 proto.RegisterType((*MemcacheBatchIncrementRequest)(nil), "appengine.MemcacheBatchIncrementRequest")
1457 proto.RegisterType((*MemcacheBatchIncrementResponse)(nil), "appengine.MemcacheBatchIncrementResponse")
1458 proto.RegisterType((*MemcacheFlushRequest)(nil), "appengine.MemcacheFlushRequest")
1459 proto.RegisterType((*MemcacheFlushResponse)(nil), "appengine.MemcacheFlushResponse")
1460 proto.RegisterType((*MemcacheStatsRequest)(nil), "appengine.MemcacheStatsRequest")
1461 proto.RegisterType((*MergedNamespaceStats)(nil), "appengine.MergedNamespaceStats")
1462 proto.RegisterType((*MemcacheStatsResponse)(nil), "appengine.MemcacheStatsResponse")
1463 proto.RegisterType((*MemcacheGrabTailRequest)(nil), "appengine.MemcacheGrabTailRequest")
1464 proto.RegisterType((*MemcacheGrabTailResponse)(nil), "appengine.MemcacheGrabTailResponse")
1465 proto.RegisterType((*MemcacheGrabTailResponse_Item)(nil), "appengine.MemcacheGrabTailResponse.Item")
1466 }
1467
1468 func init() {
1469 proto.RegisterFile("google.golang.org/appengine/v2/internal/memcache/memcache_service.proto", fileDescriptor_memcache_service_e327a14e42649a60)
1470 }
1471
1472 var fileDescriptor_memcache_service_e327a14e42649a60 = []byte{
1473 // 1379 bytes of a gzipped FileDescriptorProto
1474 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcd, 0x92, 0xdb, 0xc4,
1475 0x16, 0x8e, 0x24, 0xff, 0xe9, 0x78, 0x7e, 0x94, 0xce, 0x64, 0xe2, 0x3b, 0xb7, 0x72, 0xe3, 0x52,
1476 0xee, 0xbd, 0x18, 0x2a, 0x71, 0x82, 0x29, 0x20, 0x99, 0xca, 0x02, 0x8f, 0xad, 0x49, 0x44, 0x66,
1477 0xec, 0xa9, 0x96, 0x33, 0x50, 0xd9, 0xa8, 0x3a, 0x72, 0x47, 0xa3, 0x1a, 0x59, 0x12, 0x6a, 0x39,
1478 0x21, 0x4b, 0x8a, 0x15, 0x55, 0xb0, 0xe3, 0x05, 0xd8, 0xb0, 0x63, 0xc5, 0x3b, 0xf0, 0x0c, 0x14,
1479 0x7b, 0x8a, 0x15, 0xef, 0x40, 0x75, 0x4b, 0xb2, 0x65, 0x8f, 0x67, 0x98, 0x02, 0x76, 0x3a, 0xa7,
1480 0x4f, 0xab, 0xcf, 0x77, 0xbe, 0xaf, 0x4f, 0x1f, 0xe8, 0xbb, 0x61, 0xe8, 0xfa, 0xb4, 0xed, 0x86,
1481 0x3e, 0x09, 0xdc, 0x76, 0x18, 0xbb, 0xf7, 0x48, 0x14, 0xd1, 0xc0, 0xf5, 0x02, 0x7a, 0xcf, 0x0b,
1482 0x12, 0x1a, 0x07, 0xc4, 0xbf, 0x37, 0xa1, 0x13, 0x87, 0x38, 0x27, 0x74, 0xf6, 0x61, 0x33, 0x1a,
1483 0xbf, 0xf2, 0x1c, 0xda, 0x8e, 0xe2, 0x30, 0x09, 0x91, 0x3a, 0xdb, 0xa3, 0x7f, 0x29, 0xc1, 0xd6,
1484 0x61, 0x16, 0x65, 0xa5, 0x41, 0x46, 0x1c, 0x87, 0xb1, 0x7e, 0x0a, 0xaa, 0xf8, 0xe8, 0x85, 0x63,
1485 0x8a, 0x2a, 0x20, 0x0f, 0x9f, 0x6a, 0x57, 0xd0, 0x75, 0xb8, 0xfa, 0x6c, 0x60, 0x1d, 0x19, 0x3d,
1486 0x73, 0xdf, 0x34, 0xfa, 0xb6, 0x81, 0xf1, 0x10, 0x6b, 0x12, 0x77, 0x0f, 0xba, 0x87, 0x86, 0x75,
1487 0xd4, 0xed, 0x19, 0xf6, 0x60, 0x38, 0xb2, 0x2d, 0x63, 0xa4, 0xc9, 0xdc, 0x7d, 0x64, 0xe0, 0x43,
1488 0xd3, 0xb2, 0xcc, 0xe1, 0xc0, 0xee, 0x1b, 0x03, 0xd3, 0xe8, 0x6b, 0x0a, 0xba, 0x0a, 0xeb, 0xe6,
1489 0xe0, 0xb8, 0x7b, 0x60, 0xf6, 0xed, 0xe3, 0xee, 0xc1, 0x33, 0x43, 0xab, 0xe8, 0x5f, 0xc8, 0x50,
1490 0xef, 0x46, 0xd1, 0xf0, 0x15, 0x8d, 0x63, 0x6f, 0x4c, 0xd1, 0x75, 0xa8, 0x90, 0x28, 0xb2, 0xbd,
1491 0x71, 0x43, 0x6a, 0xca, 0x2d, 0x15, 0x97, 0x49, 0x14, 0x99, 0x63, 0xf4, 0x00, 0xb6, 0x83, 0xe9,
1492 0xc4, 0xce, 0x51, 0xb9, 0xf6, 0x0b, 0xe2, 0x9c, 0xd2, 0x60, 0xcc, 0x1a, 0x72, 0x53, 0x6a, 0x95,
1493 0xf7, 0xe4, 0x86, 0x84, 0xb7, 0x82, 0xe9, 0x24, 0x07, 0xe4, 0xee, 0x65, 0xeb, 0xe8, 0x2e, 0x68,
1494 0x9e, 0x1b, 0x84, 0x31, 0xb5, 0xd9, 0x09, 0x89, 0xc7, 0x7e, 0xe8, 0x9c, 0x36, 0x94, 0xa6, 0xd4,
1495 0xaa, 0x89, 0x3d, 0x9b, 0xe9, 0x9a, 0x95, 0x2f, 0xa1, 0xfb, 0x80, 0x66, 0xa5, 0x8b, 0xc2, 0xd0,
1496 0xb7, 0x4f, 0xbc, 0x20, 0x69, 0x94, 0x9a, 0x52, 0x4b, 0x15, 0x1b, 0xb4, 0x7c, 0xf5, 0x28, 0x0c,
1497 0xfd, 0x27, 0x5e, 0x90, 0xa0, 0x8f, 0x60, 0x67, 0x5e, 0x6c, 0xfe, 0x1f, 0x2f, 0x70, 0x6d, 0x96,
1498 0xc4, 0x24, 0xa1, 0xee, 0x9b, 0x46, 0xb9, 0x29, 0xb5, 0xd6, 0xc4, 0xce, 0x46, 0x1e, 0x65, 0x65,
1499 0x41, 0x56, 0x16, 0xa3, 0x7f, 0x2b, 0x01, 0xca, 0x13, 0x7f, 0x4c, 0x13, 0x4c, 0x3f, 0x9b, 0x52,
1500 0x96, 0x20, 0x0d, 0x94, 0x53, 0xfa, 0xa6, 0x21, 0x35, 0x95, 0xd6, 0x1a, 0xe6, 0x9f, 0xe8, 0x16,
1501 0x40, 0x40, 0x26, 0xd4, 0x66, 0x11, 0x71, 0xa8, 0x40, 0xae, 0xee, 0x5e, 0xc1, 0x2a, 0xf7, 0x59,
1502 0xdc, 0x85, 0x6e, 0x40, 0xf5, 0x65, 0x18, 0xdb, 0x0e, 0x61, 0x22, 0xe5, 0x1a, 0xae, 0xbc, 0x0c,
1503 0xe3, 0x1e, 0x61, 0xa8, 0x03, 0xb5, 0x30, 0x2b, 0xb1, 0x48, 0xa9, 0xde, 0xd9, 0x6e, 0xcf, 0xa4,
1504 0xd0, 0x2e, 0x10, 0x80, 0x67, 0x71, 0xfa, 0x2f, 0x12, 0x5c, 0x5b, 0x48, 0x8b, 0x45, 0x61, 0xc0,
1505 0x28, 0xfa, 0x10, 0x4a, 0x5e, 0x42, 0x27, 0x22, 0x31, 0xe8, 0xdc, 0x2e, 0xfc, 0x67, 0x45, 0x74,
1506 0xdb, 0x4c, 0xe8, 0x04, 0x8b, 0x0d, 0x3b, 0x5f, 0x49, 0x50, 0xe2, 0x66, 0x8e, 0x4c, 0x6e, 0xca,
1507 0x39, 0xb2, 0x2d, 0x28, 0xbf, 0x22, 0xfe, 0x94, 0x36, 0x14, 0xe1, 0x4b, 0x0d, 0xee, 0x7d, 0xe9,
1508 0x13, 0x37, 0x05, 0x53, 0xc5, 0xa9, 0xc1, 0x25, 0xe2, 0x10, 0xc6, 0x25, 0xc2, 0x91, 0x54, 0x70,
1509 0xd9, 0x21, 0xcc, 0x1c, 0xa3, 0x3b, 0x80, 0xe8, 0xe7, 0x91, 0x17, 0x53, 0x66, 0x7b, 0x81, 0xcd,
1510 0xa8, 0x13, 0x72, 0x79, 0x54, 0xb8, 0x3c, 0xb0, 0x96, 0xad, 0x98, 0x81, 0x95, 0xfa, 0xf5, 0x9f,
1511 0x94, 0x79, 0xcd, 0xad, 0x79, 0xcd, 0x3f, 0x58, 0xc0, 0xa6, 0xaf, 0xc0, 0x36, 0x0f, 0x2e, 0x40,
1512 0x5b, 0x62, 0xa6, 0x7a, 0x96, 0x99, 0x22, 0x01, 0x70, 0x39, 0x02, 0x76, 0x7e, 0xff, 0x67, 0xea,
1513 0xf5, 0x14, 0x80, 0xd1, 0xc4, 0x8e, 0x42, 0xdf, 0x73, 0x52, 0x41, 0x6e, 0x74, 0xde, 0xba, 0x18,
1514 0x99, 0x45, 0x93, 0x23, 0x11, 0xbe, 0xab, 0x58, 0xc6, 0x08, 0xab, 0x2c, 0xb7, 0xd1, 0x3b, 0xb0,
1515 0x29, 0x6a, 0x49, 0x12, 0x2f, 0x0c, 0xec, 0xc4, 0x9b, 0x50, 0x51, 0xe2, 0xea, 0xae, 0x74, 0x1f,
1516 0x6f, 0xcc, 0x57, 0x46, 0xde, 0x84, 0x16, 0x88, 0xaa, 0x15, 0x89, 0x2a, 0x88, 0x54, 0x2d, 0x8a,
1517 0x54, 0x7f, 0x0f, 0xd4, 0xd9, 0xc1, 0xa8, 0x0a, 0xfc, 0x68, 0x4d, 0xe2, 0x1f, 0xdd, 0x7e, 0x5f,
1518 0x93, 0x51, 0x1d, 0xaa, 0xd8, 0x38, 0x3a, 0xe8, 0xf6, 0x0c, 0x4d, 0xe1, 0xde, 0x5e, 0xd7, 0xd2,
1519 0x4a, 0xfa, 0xf7, 0x05, 0x95, 0x5a, 0x05, 0x95, 0x66, 0xa8, 0x59, 0x42, 0x92, 0x29, 0x13, 0x7c,
1520 0x6e, 0x74, 0xee, 0x9c, 0x87, 0x3a, 0xd3, 0xaa, 0x45, 0x13, 0x4b, 0xc4, 0xf3, 0xd6, 0x27, 0x50,
1521 0xa7, 0xa6, 0xbe, 0x07, 0xeb, 0x0b, 0x6b, 0x08, 0xa0, 0x62, 0x8d, 0x86, 0xd8, 0xe8, 0x6b, 0x12,
1522 0xda, 0x00, 0x10, 0x9d, 0x2f, 0xb5, 0x65, 0xa4, 0x42, 0x39, 0x6d, 0x8f, 0x0a, 0x0f, 0x33, 0x3e,
1523 0x35, 0xad, 0x11, 0x4f, 0xf4, 0x57, 0x09, 0xae, 0xe7, 0x87, 0xf6, 0xa9, 0x4f, 0x13, 0x9a, 0x8b,
1524 0xee, 0xe1, 0x82, 0xe8, 0xfe, 0xb7, 0x22, 0xc9, 0x85, 0xf8, 0xf3, 0x75, 0x57, 0xba, 0x58, 0x77,
1525 0x97, 0xbc, 0xf8, 0x3b, 0x8f, 0xce, 0x95, 0x9d, 0x0e, 0xf5, 0xb1, 0x48, 0x25, 0x65, 0x5e, 0xc9,
1526 0x99, 0x87, 0xd4, 0xcb, 0x59, 0xd7, 0xbf, 0x93, 0x60, 0x7b, 0x39, 0xef, 0x8c, 0x93, 0x4f, 0x60,
1527 0x3d, 0xdb, 0xbe, 0x40, 0x4b, 0xe7, 0x02, 0xc4, 0x19, 0x33, 0xa9, 0x59, 0x20, 0x67, 0x6d, 0x5c,
1528 0xf0, 0xe8, 0x6d, 0xd0, 0x96, 0x23, 0xb8, 0x5c, 0xfa, 0xc6, 0x81, 0x31, 0x12, 0x1c, 0xad, 0x83,
1529 0xca, 0x39, 0xda, 0x1f, 0x3e, 0x1b, 0xf4, 0x35, 0x59, 0xff, 0x4d, 0x86, 0x46, 0x7e, 0x92, 0x19,
1530 0x38, 0x31, 0x9d, 0xd0, 0xe0, 0x6c, 0xdf, 0x95, 0x57, 0xf7, 0xdd, 0xd2, 0xaa, 0xbe, 0x5b, 0x1e,
1531 0x53, 0x3f, 0x21, 0xa2, 0x27, 0x97, 0x76, 0xa5, 0x77, 0x71, 0x6a, 0xa3, 0x63, 0x50, 0xc7, 0x5e,
1532 0x4c, 0x1d, 0x7e, 0x27, 0x44, 0xb9, 0x36, 0x3a, 0x77, 0x57, 0xa0, 0x5d, 0xce, 0xa1, 0xdd, 0xcf,
1533 0x37, 0xed, 0xaa, 0xe6, 0xa0, 0x87, 0x8d, 0x43, 0x63, 0x30, 0xc2, 0xf3, 0x5f, 0xa1, 0xdb, 0xb0,
1534 0xee, 0x05, 0x5e, 0xe2, 0x11, 0xdf, 0x4e, 0xfb, 0x00, 0xe7, 0xb6, 0x84, 0xd7, 0x32, 0xe7, 0xb1,
1535 0x68, 0x07, 0x85, 0xa0, 0xb4, 0x2d, 0x88, 0x9b, 0x3a, 0x0b, 0xda, 0x17, 0xdd, 0xa1, 0x28, 0x90,
1536 0xea, 0x25, 0x5f, 0x86, 0xb7, 0x41, 0x9d, 0x25, 0xc8, 0x4b, 0x3b, 0x4b, 0x31, 0xad, 0x74, 0xdf,
1537 0xc8, 0x4d, 0x59, 0xff, 0x59, 0x82, 0x7f, 0xad, 0x40, 0x99, 0x09, 0xe2, 0xdf, 0xa0, 0x06, 0xf4,
1538 0x75, 0x06, 0x41, 0x12, 0x10, 0x6a, 0x01, 0x7d, 0x9d, 0xa6, 0xef, 0x80, 0xe6, 0xe5, 0x3b, 0x72,
1539 0xc1, 0xc8, 0xa2, 0x84, 0x0f, 0x2e, 0x2e, 0x61, 0xfe, 0xf2, 0xe4, 0x9e, 0x82, 0x6c, 0x36, 0xbd,
1540 0x45, 0xa7, 0xfe, 0x10, 0xae, 0xad, 0x88, 0xcb, 0xc6, 0x1e, 0x09, 0x6d, 0x42, 0x9d, 0xeb, 0xa6,
1541 0xf7, 0xa4, 0x3b, 0x78, 0xbc, 0x74, 0xb9, 0xf5, 0x1f, 0x24, 0xb8, 0x99, 0x9f, 0xbe, 0x47, 0x12,
1542 0xe7, 0xe4, 0x8c, 0x92, 0x16, 0x75, 0x23, 0x9d, 0xd5, 0x4d, 0xfe, 0x94, 0xca, 0x4d, 0xa5, 0x55,
1543 0x5f, 0xf9, 0x94, 0x2e, 0xff, 0x33, 0xbb, 0xf7, 0x45, 0xd6, 0x94, 0x4b, 0xb2, 0xf6, 0x1c, 0xfe,
1544 0x73, 0x5e, 0xba, 0x19, 0x1d, 0x0f, 0x0a, 0x8d, 0xa8, 0xde, 0xf9, 0xef, 0x65, 0xaa, 0x9c, 0xe6,
1545 0xa3, 0x7f, 0x3c, 0x9f, 0x25, 0xf7, 0xfd, 0x29, 0x3b, 0xc9, 0x2b, 0x50, 0xcc, 0x53, 0xba, 0x64,
1546 0x9e, 0x37, 0xe6, 0x7d, 0x32, 0xfb, 0x57, 0x7a, 0x54, 0xf1, 0x10, 0x4e, 0x15, 0xfb, 0x3b, 0x87,
1547 0xfc, 0x28, 0xa6, 0xdf, 0xd8, 0xa5, 0xe3, 0x01, 0x99, 0x50, 0x41, 0x90, 0xf8, 0x27, 0x42, 0x50,
1548 0x3a, 0xf1, 0x12, 0x26, 0xae, 0x7f, 0x09, 0x8b, 0x6f, 0xb4, 0x0d, 0x95, 0x89, 0xc7, 0x18, 0x65,
1549 0xa2, 0x17, 0x96, 0x70, 0x66, 0x71, 0xf9, 0xbe, 0x78, 0x93, 0x50, 0x5b, 0x6c, 0x50, 0xc4, 0x52,
1550 0x8d, 0x3b, 0x9e, 0xf0, 0x4d, 0x5b, 0x50, 0xe6, 0xa5, 0xe1, 0x8f, 0x31, 0x5f, 0x48, 0x0d, 0xee,
1551 0xe5, 0x11, 0xac, 0x51, 0x4e, 0xbd, 0xc2, 0x40, 0xff, 0x87, 0xcd, 0xd0, 0x1f, 0x53, 0x96, 0xd8,
1552 0x3c, 0xca, 0x26, 0x2e, 0x7f, 0x55, 0xe5, 0x56, 0x15, 0xaf, 0xa7, 0x6e, 0xde, 0x8e, 0xbb, 0x2e,
1553 0xd5, 0x07, 0xf3, 0xd2, 0x64, 0x15, 0xc8, 0x98, 0x7b, 0x1f, 0xca, 0xfc, 0x86, 0xb0, 0x0c, 0xff,
1554 0xad, 0x05, 0xea, 0xce, 0xa2, 0xc4, 0x69, 0xb4, 0xfe, 0x8d, 0x04, 0x37, 0x66, 0x43, 0x5b, 0x4c,
1555 0x5e, 0x8c, 0x88, 0xe7, 0xe7, 0x55, 0xbd, 0x09, 0x20, 0x92, 0x71, 0xc2, 0x69, 0x90, 0x88, 0x72,
1556 0x94, 0xb1, 0xca, 0x3d, 0x3d, 0xee, 0xf8, 0xf3, 0x59, 0xf4, 0xaf, 0x48, 0xf4, 0x6b, 0x69, 0xde,
1557 0x97, 0xe7, 0xf9, 0x64, 0x18, 0x1f, 0x2d, 0x3c, 0x93, 0xad, 0x55, 0x73, 0xe7, 0xd2, 0x96, 0xe2,
1558 0xf0, 0xd9, 0xc9, 0x1e, 0xb5, 0xd9, 0xe4, 0x24, 0xaf, 0x9c, 0x9c, 0x94, 0xc2, 0xe4, 0xb4, 0x07,
1559 0xcf, 0x6b, 0xf9, 0xd0, 0xfe, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x76, 0x8b, 0xe6, 0x6b, 0x80,
1560 0x0d, 0x00, 0x00,
1561 }
0 syntax = "proto2";
1 option go_package = "memcache";
2
3 package appengine;
4
5 message MemcacheServiceError {
6 enum ErrorCode {
7 OK = 0;
8 UNSPECIFIED_ERROR = 1;
9 NAMESPACE_NOT_SET = 2;
10 PERMISSION_DENIED = 3;
11 INVALID_VALUE = 6;
12 }
13 }
14
15 message AppOverride {
16 required string app_id = 1;
17
18 optional int32 num_memcacheg_backends = 2 [deprecated=true];
19 optional bool ignore_shardlock = 3 [deprecated=true];
20 optional string memcache_pool_hint = 4 [deprecated=true];
21 optional bytes memcache_sharding_strategy = 5 [deprecated=true];
22 }
23
24 message MemcacheGetRequest {
25 repeated bytes key = 1;
26 optional string name_space = 2 [default = ""];
27 optional bool for_cas = 4;
28 optional AppOverride override = 5;
29 }
30
31 message MemcacheGetResponse {
32 repeated group Item = 1 {
33 required bytes key = 2;
34 required bytes value = 3;
35 optional fixed32 flags = 4;
36 optional fixed64 cas_id = 5;
37 optional int32 expires_in_seconds = 6;
38 }
39 }
40
41 message MemcacheSetRequest {
42 enum SetPolicy {
43 SET = 1;
44 ADD = 2;
45 REPLACE = 3;
46 CAS = 4;
47 }
48 repeated group Item = 1 {
49 required bytes key = 2;
50 required bytes value = 3;
51
52 optional fixed32 flags = 4;
53 optional SetPolicy set_policy = 5 [default = SET];
54 optional fixed32 expiration_time = 6 [default = 0];
55
56 optional fixed64 cas_id = 8;
57 optional bool for_cas = 9;
58 }
59 optional string name_space = 7 [default = ""];
60 optional AppOverride override = 10;
61 }
62
63 message MemcacheSetResponse {
64 enum SetStatusCode {
65 STORED = 1;
66 NOT_STORED = 2;
67 ERROR = 3;
68 EXISTS = 4;
69 }
70 repeated SetStatusCode set_status = 1;
71 }
72
73 message MemcacheDeleteRequest {
74 repeated group Item = 1 {
75 required bytes key = 2;
76 optional fixed32 delete_time = 3 [default = 0];
77 }
78 optional string name_space = 4 [default = ""];
79 optional AppOverride override = 5;
80 }
81
82 message MemcacheDeleteResponse {
83 enum DeleteStatusCode {
84 DELETED = 1;
85 NOT_FOUND = 2;
86 }
87 repeated DeleteStatusCode delete_status = 1;
88 }
89
90 message MemcacheIncrementRequest {
91 enum Direction {
92 INCREMENT = 1;
93 DECREMENT = 2;
94 }
95 required bytes key = 1;
96 optional string name_space = 4 [default = ""];
97
98 optional uint64 delta = 2 [default = 1];
99 optional Direction direction = 3 [default = INCREMENT];
100
101 optional uint64 initial_value = 5;
102 optional fixed32 initial_flags = 6;
103 optional AppOverride override = 7;
104 }
105
106 message MemcacheIncrementResponse {
107 enum IncrementStatusCode {
108 OK = 1;
109 NOT_CHANGED = 2;
110 ERROR = 3;
111 }
112
113 optional uint64 new_value = 1;
114 optional IncrementStatusCode increment_status = 2;
115 }
116
117 message MemcacheBatchIncrementRequest {
118 optional string name_space = 1 [default = ""];
119 repeated MemcacheIncrementRequest item = 2;
120 optional AppOverride override = 3;
121 }
122
123 message MemcacheBatchIncrementResponse {
124 repeated MemcacheIncrementResponse item = 1;
125 }
126
127 message MemcacheFlushRequest {
128 optional AppOverride override = 1;
129 }
130
131 message MemcacheFlushResponse {
132 }
133
134 message MemcacheStatsRequest {
135 optional AppOverride override = 1;
136 }
137
138 message MergedNamespaceStats {
139 required uint64 hits = 1;
140 required uint64 misses = 2;
141 required uint64 byte_hits = 3;
142
143 required uint64 items = 4;
144 required uint64 bytes = 5;
145
146 required fixed32 oldest_item_age = 6;
147 }
148
149 message MemcacheStatsResponse {
150 optional MergedNamespaceStats stats = 1;
151 }
152
153 message MemcacheGrabTailRequest {
154 required int32 item_count = 1;
155 optional string name_space = 2 [default = ""];
156 optional AppOverride override = 3;
157 }
158
159 message MemcacheGrabTailResponse {
160 repeated group Item = 1 {
161 required bytes value = 2;
162 optional fixed32 flags = 3;
163 }
164 }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 // This file has code for accessing metadata.
7 //
8 // References:
9 // https://cloud.google.com/compute/docs/metadata
10
11 import (
12 "fmt"
13 "io/ioutil"
14 "net/http"
15 "net/url"
16 )
17
18 const (
19 metadataHost = "metadata"
20 metadataPath = "/computeMetadata/v1/"
21 )
22
23 var (
24 metadataRequestHeaders = http.Header{
25 "Metadata-Flavor": []string{"Google"},
26 }
27 )
28
29 // TODO(dsymonds): Do we need to support default values, like Python?
30 func mustGetMetadata(key string) []byte {
31 b, err := getMetadata(key)
32 if err != nil {
33 panic(fmt.Sprintf("Metadata fetch failed for '%s': %v", key, err))
34 }
35 return b
36 }
37
38 func getMetadata(key string) ([]byte, error) {
39 // TODO(dsymonds): May need to use url.Parse to support keys with query args.
40 req := &http.Request{
41 Method: "GET",
42 URL: &url.URL{
43 Scheme: "http",
44 Host: metadataHost,
45 Path: metadataPath + key,
46 },
47 Header: metadataRequestHeaders,
48 Host: metadataHost,
49 }
50 resp, err := http.DefaultClient.Do(req)
51 if err != nil {
52 return nil, err
53 }
54 defer resp.Body.Close()
55 if resp.StatusCode != 200 {
56 return nil, fmt.Errorf("metadata server returned HTTP %d", resp.StatusCode)
57 }
58 return ioutil.ReadAll(resp.Body)
59 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/modules/modules_service.proto
2
3 package modules
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type ModulesServiceError_ErrorCode int32
21
22 const (
23 ModulesServiceError_OK ModulesServiceError_ErrorCode = 0
24 ModulesServiceError_INVALID_MODULE ModulesServiceError_ErrorCode = 1
25 ModulesServiceError_INVALID_VERSION ModulesServiceError_ErrorCode = 2
26 ModulesServiceError_INVALID_INSTANCES ModulesServiceError_ErrorCode = 3
27 ModulesServiceError_TRANSIENT_ERROR ModulesServiceError_ErrorCode = 4
28 ModulesServiceError_UNEXPECTED_STATE ModulesServiceError_ErrorCode = 5
29 )
30
31 var ModulesServiceError_ErrorCode_name = map[int32]string{
32 0: "OK",
33 1: "INVALID_MODULE",
34 2: "INVALID_VERSION",
35 3: "INVALID_INSTANCES",
36 4: "TRANSIENT_ERROR",
37 5: "UNEXPECTED_STATE",
38 }
39 var ModulesServiceError_ErrorCode_value = map[string]int32{
40 "OK": 0,
41 "INVALID_MODULE": 1,
42 "INVALID_VERSION": 2,
43 "INVALID_INSTANCES": 3,
44 "TRANSIENT_ERROR": 4,
45 "UNEXPECTED_STATE": 5,
46 }
47
48 func (x ModulesServiceError_ErrorCode) Enum() *ModulesServiceError_ErrorCode {
49 p := new(ModulesServiceError_ErrorCode)
50 *p = x
51 return p
52 }
53 func (x ModulesServiceError_ErrorCode) String() string {
54 return proto.EnumName(ModulesServiceError_ErrorCode_name, int32(x))
55 }
56 func (x *ModulesServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
57 value, err := proto.UnmarshalJSONEnum(ModulesServiceError_ErrorCode_value, data, "ModulesServiceError_ErrorCode")
58 if err != nil {
59 return err
60 }
61 *x = ModulesServiceError_ErrorCode(value)
62 return nil
63 }
64 func (ModulesServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
65 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{0, 0}
66 }
67
68 type ModulesServiceError struct {
69 XXX_NoUnkeyedLiteral struct{} `json:"-"`
70 XXX_unrecognized []byte `json:"-"`
71 XXX_sizecache int32 `json:"-"`
72 }
73
74 func (m *ModulesServiceError) Reset() { *m = ModulesServiceError{} }
75 func (m *ModulesServiceError) String() string { return proto.CompactTextString(m) }
76 func (*ModulesServiceError) ProtoMessage() {}
77 func (*ModulesServiceError) Descriptor() ([]byte, []int) {
78 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{0}
79 }
80 func (m *ModulesServiceError) XXX_Unmarshal(b []byte) error {
81 return xxx_messageInfo_ModulesServiceError.Unmarshal(m, b)
82 }
83 func (m *ModulesServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
84 return xxx_messageInfo_ModulesServiceError.Marshal(b, m, deterministic)
85 }
86 func (dst *ModulesServiceError) XXX_Merge(src proto.Message) {
87 xxx_messageInfo_ModulesServiceError.Merge(dst, src)
88 }
89 func (m *ModulesServiceError) XXX_Size() int {
90 return xxx_messageInfo_ModulesServiceError.Size(m)
91 }
92 func (m *ModulesServiceError) XXX_DiscardUnknown() {
93 xxx_messageInfo_ModulesServiceError.DiscardUnknown(m)
94 }
95
96 var xxx_messageInfo_ModulesServiceError proto.InternalMessageInfo
97
98 type GetModulesRequest struct {
99 XXX_NoUnkeyedLiteral struct{} `json:"-"`
100 XXX_unrecognized []byte `json:"-"`
101 XXX_sizecache int32 `json:"-"`
102 }
103
104 func (m *GetModulesRequest) Reset() { *m = GetModulesRequest{} }
105 func (m *GetModulesRequest) String() string { return proto.CompactTextString(m) }
106 func (*GetModulesRequest) ProtoMessage() {}
107 func (*GetModulesRequest) Descriptor() ([]byte, []int) {
108 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{1}
109 }
110 func (m *GetModulesRequest) XXX_Unmarshal(b []byte) error {
111 return xxx_messageInfo_GetModulesRequest.Unmarshal(m, b)
112 }
113 func (m *GetModulesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
114 return xxx_messageInfo_GetModulesRequest.Marshal(b, m, deterministic)
115 }
116 func (dst *GetModulesRequest) XXX_Merge(src proto.Message) {
117 xxx_messageInfo_GetModulesRequest.Merge(dst, src)
118 }
119 func (m *GetModulesRequest) XXX_Size() int {
120 return xxx_messageInfo_GetModulesRequest.Size(m)
121 }
122 func (m *GetModulesRequest) XXX_DiscardUnknown() {
123 xxx_messageInfo_GetModulesRequest.DiscardUnknown(m)
124 }
125
126 var xxx_messageInfo_GetModulesRequest proto.InternalMessageInfo
127
128 type GetModulesResponse struct {
129 Module []string `protobuf:"bytes,1,rep,name=module" json:"module,omitempty"`
130 XXX_NoUnkeyedLiteral struct{} `json:"-"`
131 XXX_unrecognized []byte `json:"-"`
132 XXX_sizecache int32 `json:"-"`
133 }
134
135 func (m *GetModulesResponse) Reset() { *m = GetModulesResponse{} }
136 func (m *GetModulesResponse) String() string { return proto.CompactTextString(m) }
137 func (*GetModulesResponse) ProtoMessage() {}
138 func (*GetModulesResponse) Descriptor() ([]byte, []int) {
139 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{2}
140 }
141 func (m *GetModulesResponse) XXX_Unmarshal(b []byte) error {
142 return xxx_messageInfo_GetModulesResponse.Unmarshal(m, b)
143 }
144 func (m *GetModulesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
145 return xxx_messageInfo_GetModulesResponse.Marshal(b, m, deterministic)
146 }
147 func (dst *GetModulesResponse) XXX_Merge(src proto.Message) {
148 xxx_messageInfo_GetModulesResponse.Merge(dst, src)
149 }
150 func (m *GetModulesResponse) XXX_Size() int {
151 return xxx_messageInfo_GetModulesResponse.Size(m)
152 }
153 func (m *GetModulesResponse) XXX_DiscardUnknown() {
154 xxx_messageInfo_GetModulesResponse.DiscardUnknown(m)
155 }
156
157 var xxx_messageInfo_GetModulesResponse proto.InternalMessageInfo
158
159 func (m *GetModulesResponse) GetModule() []string {
160 if m != nil {
161 return m.Module
162 }
163 return nil
164 }
165
166 type GetVersionsRequest struct {
167 Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
168 XXX_NoUnkeyedLiteral struct{} `json:"-"`
169 XXX_unrecognized []byte `json:"-"`
170 XXX_sizecache int32 `json:"-"`
171 }
172
173 func (m *GetVersionsRequest) Reset() { *m = GetVersionsRequest{} }
174 func (m *GetVersionsRequest) String() string { return proto.CompactTextString(m) }
175 func (*GetVersionsRequest) ProtoMessage() {}
176 func (*GetVersionsRequest) Descriptor() ([]byte, []int) {
177 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{3}
178 }
179 func (m *GetVersionsRequest) XXX_Unmarshal(b []byte) error {
180 return xxx_messageInfo_GetVersionsRequest.Unmarshal(m, b)
181 }
182 func (m *GetVersionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
183 return xxx_messageInfo_GetVersionsRequest.Marshal(b, m, deterministic)
184 }
185 func (dst *GetVersionsRequest) XXX_Merge(src proto.Message) {
186 xxx_messageInfo_GetVersionsRequest.Merge(dst, src)
187 }
188 func (m *GetVersionsRequest) XXX_Size() int {
189 return xxx_messageInfo_GetVersionsRequest.Size(m)
190 }
191 func (m *GetVersionsRequest) XXX_DiscardUnknown() {
192 xxx_messageInfo_GetVersionsRequest.DiscardUnknown(m)
193 }
194
195 var xxx_messageInfo_GetVersionsRequest proto.InternalMessageInfo
196
197 func (m *GetVersionsRequest) GetModule() string {
198 if m != nil && m.Module != nil {
199 return *m.Module
200 }
201 return ""
202 }
203
204 type GetVersionsResponse struct {
205 Version []string `protobuf:"bytes,1,rep,name=version" json:"version,omitempty"`
206 XXX_NoUnkeyedLiteral struct{} `json:"-"`
207 XXX_unrecognized []byte `json:"-"`
208 XXX_sizecache int32 `json:"-"`
209 }
210
211 func (m *GetVersionsResponse) Reset() { *m = GetVersionsResponse{} }
212 func (m *GetVersionsResponse) String() string { return proto.CompactTextString(m) }
213 func (*GetVersionsResponse) ProtoMessage() {}
214 func (*GetVersionsResponse) Descriptor() ([]byte, []int) {
215 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{4}
216 }
217 func (m *GetVersionsResponse) XXX_Unmarshal(b []byte) error {
218 return xxx_messageInfo_GetVersionsResponse.Unmarshal(m, b)
219 }
220 func (m *GetVersionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
221 return xxx_messageInfo_GetVersionsResponse.Marshal(b, m, deterministic)
222 }
223 func (dst *GetVersionsResponse) XXX_Merge(src proto.Message) {
224 xxx_messageInfo_GetVersionsResponse.Merge(dst, src)
225 }
226 func (m *GetVersionsResponse) XXX_Size() int {
227 return xxx_messageInfo_GetVersionsResponse.Size(m)
228 }
229 func (m *GetVersionsResponse) XXX_DiscardUnknown() {
230 xxx_messageInfo_GetVersionsResponse.DiscardUnknown(m)
231 }
232
233 var xxx_messageInfo_GetVersionsResponse proto.InternalMessageInfo
234
235 func (m *GetVersionsResponse) GetVersion() []string {
236 if m != nil {
237 return m.Version
238 }
239 return nil
240 }
241
242 type GetDefaultVersionRequest struct {
243 Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
244 XXX_NoUnkeyedLiteral struct{} `json:"-"`
245 XXX_unrecognized []byte `json:"-"`
246 XXX_sizecache int32 `json:"-"`
247 }
248
249 func (m *GetDefaultVersionRequest) Reset() { *m = GetDefaultVersionRequest{} }
250 func (m *GetDefaultVersionRequest) String() string { return proto.CompactTextString(m) }
251 func (*GetDefaultVersionRequest) ProtoMessage() {}
252 func (*GetDefaultVersionRequest) Descriptor() ([]byte, []int) {
253 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{5}
254 }
255 func (m *GetDefaultVersionRequest) XXX_Unmarshal(b []byte) error {
256 return xxx_messageInfo_GetDefaultVersionRequest.Unmarshal(m, b)
257 }
258 func (m *GetDefaultVersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
259 return xxx_messageInfo_GetDefaultVersionRequest.Marshal(b, m, deterministic)
260 }
261 func (dst *GetDefaultVersionRequest) XXX_Merge(src proto.Message) {
262 xxx_messageInfo_GetDefaultVersionRequest.Merge(dst, src)
263 }
264 func (m *GetDefaultVersionRequest) XXX_Size() int {
265 return xxx_messageInfo_GetDefaultVersionRequest.Size(m)
266 }
267 func (m *GetDefaultVersionRequest) XXX_DiscardUnknown() {
268 xxx_messageInfo_GetDefaultVersionRequest.DiscardUnknown(m)
269 }
270
271 var xxx_messageInfo_GetDefaultVersionRequest proto.InternalMessageInfo
272
273 func (m *GetDefaultVersionRequest) GetModule() string {
274 if m != nil && m.Module != nil {
275 return *m.Module
276 }
277 return ""
278 }
279
280 type GetDefaultVersionResponse struct {
281 Version *string `protobuf:"bytes,1,req,name=version" json:"version,omitempty"`
282 XXX_NoUnkeyedLiteral struct{} `json:"-"`
283 XXX_unrecognized []byte `json:"-"`
284 XXX_sizecache int32 `json:"-"`
285 }
286
287 func (m *GetDefaultVersionResponse) Reset() { *m = GetDefaultVersionResponse{} }
288 func (m *GetDefaultVersionResponse) String() string { return proto.CompactTextString(m) }
289 func (*GetDefaultVersionResponse) ProtoMessage() {}
290 func (*GetDefaultVersionResponse) Descriptor() ([]byte, []int) {
291 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{6}
292 }
293 func (m *GetDefaultVersionResponse) XXX_Unmarshal(b []byte) error {
294 return xxx_messageInfo_GetDefaultVersionResponse.Unmarshal(m, b)
295 }
296 func (m *GetDefaultVersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
297 return xxx_messageInfo_GetDefaultVersionResponse.Marshal(b, m, deterministic)
298 }
299 func (dst *GetDefaultVersionResponse) XXX_Merge(src proto.Message) {
300 xxx_messageInfo_GetDefaultVersionResponse.Merge(dst, src)
301 }
302 func (m *GetDefaultVersionResponse) XXX_Size() int {
303 return xxx_messageInfo_GetDefaultVersionResponse.Size(m)
304 }
305 func (m *GetDefaultVersionResponse) XXX_DiscardUnknown() {
306 xxx_messageInfo_GetDefaultVersionResponse.DiscardUnknown(m)
307 }
308
309 var xxx_messageInfo_GetDefaultVersionResponse proto.InternalMessageInfo
310
311 func (m *GetDefaultVersionResponse) GetVersion() string {
312 if m != nil && m.Version != nil {
313 return *m.Version
314 }
315 return ""
316 }
317
318 type GetNumInstancesRequest struct {
319 Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
320 Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
321 XXX_NoUnkeyedLiteral struct{} `json:"-"`
322 XXX_unrecognized []byte `json:"-"`
323 XXX_sizecache int32 `json:"-"`
324 }
325
326 func (m *GetNumInstancesRequest) Reset() { *m = GetNumInstancesRequest{} }
327 func (m *GetNumInstancesRequest) String() string { return proto.CompactTextString(m) }
328 func (*GetNumInstancesRequest) ProtoMessage() {}
329 func (*GetNumInstancesRequest) Descriptor() ([]byte, []int) {
330 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{7}
331 }
332 func (m *GetNumInstancesRequest) XXX_Unmarshal(b []byte) error {
333 return xxx_messageInfo_GetNumInstancesRequest.Unmarshal(m, b)
334 }
335 func (m *GetNumInstancesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
336 return xxx_messageInfo_GetNumInstancesRequest.Marshal(b, m, deterministic)
337 }
338 func (dst *GetNumInstancesRequest) XXX_Merge(src proto.Message) {
339 xxx_messageInfo_GetNumInstancesRequest.Merge(dst, src)
340 }
341 func (m *GetNumInstancesRequest) XXX_Size() int {
342 return xxx_messageInfo_GetNumInstancesRequest.Size(m)
343 }
344 func (m *GetNumInstancesRequest) XXX_DiscardUnknown() {
345 xxx_messageInfo_GetNumInstancesRequest.DiscardUnknown(m)
346 }
347
348 var xxx_messageInfo_GetNumInstancesRequest proto.InternalMessageInfo
349
350 func (m *GetNumInstancesRequest) GetModule() string {
351 if m != nil && m.Module != nil {
352 return *m.Module
353 }
354 return ""
355 }
356
357 func (m *GetNumInstancesRequest) GetVersion() string {
358 if m != nil && m.Version != nil {
359 return *m.Version
360 }
361 return ""
362 }
363
364 type GetNumInstancesResponse struct {
365 Instances *int64 `protobuf:"varint,1,req,name=instances" json:"instances,omitempty"`
366 XXX_NoUnkeyedLiteral struct{} `json:"-"`
367 XXX_unrecognized []byte `json:"-"`
368 XXX_sizecache int32 `json:"-"`
369 }
370
371 func (m *GetNumInstancesResponse) Reset() { *m = GetNumInstancesResponse{} }
372 func (m *GetNumInstancesResponse) String() string { return proto.CompactTextString(m) }
373 func (*GetNumInstancesResponse) ProtoMessage() {}
374 func (*GetNumInstancesResponse) Descriptor() ([]byte, []int) {
375 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{8}
376 }
377 func (m *GetNumInstancesResponse) XXX_Unmarshal(b []byte) error {
378 return xxx_messageInfo_GetNumInstancesResponse.Unmarshal(m, b)
379 }
380 func (m *GetNumInstancesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
381 return xxx_messageInfo_GetNumInstancesResponse.Marshal(b, m, deterministic)
382 }
383 func (dst *GetNumInstancesResponse) XXX_Merge(src proto.Message) {
384 xxx_messageInfo_GetNumInstancesResponse.Merge(dst, src)
385 }
386 func (m *GetNumInstancesResponse) XXX_Size() int {
387 return xxx_messageInfo_GetNumInstancesResponse.Size(m)
388 }
389 func (m *GetNumInstancesResponse) XXX_DiscardUnknown() {
390 xxx_messageInfo_GetNumInstancesResponse.DiscardUnknown(m)
391 }
392
393 var xxx_messageInfo_GetNumInstancesResponse proto.InternalMessageInfo
394
395 func (m *GetNumInstancesResponse) GetInstances() int64 {
396 if m != nil && m.Instances != nil {
397 return *m.Instances
398 }
399 return 0
400 }
401
402 type SetNumInstancesRequest struct {
403 Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
404 Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
405 Instances *int64 `protobuf:"varint,3,req,name=instances" json:"instances,omitempty"`
406 XXX_NoUnkeyedLiteral struct{} `json:"-"`
407 XXX_unrecognized []byte `json:"-"`
408 XXX_sizecache int32 `json:"-"`
409 }
410
411 func (m *SetNumInstancesRequest) Reset() { *m = SetNumInstancesRequest{} }
412 func (m *SetNumInstancesRequest) String() string { return proto.CompactTextString(m) }
413 func (*SetNumInstancesRequest) ProtoMessage() {}
414 func (*SetNumInstancesRequest) Descriptor() ([]byte, []int) {
415 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{9}
416 }
417 func (m *SetNumInstancesRequest) XXX_Unmarshal(b []byte) error {
418 return xxx_messageInfo_SetNumInstancesRequest.Unmarshal(m, b)
419 }
420 func (m *SetNumInstancesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
421 return xxx_messageInfo_SetNumInstancesRequest.Marshal(b, m, deterministic)
422 }
423 func (dst *SetNumInstancesRequest) XXX_Merge(src proto.Message) {
424 xxx_messageInfo_SetNumInstancesRequest.Merge(dst, src)
425 }
426 func (m *SetNumInstancesRequest) XXX_Size() int {
427 return xxx_messageInfo_SetNumInstancesRequest.Size(m)
428 }
429 func (m *SetNumInstancesRequest) XXX_DiscardUnknown() {
430 xxx_messageInfo_SetNumInstancesRequest.DiscardUnknown(m)
431 }
432
433 var xxx_messageInfo_SetNumInstancesRequest proto.InternalMessageInfo
434
435 func (m *SetNumInstancesRequest) GetModule() string {
436 if m != nil && m.Module != nil {
437 return *m.Module
438 }
439 return ""
440 }
441
442 func (m *SetNumInstancesRequest) GetVersion() string {
443 if m != nil && m.Version != nil {
444 return *m.Version
445 }
446 return ""
447 }
448
449 func (m *SetNumInstancesRequest) GetInstances() int64 {
450 if m != nil && m.Instances != nil {
451 return *m.Instances
452 }
453 return 0
454 }
455
456 type SetNumInstancesResponse struct {
457 XXX_NoUnkeyedLiteral struct{} `json:"-"`
458 XXX_unrecognized []byte `json:"-"`
459 XXX_sizecache int32 `json:"-"`
460 }
461
462 func (m *SetNumInstancesResponse) Reset() { *m = SetNumInstancesResponse{} }
463 func (m *SetNumInstancesResponse) String() string { return proto.CompactTextString(m) }
464 func (*SetNumInstancesResponse) ProtoMessage() {}
465 func (*SetNumInstancesResponse) Descriptor() ([]byte, []int) {
466 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{10}
467 }
468 func (m *SetNumInstancesResponse) XXX_Unmarshal(b []byte) error {
469 return xxx_messageInfo_SetNumInstancesResponse.Unmarshal(m, b)
470 }
471 func (m *SetNumInstancesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
472 return xxx_messageInfo_SetNumInstancesResponse.Marshal(b, m, deterministic)
473 }
474 func (dst *SetNumInstancesResponse) XXX_Merge(src proto.Message) {
475 xxx_messageInfo_SetNumInstancesResponse.Merge(dst, src)
476 }
477 func (m *SetNumInstancesResponse) XXX_Size() int {
478 return xxx_messageInfo_SetNumInstancesResponse.Size(m)
479 }
480 func (m *SetNumInstancesResponse) XXX_DiscardUnknown() {
481 xxx_messageInfo_SetNumInstancesResponse.DiscardUnknown(m)
482 }
483
484 var xxx_messageInfo_SetNumInstancesResponse proto.InternalMessageInfo
485
486 type StartModuleRequest struct {
487 Module *string `protobuf:"bytes,1,req,name=module" json:"module,omitempty"`
488 Version *string `protobuf:"bytes,2,req,name=version" json:"version,omitempty"`
489 XXX_NoUnkeyedLiteral struct{} `json:"-"`
490 XXX_unrecognized []byte `json:"-"`
491 XXX_sizecache int32 `json:"-"`
492 }
493
494 func (m *StartModuleRequest) Reset() { *m = StartModuleRequest{} }
495 func (m *StartModuleRequest) String() string { return proto.CompactTextString(m) }
496 func (*StartModuleRequest) ProtoMessage() {}
497 func (*StartModuleRequest) Descriptor() ([]byte, []int) {
498 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{11}
499 }
500 func (m *StartModuleRequest) XXX_Unmarshal(b []byte) error {
501 return xxx_messageInfo_StartModuleRequest.Unmarshal(m, b)
502 }
503 func (m *StartModuleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
504 return xxx_messageInfo_StartModuleRequest.Marshal(b, m, deterministic)
505 }
506 func (dst *StartModuleRequest) XXX_Merge(src proto.Message) {
507 xxx_messageInfo_StartModuleRequest.Merge(dst, src)
508 }
509 func (m *StartModuleRequest) XXX_Size() int {
510 return xxx_messageInfo_StartModuleRequest.Size(m)
511 }
512 func (m *StartModuleRequest) XXX_DiscardUnknown() {
513 xxx_messageInfo_StartModuleRequest.DiscardUnknown(m)
514 }
515
516 var xxx_messageInfo_StartModuleRequest proto.InternalMessageInfo
517
518 func (m *StartModuleRequest) GetModule() string {
519 if m != nil && m.Module != nil {
520 return *m.Module
521 }
522 return ""
523 }
524
525 func (m *StartModuleRequest) GetVersion() string {
526 if m != nil && m.Version != nil {
527 return *m.Version
528 }
529 return ""
530 }
531
532 type StartModuleResponse struct {
533 XXX_NoUnkeyedLiteral struct{} `json:"-"`
534 XXX_unrecognized []byte `json:"-"`
535 XXX_sizecache int32 `json:"-"`
536 }
537
538 func (m *StartModuleResponse) Reset() { *m = StartModuleResponse{} }
539 func (m *StartModuleResponse) String() string { return proto.CompactTextString(m) }
540 func (*StartModuleResponse) ProtoMessage() {}
541 func (*StartModuleResponse) Descriptor() ([]byte, []int) {
542 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{12}
543 }
544 func (m *StartModuleResponse) XXX_Unmarshal(b []byte) error {
545 return xxx_messageInfo_StartModuleResponse.Unmarshal(m, b)
546 }
547 func (m *StartModuleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
548 return xxx_messageInfo_StartModuleResponse.Marshal(b, m, deterministic)
549 }
550 func (dst *StartModuleResponse) XXX_Merge(src proto.Message) {
551 xxx_messageInfo_StartModuleResponse.Merge(dst, src)
552 }
553 func (m *StartModuleResponse) XXX_Size() int {
554 return xxx_messageInfo_StartModuleResponse.Size(m)
555 }
556 func (m *StartModuleResponse) XXX_DiscardUnknown() {
557 xxx_messageInfo_StartModuleResponse.DiscardUnknown(m)
558 }
559
560 var xxx_messageInfo_StartModuleResponse proto.InternalMessageInfo
561
562 type StopModuleRequest struct {
563 Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
564 Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
565 XXX_NoUnkeyedLiteral struct{} `json:"-"`
566 XXX_unrecognized []byte `json:"-"`
567 XXX_sizecache int32 `json:"-"`
568 }
569
570 func (m *StopModuleRequest) Reset() { *m = StopModuleRequest{} }
571 func (m *StopModuleRequest) String() string { return proto.CompactTextString(m) }
572 func (*StopModuleRequest) ProtoMessage() {}
573 func (*StopModuleRequest) Descriptor() ([]byte, []int) {
574 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{13}
575 }
576 func (m *StopModuleRequest) XXX_Unmarshal(b []byte) error {
577 return xxx_messageInfo_StopModuleRequest.Unmarshal(m, b)
578 }
579 func (m *StopModuleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
580 return xxx_messageInfo_StopModuleRequest.Marshal(b, m, deterministic)
581 }
582 func (dst *StopModuleRequest) XXX_Merge(src proto.Message) {
583 xxx_messageInfo_StopModuleRequest.Merge(dst, src)
584 }
585 func (m *StopModuleRequest) XXX_Size() int {
586 return xxx_messageInfo_StopModuleRequest.Size(m)
587 }
588 func (m *StopModuleRequest) XXX_DiscardUnknown() {
589 xxx_messageInfo_StopModuleRequest.DiscardUnknown(m)
590 }
591
592 var xxx_messageInfo_StopModuleRequest proto.InternalMessageInfo
593
594 func (m *StopModuleRequest) GetModule() string {
595 if m != nil && m.Module != nil {
596 return *m.Module
597 }
598 return ""
599 }
600
601 func (m *StopModuleRequest) GetVersion() string {
602 if m != nil && m.Version != nil {
603 return *m.Version
604 }
605 return ""
606 }
607
608 type StopModuleResponse struct {
609 XXX_NoUnkeyedLiteral struct{} `json:"-"`
610 XXX_unrecognized []byte `json:"-"`
611 XXX_sizecache int32 `json:"-"`
612 }
613
614 func (m *StopModuleResponse) Reset() { *m = StopModuleResponse{} }
615 func (m *StopModuleResponse) String() string { return proto.CompactTextString(m) }
616 func (*StopModuleResponse) ProtoMessage() {}
617 func (*StopModuleResponse) Descriptor() ([]byte, []int) {
618 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{14}
619 }
620 func (m *StopModuleResponse) XXX_Unmarshal(b []byte) error {
621 return xxx_messageInfo_StopModuleResponse.Unmarshal(m, b)
622 }
623 func (m *StopModuleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
624 return xxx_messageInfo_StopModuleResponse.Marshal(b, m, deterministic)
625 }
626 func (dst *StopModuleResponse) XXX_Merge(src proto.Message) {
627 xxx_messageInfo_StopModuleResponse.Merge(dst, src)
628 }
629 func (m *StopModuleResponse) XXX_Size() int {
630 return xxx_messageInfo_StopModuleResponse.Size(m)
631 }
632 func (m *StopModuleResponse) XXX_DiscardUnknown() {
633 xxx_messageInfo_StopModuleResponse.DiscardUnknown(m)
634 }
635
636 var xxx_messageInfo_StopModuleResponse proto.InternalMessageInfo
637
638 type GetHostnameRequest struct {
639 Module *string `protobuf:"bytes,1,opt,name=module" json:"module,omitempty"`
640 Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
641 Instance *string `protobuf:"bytes,3,opt,name=instance" json:"instance,omitempty"`
642 XXX_NoUnkeyedLiteral struct{} `json:"-"`
643 XXX_unrecognized []byte `json:"-"`
644 XXX_sizecache int32 `json:"-"`
645 }
646
647 func (m *GetHostnameRequest) Reset() { *m = GetHostnameRequest{} }
648 func (m *GetHostnameRequest) String() string { return proto.CompactTextString(m) }
649 func (*GetHostnameRequest) ProtoMessage() {}
650 func (*GetHostnameRequest) Descriptor() ([]byte, []int) {
651 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{15}
652 }
653 func (m *GetHostnameRequest) XXX_Unmarshal(b []byte) error {
654 return xxx_messageInfo_GetHostnameRequest.Unmarshal(m, b)
655 }
656 func (m *GetHostnameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
657 return xxx_messageInfo_GetHostnameRequest.Marshal(b, m, deterministic)
658 }
659 func (dst *GetHostnameRequest) XXX_Merge(src proto.Message) {
660 xxx_messageInfo_GetHostnameRequest.Merge(dst, src)
661 }
662 func (m *GetHostnameRequest) XXX_Size() int {
663 return xxx_messageInfo_GetHostnameRequest.Size(m)
664 }
665 func (m *GetHostnameRequest) XXX_DiscardUnknown() {
666 xxx_messageInfo_GetHostnameRequest.DiscardUnknown(m)
667 }
668
669 var xxx_messageInfo_GetHostnameRequest proto.InternalMessageInfo
670
671 func (m *GetHostnameRequest) GetModule() string {
672 if m != nil && m.Module != nil {
673 return *m.Module
674 }
675 return ""
676 }
677
678 func (m *GetHostnameRequest) GetVersion() string {
679 if m != nil && m.Version != nil {
680 return *m.Version
681 }
682 return ""
683 }
684
685 func (m *GetHostnameRequest) GetInstance() string {
686 if m != nil && m.Instance != nil {
687 return *m.Instance
688 }
689 return ""
690 }
691
692 type GetHostnameResponse struct {
693 Hostname *string `protobuf:"bytes,1,req,name=hostname" json:"hostname,omitempty"`
694 XXX_NoUnkeyedLiteral struct{} `json:"-"`
695 XXX_unrecognized []byte `json:"-"`
696 XXX_sizecache int32 `json:"-"`
697 }
698
699 func (m *GetHostnameResponse) Reset() { *m = GetHostnameResponse{} }
700 func (m *GetHostnameResponse) String() string { return proto.CompactTextString(m) }
701 func (*GetHostnameResponse) ProtoMessage() {}
702 func (*GetHostnameResponse) Descriptor() ([]byte, []int) {
703 return fileDescriptor_modules_service_9cd3bffe4e91c59a, []int{16}
704 }
705 func (m *GetHostnameResponse) XXX_Unmarshal(b []byte) error {
706 return xxx_messageInfo_GetHostnameResponse.Unmarshal(m, b)
707 }
708 func (m *GetHostnameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
709 return xxx_messageInfo_GetHostnameResponse.Marshal(b, m, deterministic)
710 }
711 func (dst *GetHostnameResponse) XXX_Merge(src proto.Message) {
712 xxx_messageInfo_GetHostnameResponse.Merge(dst, src)
713 }
714 func (m *GetHostnameResponse) XXX_Size() int {
715 return xxx_messageInfo_GetHostnameResponse.Size(m)
716 }
717 func (m *GetHostnameResponse) XXX_DiscardUnknown() {
718 xxx_messageInfo_GetHostnameResponse.DiscardUnknown(m)
719 }
720
721 var xxx_messageInfo_GetHostnameResponse proto.InternalMessageInfo
722
723 func (m *GetHostnameResponse) GetHostname() string {
724 if m != nil && m.Hostname != nil {
725 return *m.Hostname
726 }
727 return ""
728 }
729
730 func init() {
731 proto.RegisterType((*ModulesServiceError)(nil), "appengine.ModulesServiceError")
732 proto.RegisterType((*GetModulesRequest)(nil), "appengine.GetModulesRequest")
733 proto.RegisterType((*GetModulesResponse)(nil), "appengine.GetModulesResponse")
734 proto.RegisterType((*GetVersionsRequest)(nil), "appengine.GetVersionsRequest")
735 proto.RegisterType((*GetVersionsResponse)(nil), "appengine.GetVersionsResponse")
736 proto.RegisterType((*GetDefaultVersionRequest)(nil), "appengine.GetDefaultVersionRequest")
737 proto.RegisterType((*GetDefaultVersionResponse)(nil), "appengine.GetDefaultVersionResponse")
738 proto.RegisterType((*GetNumInstancesRequest)(nil), "appengine.GetNumInstancesRequest")
739 proto.RegisterType((*GetNumInstancesResponse)(nil), "appengine.GetNumInstancesResponse")
740 proto.RegisterType((*SetNumInstancesRequest)(nil), "appengine.SetNumInstancesRequest")
741 proto.RegisterType((*SetNumInstancesResponse)(nil), "appengine.SetNumInstancesResponse")
742 proto.RegisterType((*StartModuleRequest)(nil), "appengine.StartModuleRequest")
743 proto.RegisterType((*StartModuleResponse)(nil), "appengine.StartModuleResponse")
744 proto.RegisterType((*StopModuleRequest)(nil), "appengine.StopModuleRequest")
745 proto.RegisterType((*StopModuleResponse)(nil), "appengine.StopModuleResponse")
746 proto.RegisterType((*GetHostnameRequest)(nil), "appengine.GetHostnameRequest")
747 proto.RegisterType((*GetHostnameResponse)(nil), "appengine.GetHostnameResponse")
748 }
749
750 func init() {
751 proto.RegisterFile("google.golang.org/appengine/v2/internal/modules/modules_service.proto", fileDescriptor_modules_service_9cd3bffe4e91c59a)
752 }
753
754 var fileDescriptor_modules_service_9cd3bffe4e91c59a = []byte{
755 // 457 bytes of a gzipped FileDescriptorProto
756 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0xc1, 0x6f, 0xd3, 0x30,
757 0x14, 0xc6, 0x69, 0x02, 0xdb, 0xf2, 0x0e, 0x90, 0x3a, 0x5b, 0xd7, 0x4d, 0x1c, 0x50, 0x4e, 0x1c,
758 0x50, 0x2b, 0x90, 0x10, 0xe7, 0xae, 0x35, 0x25, 0xb0, 0xa5, 0x28, 0xce, 0x2a, 0xc4, 0xa5, 0x0a,
759 0xdb, 0x23, 0x8b, 0x94, 0xda, 0xc1, 0x76, 0x77, 0xe4, 0xbf, 0xe0, 0xff, 0x45, 0x4b, 0xed, 0xb6,
760 0x81, 0x4e, 0x45, 0x68, 0xa7, 0xe4, 0x7d, 0xfe, 0xfc, 0x7b, 0x9f, 0x5f, 0xac, 0xc0, 0x59, 0x2e,
761 0x44, 0x5e, 0x62, 0x2f, 0x17, 0x65, 0xc6, 0xf3, 0x9e, 0x90, 0x79, 0x3f, 0xab, 0x2a, 0xe4, 0x79,
762 0xc1, 0xb1, 0x5f, 0x70, 0x8d, 0x92, 0x67, 0x65, 0x7f, 0x2e, 0xae, 0x17, 0x25, 0x2a, 0xfb, 0x9c,
763 0x29, 0x94, 0xb7, 0xc5, 0x15, 0xf6, 0x2a, 0x29, 0xb4, 0x20, 0xde, 0x6a, 0x47, 0xf8, 0xab, 0x05,
764 0xc1, 0xc5, 0xd2, 0xc4, 0x96, 0x1e, 0x2a, 0xa5, 0x90, 0xe1, 0x4f, 0xf0, 0xea, 0x97, 0xa1, 0xb8,
765 0x46, 0xb2, 0x07, 0xce, 0xe4, 0x93, 0xff, 0x88, 0x10, 0x78, 0x1a, 0xc5, 0xd3, 0xc1, 0x79, 0x34,
766 0x9a, 0x5d, 0x4c, 0x46, 0x97, 0xe7, 0xd4, 0x6f, 0x91, 0x00, 0x9e, 0x59, 0x6d, 0x4a, 0x13, 0x16,
767 0x4d, 0x62, 0xdf, 0x21, 0x47, 0xd0, 0xb6, 0x62, 0x14, 0xb3, 0x74, 0x10, 0x0f, 0x29, 0xf3, 0xdd,
768 0x3b, 0x6f, 0x9a, 0x0c, 0x62, 0x16, 0xd1, 0x38, 0x9d, 0xd1, 0x24, 0x99, 0x24, 0xfe, 0x63, 0x72,
769 0x08, 0xfe, 0x65, 0x4c, 0xbf, 0x7c, 0xa6, 0xc3, 0x94, 0x8e, 0x66, 0x2c, 0x1d, 0xa4, 0xd4, 0x7f,
770 0x12, 0x06, 0xd0, 0x1e, 0xa3, 0x36, 0xc9, 0x12, 0xfc, 0xb1, 0x40, 0xa5, 0xc3, 0x57, 0x40, 0x36,
771 0x45, 0x55, 0x09, 0xae, 0x90, 0x74, 0x60, 0x6f, 0x79, 0xcc, 0x6e, 0xeb, 0x85, 0xfb, 0xd2, 0x4b,
772 0x4c, 0x65, 0xdc, 0x53, 0x94, 0xaa, 0x10, 0xdc, 0x32, 0x1a, 0xee, 0xd6, 0x86, 0xbb, 0x0f, 0x41,
773 0xc3, 0x6d, 0xe0, 0x5d, 0xd8, 0xbf, 0x5d, 0x6a, 0x86, 0x6e, 0xcb, 0xf0, 0x0d, 0x74, 0xc7, 0xa8,
774 0x47, 0xf8, 0x3d, 0x5b, 0x94, 0x76, 0xdf, 0xae, 0x26, 0x6f, 0xe1, 0x64, 0xcb, 0x9e, 0x6d, 0xad,
775 0x9c, 0xcd, 0x56, 0x1f, 0xa1, 0x33, 0x46, 0x1d, 0x2f, 0xe6, 0x11, 0x57, 0x3a, 0xe3, 0x57, 0xb8,
776 0xeb, 0x34, 0x9b, 0x2c, 0xa7, 0x5e, 0x58, 0xb1, 0xde, 0xc1, 0xf1, 0x5f, 0x2c, 0x13, 0xe0, 0x39,
777 0x78, 0x85, 0x15, 0xeb, 0x08, 0x6e, 0xb2, 0x16, 0xc2, 0x1b, 0xe8, 0xb0, 0x07, 0x0a, 0xd1, 0xec,
778 0xe4, 0xfe, 0xd9, 0xe9, 0x04, 0x8e, 0xd9, 0xf6, 0x88, 0xe1, 0x7b, 0x20, 0x4c, 0x67, 0xd2, 0xdc,
779 0x81, 0x6d, 0x01, 0x9c, 0xfb, 0x02, 0x34, 0x26, 0x7a, 0x04, 0x41, 0x83, 0x63, 0xf0, 0x14, 0xda,
780 0x4c, 0x8b, 0xea, 0x7e, 0xfa, 0xbf, 0xcd, 0xf8, 0xf0, 0x2e, 0xe5, 0x1a, 0x63, 0xe0, 0xdf, 0xea,
781 0xfb, 0xf8, 0x41, 0x28, 0xcd, 0xb3, 0xf9, 0xff, 0xd3, 0xc9, 0x29, 0x1c, 0xd8, 0x59, 0x75, 0xdd,
782 0x7a, 0x69, 0x55, 0x87, 0xaf, 0xeb, 0x5b, 0xbc, 0xee, 0x61, 0xbe, 0xec, 0x29, 0x1c, 0xdc, 0x18,
783 0xcd, 0x8c, 0x68, 0x55, 0x9f, 0x79, 0x5f, 0xf7, 0xcd, 0x5f, 0xe2, 0x77, 0x00, 0x00, 0x00, 0xff,
784 0xff, 0x6e, 0xbc, 0xe0, 0x61, 0x5c, 0x04, 0x00, 0x00,
785 }
0 syntax = "proto2";
1 option go_package = "modules";
2
3 package appengine;
4
5 message ModulesServiceError {
6 enum ErrorCode {
7 OK = 0;
8 INVALID_MODULE = 1;
9 INVALID_VERSION = 2;
10 INVALID_INSTANCES = 3;
11 TRANSIENT_ERROR = 4;
12 UNEXPECTED_STATE = 5;
13 }
14 }
15
16 message GetModulesRequest {
17 }
18
19 message GetModulesResponse {
20 repeated string module = 1;
21 }
22
23 message GetVersionsRequest {
24 optional string module = 1;
25 }
26
27 message GetVersionsResponse {
28 repeated string version = 1;
29 }
30
31 message GetDefaultVersionRequest {
32 optional string module = 1;
33 }
34
35 message GetDefaultVersionResponse {
36 required string version = 1;
37 }
38
39 message GetNumInstancesRequest {
40 optional string module = 1;
41 optional string version = 2;
42 }
43
44 message GetNumInstancesResponse {
45 required int64 instances = 1;
46 }
47
48 message SetNumInstancesRequest {
49 optional string module = 1;
50 optional string version = 2;
51 required int64 instances = 3;
52 }
53
54 message SetNumInstancesResponse {}
55
56 message StartModuleRequest {
57 required string module = 1;
58 required string version = 2;
59 }
60
61 message StartModuleResponse {}
62
63 message StopModuleRequest {
64 optional string module = 1;
65 optional string version = 2;
66 }
67
68 message StopModuleResponse {}
69
70 message GetHostnameRequest {
71 optional string module = 1;
72 optional string version = 2;
73 optional string instance = 3;
74 }
75
76 message GetHostnameResponse {
77 required string hostname = 1;
78 }
79
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 // This file implements a network dialer that limits the number of concurrent connections.
7 // It is only used for API calls.
8
9 import (
10 "log"
11 "net"
12 "runtime"
13 "sync"
14 "time"
15 )
16
17 var limitSem = make(chan int, 100) // TODO(dsymonds): Use environment variable.
18
19 func limitRelease() {
20 // non-blocking
21 select {
22 case <-limitSem:
23 default:
24 // This should not normally happen.
25 log.Print("appengine: unbalanced limitSem release!")
26 }
27 }
28
29 func limitDial(network, addr string) (net.Conn, error) {
30 limitSem <- 1
31
32 // Dial with a timeout in case the API host is MIA.
33 // The connection should normally be very fast.
34 conn, err := net.DialTimeout(network, addr, 10*time.Second)
35 if err != nil {
36 limitRelease()
37 return nil, err
38 }
39 lc := &limitConn{Conn: conn}
40 runtime.SetFinalizer(lc, (*limitConn).Close) // shouldn't usually be required
41 return lc, nil
42 }
43
44 type limitConn struct {
45 close sync.Once
46 net.Conn
47 }
48
49 func (lc *limitConn) Close() error {
50 defer lc.close.Do(func() {
51 limitRelease()
52 runtime.SetFinalizer(lc, nil)
53 })
54 return lc.Conn.Close()
55 }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 import (
7 netcontext "context"
8 "sync"
9 "testing"
10 "time"
11
12 basepb "google.golang.org/appengine/v2/internal/base"
13 )
14
15 func TestDialLimit(t *testing.T) {
16 // Fill up semaphore with false acquisitions to permit only two TCP connections at a time.
17 // We don't replace limitSem because that results in a data race when net/http lazily closes connections.
18 nFake := cap(limitSem) - 2
19 for i := 0; i < nFake; i++ {
20 limitSem <- 1
21 }
22 defer func() {
23 for i := 0; i < nFake; i++ {
24 <-limitSem
25 }
26 }()
27
28 f, c, cleanup := setup() // setup is in api_test.go
29 defer cleanup()
30 f.hang = make(chan int)
31
32 // If we make two RunSlowly RPCs (which will wait for f.hang to be strobed),
33 // then the simple Non200 RPC should hang.
34 var wg sync.WaitGroup
35 wg.Add(2)
36 for i := 0; i < 2; i++ {
37 go func() {
38 defer wg.Done()
39 Call(toContext(c), "errors", "RunSlowly", &basepb.VoidProto{}, &basepb.VoidProto{})
40 }()
41 }
42 time.Sleep(50 * time.Millisecond) // let those two RPCs start
43
44 ctx, _ := netcontext.WithTimeout(toContext(c), 50*time.Millisecond)
45 err := Call(ctx, "errors", "Non200", &basepb.VoidProto{}, &basepb.VoidProto{})
46 if err != errTimeout {
47 t.Errorf("Non200 RPC returned with err %v, want errTimeout", err)
48 }
49
50 // Drain the two RunSlowly calls.
51 f.hang <- 1
52 f.hang <- 1
53 wg.Wait()
54 }
0 #!/bin/bash -e
1 #
2 # This script rebuilds the generated code for the protocol buffers.
3 # To run this you will need protoc and goprotobuf installed;
4 # see https://github.com/golang/protobuf for instructions.
5
6 PKG=google.golang.org/appengine
7
8 function die() {
9 echo 1>&2 $*
10 exit 1
11 }
12
13 # Sanity check that the right tools are accessible.
14 for tool in go protoc protoc-gen-go; do
15 q=$(which $tool) || die "didn't find $tool"
16 echo 1>&2 "$tool: $q"
17 done
18
19 echo -n 1>&2 "finding package dir... "
20 pkgdir=$(go list -f '{{.Dir}}' $PKG)
21 echo 1>&2 $pkgdir
22 base=$(echo $pkgdir | sed "s,/$PKG\$,,")
23 echo 1>&2 "base: $base"
24 cd $base
25
26 # Run protoc once per package.
27 for dir in $(find $PKG/internal -name '*.proto' | xargs dirname | sort | uniq); do
28 echo 1>&2 "* $dir"
29 protoc --go_out=. $dir/*.proto
30 done
31
32 for f in $(find $PKG/internal -name '*.pb.go'); do
33 # Remove proto.RegisterEnum calls.
34 # These cause duplicate registration panics when these packages
35 # are used on classic App Engine. proto.RegisterEnum only affects
36 # parsing the text format; we don't care about that.
37 # https://code.google.com/p/googleappengine/issues/detail?id=11670#c17
38 sed -i '/proto.RegisterEnum/d' $f
39 done
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/remote_api/remote_api.proto
2
3 package remote_api
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type RpcError_ErrorCode int32
21
22 const (
23 RpcError_UNKNOWN RpcError_ErrorCode = 0
24 RpcError_CALL_NOT_FOUND RpcError_ErrorCode = 1
25 RpcError_PARSE_ERROR RpcError_ErrorCode = 2
26 RpcError_SECURITY_VIOLATION RpcError_ErrorCode = 3
27 RpcError_OVER_QUOTA RpcError_ErrorCode = 4
28 RpcError_REQUEST_TOO_LARGE RpcError_ErrorCode = 5
29 RpcError_CAPABILITY_DISABLED RpcError_ErrorCode = 6
30 RpcError_FEATURE_DISABLED RpcError_ErrorCode = 7
31 RpcError_BAD_REQUEST RpcError_ErrorCode = 8
32 RpcError_RESPONSE_TOO_LARGE RpcError_ErrorCode = 9
33 RpcError_CANCELLED RpcError_ErrorCode = 10
34 RpcError_REPLAY_ERROR RpcError_ErrorCode = 11
35 RpcError_DEADLINE_EXCEEDED RpcError_ErrorCode = 12
36 )
37
38 var RpcError_ErrorCode_name = map[int32]string{
39 0: "UNKNOWN",
40 1: "CALL_NOT_FOUND",
41 2: "PARSE_ERROR",
42 3: "SECURITY_VIOLATION",
43 4: "OVER_QUOTA",
44 5: "REQUEST_TOO_LARGE",
45 6: "CAPABILITY_DISABLED",
46 7: "FEATURE_DISABLED",
47 8: "BAD_REQUEST",
48 9: "RESPONSE_TOO_LARGE",
49 10: "CANCELLED",
50 11: "REPLAY_ERROR",
51 12: "DEADLINE_EXCEEDED",
52 }
53 var RpcError_ErrorCode_value = map[string]int32{
54 "UNKNOWN": 0,
55 "CALL_NOT_FOUND": 1,
56 "PARSE_ERROR": 2,
57 "SECURITY_VIOLATION": 3,
58 "OVER_QUOTA": 4,
59 "REQUEST_TOO_LARGE": 5,
60 "CAPABILITY_DISABLED": 6,
61 "FEATURE_DISABLED": 7,
62 "BAD_REQUEST": 8,
63 "RESPONSE_TOO_LARGE": 9,
64 "CANCELLED": 10,
65 "REPLAY_ERROR": 11,
66 "DEADLINE_EXCEEDED": 12,
67 }
68
69 func (x RpcError_ErrorCode) Enum() *RpcError_ErrorCode {
70 p := new(RpcError_ErrorCode)
71 *p = x
72 return p
73 }
74 func (x RpcError_ErrorCode) String() string {
75 return proto.EnumName(RpcError_ErrorCode_name, int32(x))
76 }
77 func (x *RpcError_ErrorCode) UnmarshalJSON(data []byte) error {
78 value, err := proto.UnmarshalJSONEnum(RpcError_ErrorCode_value, data, "RpcError_ErrorCode")
79 if err != nil {
80 return err
81 }
82 *x = RpcError_ErrorCode(value)
83 return nil
84 }
85 func (RpcError_ErrorCode) EnumDescriptor() ([]byte, []int) {
86 return fileDescriptor_remote_api_1978114ec33a273d, []int{2, 0}
87 }
88
89 type Request struct {
90 ServiceName *string `protobuf:"bytes,2,req,name=service_name,json=serviceName" json:"service_name,omitempty"`
91 Method *string `protobuf:"bytes,3,req,name=method" json:"method,omitempty"`
92 Request []byte `protobuf:"bytes,4,req,name=request" json:"request,omitempty"`
93 RequestId *string `protobuf:"bytes,5,opt,name=request_id,json=requestId" json:"request_id,omitempty"`
94 XXX_NoUnkeyedLiteral struct{} `json:"-"`
95 XXX_unrecognized []byte `json:"-"`
96 XXX_sizecache int32 `json:"-"`
97 }
98
99 func (m *Request) Reset() { *m = Request{} }
100 func (m *Request) String() string { return proto.CompactTextString(m) }
101 func (*Request) ProtoMessage() {}
102 func (*Request) Descriptor() ([]byte, []int) {
103 return fileDescriptor_remote_api_1978114ec33a273d, []int{0}
104 }
105 func (m *Request) XXX_Unmarshal(b []byte) error {
106 return xxx_messageInfo_Request.Unmarshal(m, b)
107 }
108 func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
109 return xxx_messageInfo_Request.Marshal(b, m, deterministic)
110 }
111 func (dst *Request) XXX_Merge(src proto.Message) {
112 xxx_messageInfo_Request.Merge(dst, src)
113 }
114 func (m *Request) XXX_Size() int {
115 return xxx_messageInfo_Request.Size(m)
116 }
117 func (m *Request) XXX_DiscardUnknown() {
118 xxx_messageInfo_Request.DiscardUnknown(m)
119 }
120
121 var xxx_messageInfo_Request proto.InternalMessageInfo
122
123 func (m *Request) GetServiceName() string {
124 if m != nil && m.ServiceName != nil {
125 return *m.ServiceName
126 }
127 return ""
128 }
129
130 func (m *Request) GetMethod() string {
131 if m != nil && m.Method != nil {
132 return *m.Method
133 }
134 return ""
135 }
136
137 func (m *Request) GetRequest() []byte {
138 if m != nil {
139 return m.Request
140 }
141 return nil
142 }
143
144 func (m *Request) GetRequestId() string {
145 if m != nil && m.RequestId != nil {
146 return *m.RequestId
147 }
148 return ""
149 }
150
151 type ApplicationError struct {
152 Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"`
153 Detail *string `protobuf:"bytes,2,req,name=detail" json:"detail,omitempty"`
154 XXX_NoUnkeyedLiteral struct{} `json:"-"`
155 XXX_unrecognized []byte `json:"-"`
156 XXX_sizecache int32 `json:"-"`
157 }
158
159 func (m *ApplicationError) Reset() { *m = ApplicationError{} }
160 func (m *ApplicationError) String() string { return proto.CompactTextString(m) }
161 func (*ApplicationError) ProtoMessage() {}
162 func (*ApplicationError) Descriptor() ([]byte, []int) {
163 return fileDescriptor_remote_api_1978114ec33a273d, []int{1}
164 }
165 func (m *ApplicationError) XXX_Unmarshal(b []byte) error {
166 return xxx_messageInfo_ApplicationError.Unmarshal(m, b)
167 }
168 func (m *ApplicationError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
169 return xxx_messageInfo_ApplicationError.Marshal(b, m, deterministic)
170 }
171 func (dst *ApplicationError) XXX_Merge(src proto.Message) {
172 xxx_messageInfo_ApplicationError.Merge(dst, src)
173 }
174 func (m *ApplicationError) XXX_Size() int {
175 return xxx_messageInfo_ApplicationError.Size(m)
176 }
177 func (m *ApplicationError) XXX_DiscardUnknown() {
178 xxx_messageInfo_ApplicationError.DiscardUnknown(m)
179 }
180
181 var xxx_messageInfo_ApplicationError proto.InternalMessageInfo
182
183 func (m *ApplicationError) GetCode() int32 {
184 if m != nil && m.Code != nil {
185 return *m.Code
186 }
187 return 0
188 }
189
190 func (m *ApplicationError) GetDetail() string {
191 if m != nil && m.Detail != nil {
192 return *m.Detail
193 }
194 return ""
195 }
196
197 type RpcError struct {
198 Code *int32 `protobuf:"varint,1,req,name=code" json:"code,omitempty"`
199 Detail *string `protobuf:"bytes,2,opt,name=detail" json:"detail,omitempty"`
200 XXX_NoUnkeyedLiteral struct{} `json:"-"`
201 XXX_unrecognized []byte `json:"-"`
202 XXX_sizecache int32 `json:"-"`
203 }
204
205 func (m *RpcError) Reset() { *m = RpcError{} }
206 func (m *RpcError) String() string { return proto.CompactTextString(m) }
207 func (*RpcError) ProtoMessage() {}
208 func (*RpcError) Descriptor() ([]byte, []int) {
209 return fileDescriptor_remote_api_1978114ec33a273d, []int{2}
210 }
211 func (m *RpcError) XXX_Unmarshal(b []byte) error {
212 return xxx_messageInfo_RpcError.Unmarshal(m, b)
213 }
214 func (m *RpcError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
215 return xxx_messageInfo_RpcError.Marshal(b, m, deterministic)
216 }
217 func (dst *RpcError) XXX_Merge(src proto.Message) {
218 xxx_messageInfo_RpcError.Merge(dst, src)
219 }
220 func (m *RpcError) XXX_Size() int {
221 return xxx_messageInfo_RpcError.Size(m)
222 }
223 func (m *RpcError) XXX_DiscardUnknown() {
224 xxx_messageInfo_RpcError.DiscardUnknown(m)
225 }
226
227 var xxx_messageInfo_RpcError proto.InternalMessageInfo
228
229 func (m *RpcError) GetCode() int32 {
230 if m != nil && m.Code != nil {
231 return *m.Code
232 }
233 return 0
234 }
235
236 func (m *RpcError) GetDetail() string {
237 if m != nil && m.Detail != nil {
238 return *m.Detail
239 }
240 return ""
241 }
242
243 type Response struct {
244 Response []byte `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
245 Exception []byte `protobuf:"bytes,2,opt,name=exception" json:"exception,omitempty"`
246 ApplicationError *ApplicationError `protobuf:"bytes,3,opt,name=application_error,json=applicationError" json:"application_error,omitempty"`
247 JavaException []byte `protobuf:"bytes,4,opt,name=java_exception,json=javaException" json:"java_exception,omitempty"`
248 RpcError *RpcError `protobuf:"bytes,5,opt,name=rpc_error,json=rpcError" json:"rpc_error,omitempty"`
249 XXX_NoUnkeyedLiteral struct{} `json:"-"`
250 XXX_unrecognized []byte `json:"-"`
251 XXX_sizecache int32 `json:"-"`
252 }
253
254 func (m *Response) Reset() { *m = Response{} }
255 func (m *Response) String() string { return proto.CompactTextString(m) }
256 func (*Response) ProtoMessage() {}
257 func (*Response) Descriptor() ([]byte, []int) {
258 return fileDescriptor_remote_api_1978114ec33a273d, []int{3}
259 }
260 func (m *Response) XXX_Unmarshal(b []byte) error {
261 return xxx_messageInfo_Response.Unmarshal(m, b)
262 }
263 func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
264 return xxx_messageInfo_Response.Marshal(b, m, deterministic)
265 }
266 func (dst *Response) XXX_Merge(src proto.Message) {
267 xxx_messageInfo_Response.Merge(dst, src)
268 }
269 func (m *Response) XXX_Size() int {
270 return xxx_messageInfo_Response.Size(m)
271 }
272 func (m *Response) XXX_DiscardUnknown() {
273 xxx_messageInfo_Response.DiscardUnknown(m)
274 }
275
276 var xxx_messageInfo_Response proto.InternalMessageInfo
277
278 func (m *Response) GetResponse() []byte {
279 if m != nil {
280 return m.Response
281 }
282 return nil
283 }
284
285 func (m *Response) GetException() []byte {
286 if m != nil {
287 return m.Exception
288 }
289 return nil
290 }
291
292 func (m *Response) GetApplicationError() *ApplicationError {
293 if m != nil {
294 return m.ApplicationError
295 }
296 return nil
297 }
298
299 func (m *Response) GetJavaException() []byte {
300 if m != nil {
301 return m.JavaException
302 }
303 return nil
304 }
305
306 func (m *Response) GetRpcError() *RpcError {
307 if m != nil {
308 return m.RpcError
309 }
310 return nil
311 }
312
313 func init() {
314 proto.RegisterType((*Request)(nil), "remote_api.Request")
315 proto.RegisterType((*ApplicationError)(nil), "remote_api.ApplicationError")
316 proto.RegisterType((*RpcError)(nil), "remote_api.RpcError")
317 proto.RegisterType((*Response)(nil), "remote_api.Response")
318 }
319
320 func init() {
321 proto.RegisterFile("google.golang.org/appengine/v2/internal/remote_api/remote_api.proto", fileDescriptor_remote_api_1978114ec33a273d)
322 }
323
324 var fileDescriptor_remote_api_1978114ec33a273d = []byte{
325 // 531 bytes of a gzipped FileDescriptorProto
326 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x51, 0x6e, 0xd3, 0x40,
327 0x10, 0x86, 0xb1, 0x9b, 0x34, 0xf1, 0xc4, 0x2d, 0xdb, 0xa5, 0x14, 0x0b, 0x15, 0x29, 0x44, 0x42,
328 0xca, 0x53, 0x2a, 0x38, 0x00, 0x62, 0x63, 0x6f, 0x91, 0x85, 0x65, 0xa7, 0x6b, 0xbb, 0x50, 0x5e,
329 0x56, 0x2b, 0x67, 0x65, 0x8c, 0x12, 0xaf, 0xd9, 0x98, 0x8a, 0x17, 0x6e, 0xc0, 0xb5, 0x38, 0x0c,
330 0xb7, 0x40, 0x36, 0x6e, 0x63, 0xf5, 0x89, 0xb7, 0x7f, 0x7e, 0x7b, 0xe6, 0x1b, 0xcd, 0xcc, 0xc2,
331 0xbb, 0x5c, 0xa9, 0x7c, 0x23, 0x17, 0xb9, 0xda, 0x88, 0x32, 0x5f, 0x28, 0x9d, 0x5f, 0x88, 0xaa,
332 0x92, 0x65, 0x5e, 0x94, 0xf2, 0xa2, 0x28, 0x6b, 0xa9, 0x4b, 0xb1, 0xb9, 0xd0, 0x72, 0xab, 0x6a,
333 0xc9, 0x45, 0x55, 0xf4, 0xe4, 0xa2, 0xd2, 0xaa, 0x56, 0x18, 0xf6, 0xce, 0xec, 0x27, 0x8c, 0x98,
334 0xfc, 0xf6, 0x5d, 0xee, 0x6a, 0xfc, 0x12, 0xec, 0x9d, 0xd4, 0xb7, 0x45, 0x26, 0x79, 0x29, 0xb6,
335 0xd2, 0x31, 0xa7, 0xe6, 0xdc, 0x62, 0x93, 0xce, 0x0b, 0xc5, 0x56, 0xe2, 0x33, 0x38, 0xdc, 0xca,
336 0xfa, 0x8b, 0x5a, 0x3b, 0x07, 0xed, 0xc7, 0x2e, 0xc2, 0x0e, 0x8c, 0xf4, 0xbf, 0x2a, 0xce, 0x60,
337 0x6a, 0xce, 0x6d, 0x76, 0x17, 0xe2, 0x17, 0x00, 0x9d, 0xe4, 0xc5, 0xda, 0x19, 0x4e, 0x8d, 0xb9,
338 0xc5, 0xac, 0xce, 0xf1, 0xd7, 0xb3, 0xb7, 0x80, 0x48, 0x55, 0x6d, 0x8a, 0x4c, 0xd4, 0x85, 0x2a,
339 0xa9, 0xd6, 0x4a, 0x63, 0x0c, 0x83, 0x4c, 0xad, 0xa5, 0x63, 0x4c, 0xcd, 0xf9, 0x90, 0xb5, 0xba,
340 0x01, 0xaf, 0x65, 0x2d, 0x8a, 0x4d, 0xd7, 0x55, 0x17, 0xcd, 0x7e, 0x9b, 0x30, 0x66, 0x55, 0xf6,
341 0x7f, 0x89, 0x46, 0x2f, 0xf1, 0x97, 0x09, 0x56, 0x9b, 0xe5, 0x36, 0x7f, 0x4d, 0x60, 0x94, 0x86,
342 0x1f, 0xc2, 0xe8, 0x63, 0x88, 0x1e, 0x61, 0x0c, 0xc7, 0x2e, 0x09, 0x02, 0x1e, 0x46, 0x09, 0xbf,
343 0x8c, 0xd2, 0xd0, 0x43, 0x06, 0x7e, 0x0c, 0x93, 0x15, 0x61, 0x31, 0xe5, 0x94, 0xb1, 0x88, 0x21,
344 0x13, 0x9f, 0x01, 0x8e, 0xa9, 0x9b, 0x32, 0x3f, 0xb9, 0xe1, 0xd7, 0x7e, 0x14, 0x90, 0xc4, 0x8f,
345 0x42, 0x74, 0x80, 0x8f, 0x01, 0xa2, 0x6b, 0xca, 0xf8, 0x55, 0x1a, 0x25, 0x04, 0x0d, 0xf0, 0x53,
346 0x38, 0x61, 0xf4, 0x2a, 0xa5, 0x71, 0xc2, 0x93, 0x28, 0xe2, 0x01, 0x61, 0xef, 0x29, 0x1a, 0xe2,
347 0x67, 0xf0, 0xc4, 0x25, 0x2b, 0xb2, 0xf4, 0x83, 0xa6, 0x80, 0xe7, 0xc7, 0x64, 0x19, 0x50, 0x0f,
348 0x1d, 0xe2, 0x53, 0x40, 0x97, 0x94, 0x24, 0x29, 0xa3, 0x7b, 0x77, 0xd4, 0xe0, 0x97, 0xc4, 0xe3,
349 0x5d, 0x25, 0x34, 0x6e, 0xf0, 0x8c, 0xc6, 0xab, 0x28, 0x8c, 0x69, 0xaf, 0xae, 0x85, 0x8f, 0xc0,
350 0x72, 0x49, 0xe8, 0xd2, 0xa0, 0xc9, 0x03, 0x8c, 0xc0, 0x66, 0x74, 0x15, 0x90, 0x9b, 0xae, 0xef,
351 0x49, 0xd3, 0x8f, 0x47, 0x89, 0x17, 0xf8, 0x21, 0xe5, 0xf4, 0x93, 0x4b, 0xa9, 0x47, 0x3d, 0x64,
352 0xcf, 0xfe, 0x18, 0x30, 0x66, 0x72, 0x57, 0xa9, 0x72, 0x27, 0xf1, 0x73, 0x18, 0xeb, 0x4e, 0x3b,
353 0xc6, 0xd4, 0x98, 0xdb, 0xec, 0x3e, 0xc6, 0xe7, 0x60, 0xc9, 0x1f, 0x99, 0xac, 0x9a, 0x75, 0xb5,
354 0x23, 0xb5, 0xd9, 0xde, 0xc0, 0x3e, 0x9c, 0x88, 0xfd, 0x3a, 0xb9, 0x6c, 0x06, 0xec, 0x1c, 0x4c,
355 0x8d, 0xf9, 0xe4, 0xcd, 0xf9, 0xa2, 0x77, 0x87, 0x0f, 0x77, 0xce, 0x90, 0x78, 0x78, 0x05, 0xaf,
356 0xe0, 0xf8, 0xab, 0xb8, 0x15, 0x7c, 0x4f, 0x1b, 0xb4, 0xb4, 0xa3, 0xc6, 0xa5, 0xf7, 0xc4, 0xd7,
357 0x60, 0xe9, 0x2a, 0xeb, 0x48, 0xc3, 0x96, 0x74, 0xda, 0x27, 0xdd, 0x1d, 0x07, 0x1b, 0xeb, 0x4e,
358 0x2d, 0xed, 0xcf, 0xbd, 0x07, 0xf0, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xd1, 0x0f, 0x22, 0x4f,
359 0x03, 0x00, 0x00,
360 }
0 syntax = "proto2";
1 option go_package = "remote_api";
2
3 package remote_api;
4
5 message Request {
6 required string service_name = 2;
7 required string method = 3;
8 required bytes request = 4;
9 optional string request_id = 5;
10 }
11
12 message ApplicationError {
13 required int32 code = 1;
14 required string detail = 2;
15 }
16
17 message RpcError {
18 enum ErrorCode {
19 UNKNOWN = 0;
20 CALL_NOT_FOUND = 1;
21 PARSE_ERROR = 2;
22 SECURITY_VIOLATION = 3;
23 OVER_QUOTA = 4;
24 REQUEST_TOO_LARGE = 5;
25 CAPABILITY_DISABLED = 6;
26 FEATURE_DISABLED = 7;
27 BAD_REQUEST = 8;
28 RESPONSE_TOO_LARGE = 9;
29 CANCELLED = 10;
30 REPLAY_ERROR = 11;
31 DEADLINE_EXCEEDED = 12;
32 }
33 required int32 code = 1;
34 optional string detail = 2;
35 }
36
37 message Response {
38 optional bytes response = 1;
39 optional bytes exception = 2;
40 optional ApplicationError application_error = 3;
41 optional bytes java_exception = 4;
42 optional RpcError rpc_error = 5;
43 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/system/system_service.proto
2
3 package system
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type SystemServiceError_ErrorCode int32
21
22 const (
23 SystemServiceError_OK SystemServiceError_ErrorCode = 0
24 SystemServiceError_INTERNAL_ERROR SystemServiceError_ErrorCode = 1
25 SystemServiceError_BACKEND_REQUIRED SystemServiceError_ErrorCode = 2
26 SystemServiceError_LIMIT_REACHED SystemServiceError_ErrorCode = 3
27 )
28
29 var SystemServiceError_ErrorCode_name = map[int32]string{
30 0: "OK",
31 1: "INTERNAL_ERROR",
32 2: "BACKEND_REQUIRED",
33 3: "LIMIT_REACHED",
34 }
35 var SystemServiceError_ErrorCode_value = map[string]int32{
36 "OK": 0,
37 "INTERNAL_ERROR": 1,
38 "BACKEND_REQUIRED": 2,
39 "LIMIT_REACHED": 3,
40 }
41
42 func (x SystemServiceError_ErrorCode) Enum() *SystemServiceError_ErrorCode {
43 p := new(SystemServiceError_ErrorCode)
44 *p = x
45 return p
46 }
47 func (x SystemServiceError_ErrorCode) String() string {
48 return proto.EnumName(SystemServiceError_ErrorCode_name, int32(x))
49 }
50 func (x *SystemServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
51 value, err := proto.UnmarshalJSONEnum(SystemServiceError_ErrorCode_value, data, "SystemServiceError_ErrorCode")
52 if err != nil {
53 return err
54 }
55 *x = SystemServiceError_ErrorCode(value)
56 return nil
57 }
58 func (SystemServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
59 return fileDescriptor_system_service_ccf41ec210fc59eb, []int{0, 0}
60 }
61
62 type SystemServiceError struct {
63 XXX_NoUnkeyedLiteral struct{} `json:"-"`
64 XXX_unrecognized []byte `json:"-"`
65 XXX_sizecache int32 `json:"-"`
66 }
67
68 func (m *SystemServiceError) Reset() { *m = SystemServiceError{} }
69 func (m *SystemServiceError) String() string { return proto.CompactTextString(m) }
70 func (*SystemServiceError) ProtoMessage() {}
71 func (*SystemServiceError) Descriptor() ([]byte, []int) {
72 return fileDescriptor_system_service_ccf41ec210fc59eb, []int{0}
73 }
74 func (m *SystemServiceError) XXX_Unmarshal(b []byte) error {
75 return xxx_messageInfo_SystemServiceError.Unmarshal(m, b)
76 }
77 func (m *SystemServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
78 return xxx_messageInfo_SystemServiceError.Marshal(b, m, deterministic)
79 }
80 func (dst *SystemServiceError) XXX_Merge(src proto.Message) {
81 xxx_messageInfo_SystemServiceError.Merge(dst, src)
82 }
83 func (m *SystemServiceError) XXX_Size() int {
84 return xxx_messageInfo_SystemServiceError.Size(m)
85 }
86 func (m *SystemServiceError) XXX_DiscardUnknown() {
87 xxx_messageInfo_SystemServiceError.DiscardUnknown(m)
88 }
89
90 var xxx_messageInfo_SystemServiceError proto.InternalMessageInfo
91
92 type SystemStat struct {
93 // Instaneous value of this stat.
94 Current *float64 `protobuf:"fixed64,1,opt,name=current" json:"current,omitempty"`
95 // Average over time, if this stat has an instaneous value.
96 Average1M *float64 `protobuf:"fixed64,3,opt,name=average1m" json:"average1m,omitempty"`
97 Average10M *float64 `protobuf:"fixed64,4,opt,name=average10m" json:"average10m,omitempty"`
98 // Total value, if the stat accumulates over time.
99 Total *float64 `protobuf:"fixed64,2,opt,name=total" json:"total,omitempty"`
100 // Rate over time, if this stat accumulates.
101 Rate1M *float64 `protobuf:"fixed64,5,opt,name=rate1m" json:"rate1m,omitempty"`
102 Rate10M *float64 `protobuf:"fixed64,6,opt,name=rate10m" json:"rate10m,omitempty"`
103 XXX_NoUnkeyedLiteral struct{} `json:"-"`
104 XXX_unrecognized []byte `json:"-"`
105 XXX_sizecache int32 `json:"-"`
106 }
107
108 func (m *SystemStat) Reset() { *m = SystemStat{} }
109 func (m *SystemStat) String() string { return proto.CompactTextString(m) }
110 func (*SystemStat) ProtoMessage() {}
111 func (*SystemStat) Descriptor() ([]byte, []int) {
112 return fileDescriptor_system_service_ccf41ec210fc59eb, []int{1}
113 }
114 func (m *SystemStat) XXX_Unmarshal(b []byte) error {
115 return xxx_messageInfo_SystemStat.Unmarshal(m, b)
116 }
117 func (m *SystemStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
118 return xxx_messageInfo_SystemStat.Marshal(b, m, deterministic)
119 }
120 func (dst *SystemStat) XXX_Merge(src proto.Message) {
121 xxx_messageInfo_SystemStat.Merge(dst, src)
122 }
123 func (m *SystemStat) XXX_Size() int {
124 return xxx_messageInfo_SystemStat.Size(m)
125 }
126 func (m *SystemStat) XXX_DiscardUnknown() {
127 xxx_messageInfo_SystemStat.DiscardUnknown(m)
128 }
129
130 var xxx_messageInfo_SystemStat proto.InternalMessageInfo
131
132 func (m *SystemStat) GetCurrent() float64 {
133 if m != nil && m.Current != nil {
134 return *m.Current
135 }
136 return 0
137 }
138
139 func (m *SystemStat) GetAverage1M() float64 {
140 if m != nil && m.Average1M != nil {
141 return *m.Average1M
142 }
143 return 0
144 }
145
146 func (m *SystemStat) GetAverage10M() float64 {
147 if m != nil && m.Average10M != nil {
148 return *m.Average10M
149 }
150 return 0
151 }
152
153 func (m *SystemStat) GetTotal() float64 {
154 if m != nil && m.Total != nil {
155 return *m.Total
156 }
157 return 0
158 }
159
160 func (m *SystemStat) GetRate1M() float64 {
161 if m != nil && m.Rate1M != nil {
162 return *m.Rate1M
163 }
164 return 0
165 }
166
167 func (m *SystemStat) GetRate10M() float64 {
168 if m != nil && m.Rate10M != nil {
169 return *m.Rate10M
170 }
171 return 0
172 }
173
174 type GetSystemStatsRequest struct {
175 XXX_NoUnkeyedLiteral struct{} `json:"-"`
176 XXX_unrecognized []byte `json:"-"`
177 XXX_sizecache int32 `json:"-"`
178 }
179
180 func (m *GetSystemStatsRequest) Reset() { *m = GetSystemStatsRequest{} }
181 func (m *GetSystemStatsRequest) String() string { return proto.CompactTextString(m) }
182 func (*GetSystemStatsRequest) ProtoMessage() {}
183 func (*GetSystemStatsRequest) Descriptor() ([]byte, []int) {
184 return fileDescriptor_system_service_ccf41ec210fc59eb, []int{2}
185 }
186 func (m *GetSystemStatsRequest) XXX_Unmarshal(b []byte) error {
187 return xxx_messageInfo_GetSystemStatsRequest.Unmarshal(m, b)
188 }
189 func (m *GetSystemStatsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
190 return xxx_messageInfo_GetSystemStatsRequest.Marshal(b, m, deterministic)
191 }
192 func (dst *GetSystemStatsRequest) XXX_Merge(src proto.Message) {
193 xxx_messageInfo_GetSystemStatsRequest.Merge(dst, src)
194 }
195 func (m *GetSystemStatsRequest) XXX_Size() int {
196 return xxx_messageInfo_GetSystemStatsRequest.Size(m)
197 }
198 func (m *GetSystemStatsRequest) XXX_DiscardUnknown() {
199 xxx_messageInfo_GetSystemStatsRequest.DiscardUnknown(m)
200 }
201
202 var xxx_messageInfo_GetSystemStatsRequest proto.InternalMessageInfo
203
204 type GetSystemStatsResponse struct {
205 // CPU used by this instance, in mcycles.
206 Cpu *SystemStat `protobuf:"bytes,1,opt,name=cpu" json:"cpu,omitempty"`
207 // Physical memory (RAM) used by this instance, in megabytes.
208 Memory *SystemStat `protobuf:"bytes,2,opt,name=memory" json:"memory,omitempty"`
209 XXX_NoUnkeyedLiteral struct{} `json:"-"`
210 XXX_unrecognized []byte `json:"-"`
211 XXX_sizecache int32 `json:"-"`
212 }
213
214 func (m *GetSystemStatsResponse) Reset() { *m = GetSystemStatsResponse{} }
215 func (m *GetSystemStatsResponse) String() string { return proto.CompactTextString(m) }
216 func (*GetSystemStatsResponse) ProtoMessage() {}
217 func (*GetSystemStatsResponse) Descriptor() ([]byte, []int) {
218 return fileDescriptor_system_service_ccf41ec210fc59eb, []int{3}
219 }
220 func (m *GetSystemStatsResponse) XXX_Unmarshal(b []byte) error {
221 return xxx_messageInfo_GetSystemStatsResponse.Unmarshal(m, b)
222 }
223 func (m *GetSystemStatsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
224 return xxx_messageInfo_GetSystemStatsResponse.Marshal(b, m, deterministic)
225 }
226 func (dst *GetSystemStatsResponse) XXX_Merge(src proto.Message) {
227 xxx_messageInfo_GetSystemStatsResponse.Merge(dst, src)
228 }
229 func (m *GetSystemStatsResponse) XXX_Size() int {
230 return xxx_messageInfo_GetSystemStatsResponse.Size(m)
231 }
232 func (m *GetSystemStatsResponse) XXX_DiscardUnknown() {
233 xxx_messageInfo_GetSystemStatsResponse.DiscardUnknown(m)
234 }
235
236 var xxx_messageInfo_GetSystemStatsResponse proto.InternalMessageInfo
237
238 func (m *GetSystemStatsResponse) GetCpu() *SystemStat {
239 if m != nil {
240 return m.Cpu
241 }
242 return nil
243 }
244
245 func (m *GetSystemStatsResponse) GetMemory() *SystemStat {
246 if m != nil {
247 return m.Memory
248 }
249 return nil
250 }
251
252 type StartBackgroundRequestRequest struct {
253 XXX_NoUnkeyedLiteral struct{} `json:"-"`
254 XXX_unrecognized []byte `json:"-"`
255 XXX_sizecache int32 `json:"-"`
256 }
257
258 func (m *StartBackgroundRequestRequest) Reset() { *m = StartBackgroundRequestRequest{} }
259 func (m *StartBackgroundRequestRequest) String() string { return proto.CompactTextString(m) }
260 func (*StartBackgroundRequestRequest) ProtoMessage() {}
261 func (*StartBackgroundRequestRequest) Descriptor() ([]byte, []int) {
262 return fileDescriptor_system_service_ccf41ec210fc59eb, []int{4}
263 }
264 func (m *StartBackgroundRequestRequest) XXX_Unmarshal(b []byte) error {
265 return xxx_messageInfo_StartBackgroundRequestRequest.Unmarshal(m, b)
266 }
267 func (m *StartBackgroundRequestRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
268 return xxx_messageInfo_StartBackgroundRequestRequest.Marshal(b, m, deterministic)
269 }
270 func (dst *StartBackgroundRequestRequest) XXX_Merge(src proto.Message) {
271 xxx_messageInfo_StartBackgroundRequestRequest.Merge(dst, src)
272 }
273 func (m *StartBackgroundRequestRequest) XXX_Size() int {
274 return xxx_messageInfo_StartBackgroundRequestRequest.Size(m)
275 }
276 func (m *StartBackgroundRequestRequest) XXX_DiscardUnknown() {
277 xxx_messageInfo_StartBackgroundRequestRequest.DiscardUnknown(m)
278 }
279
280 var xxx_messageInfo_StartBackgroundRequestRequest proto.InternalMessageInfo
281
282 type StartBackgroundRequestResponse struct {
283 // Every /_ah/background request will have an X-AppEngine-BackgroundRequest
284 // header, whose value will be equal to this parameter, the request_id.
285 RequestId *string `protobuf:"bytes,1,opt,name=request_id,json=requestId" json:"request_id,omitempty"`
286 XXX_NoUnkeyedLiteral struct{} `json:"-"`
287 XXX_unrecognized []byte `json:"-"`
288 XXX_sizecache int32 `json:"-"`
289 }
290
291 func (m *StartBackgroundRequestResponse) Reset() { *m = StartBackgroundRequestResponse{} }
292 func (m *StartBackgroundRequestResponse) String() string { return proto.CompactTextString(m) }
293 func (*StartBackgroundRequestResponse) ProtoMessage() {}
294 func (*StartBackgroundRequestResponse) Descriptor() ([]byte, []int) {
295 return fileDescriptor_system_service_ccf41ec210fc59eb, []int{5}
296 }
297 func (m *StartBackgroundRequestResponse) XXX_Unmarshal(b []byte) error {
298 return xxx_messageInfo_StartBackgroundRequestResponse.Unmarshal(m, b)
299 }
300 func (m *StartBackgroundRequestResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
301 return xxx_messageInfo_StartBackgroundRequestResponse.Marshal(b, m, deterministic)
302 }
303 func (dst *StartBackgroundRequestResponse) XXX_Merge(src proto.Message) {
304 xxx_messageInfo_StartBackgroundRequestResponse.Merge(dst, src)
305 }
306 func (m *StartBackgroundRequestResponse) XXX_Size() int {
307 return xxx_messageInfo_StartBackgroundRequestResponse.Size(m)
308 }
309 func (m *StartBackgroundRequestResponse) XXX_DiscardUnknown() {
310 xxx_messageInfo_StartBackgroundRequestResponse.DiscardUnknown(m)
311 }
312
313 var xxx_messageInfo_StartBackgroundRequestResponse proto.InternalMessageInfo
314
315 func (m *StartBackgroundRequestResponse) GetRequestId() string {
316 if m != nil && m.RequestId != nil {
317 return *m.RequestId
318 }
319 return ""
320 }
321
322 func init() {
323 proto.RegisterType((*SystemServiceError)(nil), "appengine.SystemServiceError")
324 proto.RegisterType((*SystemStat)(nil), "appengine.SystemStat")
325 proto.RegisterType((*GetSystemStatsRequest)(nil), "appengine.GetSystemStatsRequest")
326 proto.RegisterType((*GetSystemStatsResponse)(nil), "appengine.GetSystemStatsResponse")
327 proto.RegisterType((*StartBackgroundRequestRequest)(nil), "appengine.StartBackgroundRequestRequest")
328 proto.RegisterType((*StartBackgroundRequestResponse)(nil), "appengine.StartBackgroundRequestResponse")
329 }
330
331 func init() {
332 proto.RegisterFile("google.golang.org/appengine/v2/internal/system/system_service.proto", fileDescriptor_system_service_ccf41ec210fc59eb)
333 }
334
335 var fileDescriptor_system_service_ccf41ec210fc59eb = []byte{
336 // 377 bytes of a gzipped FileDescriptorProto
337 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x4f, 0x8f, 0x93, 0x40,
338 0x18, 0xc6, 0xa5, 0x75, 0x51, 0x5e, 0xa3, 0xc1, 0xc9, 0xee, 0xca, 0xc1, 0x5d, 0x0d, 0x17, 0xbd,
339 0x48, 0x57, 0xbf, 0x80, 0xf6, 0xcf, 0x44, 0x49, 0x6b, 0xab, 0xd3, 0x7a, 0xf1, 0x42, 0x26, 0xf0,
340 0x3a, 0x21, 0xc2, 0x0c, 0x0e, 0x43, 0x93, 0x7e, 0x27, 0x3f, 0xa4, 0xe9, 0x30, 0x6d, 0xcd, 0x26,
341 0x3d, 0x31, 0xcf, 0xf3, 0xfc, 0x02, 0x3f, 0x08, 0xf0, 0x49, 0x28, 0x25, 0x2a, 0x4c, 0x84, 0xaa,
342 0xb8, 0x14, 0x89, 0xd2, 0x62, 0xc4, 0x9b, 0x06, 0xa5, 0x28, 0x25, 0x8e, 0x4a, 0x69, 0x50, 0x4b,
343 0x5e, 0x8d, 0xda, 0x5d, 0x6b, 0xb0, 0x76, 0x97, 0xac, 0x45, 0xbd, 0x2d, 0x73, 0x4c, 0x1a, 0xad,
344 0x8c, 0x22, 0xc1, 0x91, 0x8f, 0x7f, 0x01, 0x59, 0x5b, 0x64, 0xdd, 0x13, 0x54, 0x6b, 0xa5, 0xe3,
345 0x6f, 0x10, 0xd8, 0xc3, 0x54, 0x15, 0x48, 0x7c, 0x18, 0xac, 0xe6, 0xe1, 0x03, 0x42, 0xe0, 0x59,
346 0xba, 0xdc, 0x50, 0xb6, 0x1c, 0x2f, 0x32, 0xca, 0xd8, 0x8a, 0x85, 0x1e, 0xb9, 0x84, 0x70, 0x32,
347 0x9e, 0xce, 0xe9, 0x72, 0x96, 0x31, 0xfa, 0xfd, 0x47, 0xca, 0xe8, 0x2c, 0x1c, 0x90, 0xe7, 0xf0,
348 0x74, 0x91, 0x7e, 0x4d, 0x37, 0x19, 0xa3, 0xe3, 0xe9, 0x17, 0x3a, 0x0b, 0x87, 0xf1, 0x5f, 0x0f,
349 0xc0, 0x3d, 0xc8, 0x70, 0x43, 0x22, 0x78, 0x94, 0x77, 0x5a, 0xa3, 0x34, 0x91, 0xf7, 0xda, 0x7b,
350 0xeb, 0xb1, 0x43, 0x24, 0x2f, 0x21, 0xe0, 0x5b, 0xd4, 0x5c, 0xe0, 0xfb, 0x3a, 0x1a, 0xda, 0xed,
351 0x54, 0x90, 0x5b, 0x80, 0x43, 0xb8, 0xab, 0xa3, 0x87, 0x76, 0xfe, 0xaf, 0x21, 0x97, 0x70, 0x61,
352 0x94, 0xe1, 0x55, 0x34, 0xb0, 0x53, 0x1f, 0xc8, 0x35, 0xf8, 0x9a, 0x9b, 0xfd, 0x0d, 0x2f, 0x6c,
353 0xed, 0xd2, 0xde, 0xc2, 0x9e, 0xee, 0xea, 0xc8, 0xef, 0x2d, 0x5c, 0x8c, 0x5f, 0xc0, 0xd5, 0x67,
354 0x34, 0x27, 0xe1, 0x96, 0xe1, 0x9f, 0x0e, 0x5b, 0x13, 0x37, 0x70, 0x7d, 0x7f, 0x68, 0x1b, 0x25,
355 0x5b, 0x24, 0x6f, 0x60, 0x98, 0x37, 0x9d, 0x7d, 0x9d, 0x27, 0x1f, 0xae, 0x92, 0xe3, 0x27, 0x4e,
356 0x4e, 0x30, 0xdb, 0x13, 0xe4, 0x1d, 0xf8, 0x35, 0xd6, 0x4a, 0xef, 0xac, 0xe4, 0x59, 0xd6, 0x41,
357 0xf1, 0x2b, 0xb8, 0x59, 0x1b, 0xae, 0xcd, 0x84, 0xe7, 0xbf, 0x85, 0x56, 0x9d, 0x2c, 0x9c, 0xcb,
358 0x41, 0xe9, 0x23, 0xdc, 0x9e, 0x03, 0x9c, 0xda, 0x0d, 0x80, 0xee, 0xab, 0xac, 0x2c, 0xac, 0x61,
359 0xc0, 0x02, 0xd7, 0xa4, 0xc5, 0xe4, 0xf1, 0x4f, 0xbf, 0xff, 0x4d, 0xfe, 0x05, 0x00, 0x00, 0xff,
360 0xff, 0x56, 0x5d, 0x5e, 0xc3, 0x5b, 0x02, 0x00, 0x00,
361 }
0 syntax = "proto2";
1 option go_package = "system";
2
3 package appengine;
4
5 message SystemServiceError {
6 enum ErrorCode {
7 OK = 0;
8 INTERNAL_ERROR = 1;
9 BACKEND_REQUIRED = 2;
10 LIMIT_REACHED = 3;
11 }
12 }
13
14 message SystemStat {
15 // Instaneous value of this stat.
16 optional double current = 1;
17
18 // Average over time, if this stat has an instaneous value.
19 optional double average1m = 3;
20 optional double average10m = 4;
21
22 // Total value, if the stat accumulates over time.
23 optional double total = 2;
24
25 // Rate over time, if this stat accumulates.
26 optional double rate1m = 5;
27 optional double rate10m = 6;
28 }
29
30 message GetSystemStatsRequest {
31 }
32
33 message GetSystemStatsResponse {
34 // CPU used by this instance, in mcycles.
35 optional SystemStat cpu = 1;
36
37 // Physical memory (RAM) used by this instance, in megabytes.
38 optional SystemStat memory = 2;
39 }
40
41 message StartBackgroundRequestRequest {
42 }
43
44 message StartBackgroundRequestResponse {
45 // Every /_ah/background request will have an X-AppEngine-BackgroundRequest
46 // header, whose value will be equal to this parameter, the request_id.
47 optional string request_id = 1;
48 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/taskqueue/taskqueue_service.proto
2
3 package taskqueue
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8 import datastore "google.golang.org/appengine/v2/internal/datastore"
9
10 // Reference imports to suppress errors if they are not otherwise used.
11 var _ = proto.Marshal
12 var _ = fmt.Errorf
13 var _ = math.Inf
14
15 // This is a compile-time assertion to ensure that this generated file
16 // is compatible with the proto package it is being compiled against.
17 // A compilation error at this line likely means your copy of the
18 // proto package needs to be updated.
19 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
20
21 type TaskQueueServiceError_ErrorCode int32
22
23 const (
24 TaskQueueServiceError_OK TaskQueueServiceError_ErrorCode = 0
25 TaskQueueServiceError_UNKNOWN_QUEUE TaskQueueServiceError_ErrorCode = 1
26 TaskQueueServiceError_TRANSIENT_ERROR TaskQueueServiceError_ErrorCode = 2
27 TaskQueueServiceError_INTERNAL_ERROR TaskQueueServiceError_ErrorCode = 3
28 TaskQueueServiceError_TASK_TOO_LARGE TaskQueueServiceError_ErrorCode = 4
29 TaskQueueServiceError_INVALID_TASK_NAME TaskQueueServiceError_ErrorCode = 5
30 TaskQueueServiceError_INVALID_QUEUE_NAME TaskQueueServiceError_ErrorCode = 6
31 TaskQueueServiceError_INVALID_URL TaskQueueServiceError_ErrorCode = 7
32 TaskQueueServiceError_INVALID_QUEUE_RATE TaskQueueServiceError_ErrorCode = 8
33 TaskQueueServiceError_PERMISSION_DENIED TaskQueueServiceError_ErrorCode = 9
34 TaskQueueServiceError_TASK_ALREADY_EXISTS TaskQueueServiceError_ErrorCode = 10
35 TaskQueueServiceError_TOMBSTONED_TASK TaskQueueServiceError_ErrorCode = 11
36 TaskQueueServiceError_INVALID_ETA TaskQueueServiceError_ErrorCode = 12
37 TaskQueueServiceError_INVALID_REQUEST TaskQueueServiceError_ErrorCode = 13
38 TaskQueueServiceError_UNKNOWN_TASK TaskQueueServiceError_ErrorCode = 14
39 TaskQueueServiceError_TOMBSTONED_QUEUE TaskQueueServiceError_ErrorCode = 15
40 TaskQueueServiceError_DUPLICATE_TASK_NAME TaskQueueServiceError_ErrorCode = 16
41 TaskQueueServiceError_SKIPPED TaskQueueServiceError_ErrorCode = 17
42 TaskQueueServiceError_TOO_MANY_TASKS TaskQueueServiceError_ErrorCode = 18
43 TaskQueueServiceError_INVALID_PAYLOAD TaskQueueServiceError_ErrorCode = 19
44 TaskQueueServiceError_INVALID_RETRY_PARAMETERS TaskQueueServiceError_ErrorCode = 20
45 TaskQueueServiceError_INVALID_QUEUE_MODE TaskQueueServiceError_ErrorCode = 21
46 TaskQueueServiceError_ACL_LOOKUP_ERROR TaskQueueServiceError_ErrorCode = 22
47 TaskQueueServiceError_TRANSACTIONAL_REQUEST_TOO_LARGE TaskQueueServiceError_ErrorCode = 23
48 TaskQueueServiceError_INCORRECT_CREATOR_NAME TaskQueueServiceError_ErrorCode = 24
49 TaskQueueServiceError_TASK_LEASE_EXPIRED TaskQueueServiceError_ErrorCode = 25
50 TaskQueueServiceError_QUEUE_PAUSED TaskQueueServiceError_ErrorCode = 26
51 TaskQueueServiceError_INVALID_TAG TaskQueueServiceError_ErrorCode = 27
52 // Reserved range for the Datastore error codes.
53 // Original Datastore error code is shifted by DATASTORE_ERROR offset.
54 TaskQueueServiceError_DATASTORE_ERROR TaskQueueServiceError_ErrorCode = 10000
55 )
56
57 var TaskQueueServiceError_ErrorCode_name = map[int32]string{
58 0: "OK",
59 1: "UNKNOWN_QUEUE",
60 2: "TRANSIENT_ERROR",
61 3: "INTERNAL_ERROR",
62 4: "TASK_TOO_LARGE",
63 5: "INVALID_TASK_NAME",
64 6: "INVALID_QUEUE_NAME",
65 7: "INVALID_URL",
66 8: "INVALID_QUEUE_RATE",
67 9: "PERMISSION_DENIED",
68 10: "TASK_ALREADY_EXISTS",
69 11: "TOMBSTONED_TASK",
70 12: "INVALID_ETA",
71 13: "INVALID_REQUEST",
72 14: "UNKNOWN_TASK",
73 15: "TOMBSTONED_QUEUE",
74 16: "DUPLICATE_TASK_NAME",
75 17: "SKIPPED",
76 18: "TOO_MANY_TASKS",
77 19: "INVALID_PAYLOAD",
78 20: "INVALID_RETRY_PARAMETERS",
79 21: "INVALID_QUEUE_MODE",
80 22: "ACL_LOOKUP_ERROR",
81 23: "TRANSACTIONAL_REQUEST_TOO_LARGE",
82 24: "INCORRECT_CREATOR_NAME",
83 25: "TASK_LEASE_EXPIRED",
84 26: "QUEUE_PAUSED",
85 27: "INVALID_TAG",
86 10000: "DATASTORE_ERROR",
87 }
88 var TaskQueueServiceError_ErrorCode_value = map[string]int32{
89 "OK": 0,
90 "UNKNOWN_QUEUE": 1,
91 "TRANSIENT_ERROR": 2,
92 "INTERNAL_ERROR": 3,
93 "TASK_TOO_LARGE": 4,
94 "INVALID_TASK_NAME": 5,
95 "INVALID_QUEUE_NAME": 6,
96 "INVALID_URL": 7,
97 "INVALID_QUEUE_RATE": 8,
98 "PERMISSION_DENIED": 9,
99 "TASK_ALREADY_EXISTS": 10,
100 "TOMBSTONED_TASK": 11,
101 "INVALID_ETA": 12,
102 "INVALID_REQUEST": 13,
103 "UNKNOWN_TASK": 14,
104 "TOMBSTONED_QUEUE": 15,
105 "DUPLICATE_TASK_NAME": 16,
106 "SKIPPED": 17,
107 "TOO_MANY_TASKS": 18,
108 "INVALID_PAYLOAD": 19,
109 "INVALID_RETRY_PARAMETERS": 20,
110 "INVALID_QUEUE_MODE": 21,
111 "ACL_LOOKUP_ERROR": 22,
112 "TRANSACTIONAL_REQUEST_TOO_LARGE": 23,
113 "INCORRECT_CREATOR_NAME": 24,
114 "TASK_LEASE_EXPIRED": 25,
115 "QUEUE_PAUSED": 26,
116 "INVALID_TAG": 27,
117 "DATASTORE_ERROR": 10000,
118 }
119
120 func (x TaskQueueServiceError_ErrorCode) Enum() *TaskQueueServiceError_ErrorCode {
121 p := new(TaskQueueServiceError_ErrorCode)
122 *p = x
123 return p
124 }
125 func (x TaskQueueServiceError_ErrorCode) String() string {
126 return proto.EnumName(TaskQueueServiceError_ErrorCode_name, int32(x))
127 }
128 func (x *TaskQueueServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
129 value, err := proto.UnmarshalJSONEnum(TaskQueueServiceError_ErrorCode_value, data, "TaskQueueServiceError_ErrorCode")
130 if err != nil {
131 return err
132 }
133 *x = TaskQueueServiceError_ErrorCode(value)
134 return nil
135 }
136 func (TaskQueueServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
137 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{0, 0}
138 }
139
140 type TaskQueueMode_Mode int32
141
142 const (
143 TaskQueueMode_PUSH TaskQueueMode_Mode = 0
144 TaskQueueMode_PULL TaskQueueMode_Mode = 1
145 )
146
147 var TaskQueueMode_Mode_name = map[int32]string{
148 0: "PUSH",
149 1: "PULL",
150 }
151 var TaskQueueMode_Mode_value = map[string]int32{
152 "PUSH": 0,
153 "PULL": 1,
154 }
155
156 func (x TaskQueueMode_Mode) Enum() *TaskQueueMode_Mode {
157 p := new(TaskQueueMode_Mode)
158 *p = x
159 return p
160 }
161 func (x TaskQueueMode_Mode) String() string {
162 return proto.EnumName(TaskQueueMode_Mode_name, int32(x))
163 }
164 func (x *TaskQueueMode_Mode) UnmarshalJSON(data []byte) error {
165 value, err := proto.UnmarshalJSONEnum(TaskQueueMode_Mode_value, data, "TaskQueueMode_Mode")
166 if err != nil {
167 return err
168 }
169 *x = TaskQueueMode_Mode(value)
170 return nil
171 }
172 func (TaskQueueMode_Mode) EnumDescriptor() ([]byte, []int) {
173 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{5, 0}
174 }
175
176 type TaskQueueAddRequest_RequestMethod int32
177
178 const (
179 TaskQueueAddRequest_GET TaskQueueAddRequest_RequestMethod = 1
180 TaskQueueAddRequest_POST TaskQueueAddRequest_RequestMethod = 2
181 TaskQueueAddRequest_HEAD TaskQueueAddRequest_RequestMethod = 3
182 TaskQueueAddRequest_PUT TaskQueueAddRequest_RequestMethod = 4
183 TaskQueueAddRequest_DELETE TaskQueueAddRequest_RequestMethod = 5
184 )
185
186 var TaskQueueAddRequest_RequestMethod_name = map[int32]string{
187 1: "GET",
188 2: "POST",
189 3: "HEAD",
190 4: "PUT",
191 5: "DELETE",
192 }
193 var TaskQueueAddRequest_RequestMethod_value = map[string]int32{
194 "GET": 1,
195 "POST": 2,
196 "HEAD": 3,
197 "PUT": 4,
198 "DELETE": 5,
199 }
200
201 func (x TaskQueueAddRequest_RequestMethod) Enum() *TaskQueueAddRequest_RequestMethod {
202 p := new(TaskQueueAddRequest_RequestMethod)
203 *p = x
204 return p
205 }
206 func (x TaskQueueAddRequest_RequestMethod) String() string {
207 return proto.EnumName(TaskQueueAddRequest_RequestMethod_name, int32(x))
208 }
209 func (x *TaskQueueAddRequest_RequestMethod) UnmarshalJSON(data []byte) error {
210 value, err := proto.UnmarshalJSONEnum(TaskQueueAddRequest_RequestMethod_value, data, "TaskQueueAddRequest_RequestMethod")
211 if err != nil {
212 return err
213 }
214 *x = TaskQueueAddRequest_RequestMethod(value)
215 return nil
216 }
217 func (TaskQueueAddRequest_RequestMethod) EnumDescriptor() ([]byte, []int) {
218 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{6, 0}
219 }
220
221 type TaskQueueQueryTasksResponse_Task_RequestMethod int32
222
223 const (
224 TaskQueueQueryTasksResponse_Task_GET TaskQueueQueryTasksResponse_Task_RequestMethod = 1
225 TaskQueueQueryTasksResponse_Task_POST TaskQueueQueryTasksResponse_Task_RequestMethod = 2
226 TaskQueueQueryTasksResponse_Task_HEAD TaskQueueQueryTasksResponse_Task_RequestMethod = 3
227 TaskQueueQueryTasksResponse_Task_PUT TaskQueueQueryTasksResponse_Task_RequestMethod = 4
228 TaskQueueQueryTasksResponse_Task_DELETE TaskQueueQueryTasksResponse_Task_RequestMethod = 5
229 )
230
231 var TaskQueueQueryTasksResponse_Task_RequestMethod_name = map[int32]string{
232 1: "GET",
233 2: "POST",
234 3: "HEAD",
235 4: "PUT",
236 5: "DELETE",
237 }
238 var TaskQueueQueryTasksResponse_Task_RequestMethod_value = map[string]int32{
239 "GET": 1,
240 "POST": 2,
241 "HEAD": 3,
242 "PUT": 4,
243 "DELETE": 5,
244 }
245
246 func (x TaskQueueQueryTasksResponse_Task_RequestMethod) Enum() *TaskQueueQueryTasksResponse_Task_RequestMethod {
247 p := new(TaskQueueQueryTasksResponse_Task_RequestMethod)
248 *p = x
249 return p
250 }
251 func (x TaskQueueQueryTasksResponse_Task_RequestMethod) String() string {
252 return proto.EnumName(TaskQueueQueryTasksResponse_Task_RequestMethod_name, int32(x))
253 }
254 func (x *TaskQueueQueryTasksResponse_Task_RequestMethod) UnmarshalJSON(data []byte) error {
255 value, err := proto.UnmarshalJSONEnum(TaskQueueQueryTasksResponse_Task_RequestMethod_value, data, "TaskQueueQueryTasksResponse_Task_RequestMethod")
256 if err != nil {
257 return err
258 }
259 *x = TaskQueueQueryTasksResponse_Task_RequestMethod(value)
260 return nil
261 }
262 func (TaskQueueQueryTasksResponse_Task_RequestMethod) EnumDescriptor() ([]byte, []int) {
263 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{30, 0, 0}
264 }
265
266 type TaskQueueServiceError struct {
267 XXX_NoUnkeyedLiteral struct{} `json:"-"`
268 XXX_unrecognized []byte `json:"-"`
269 XXX_sizecache int32 `json:"-"`
270 }
271
272 func (m *TaskQueueServiceError) Reset() { *m = TaskQueueServiceError{} }
273 func (m *TaskQueueServiceError) String() string { return proto.CompactTextString(m) }
274 func (*TaskQueueServiceError) ProtoMessage() {}
275 func (*TaskQueueServiceError) Descriptor() ([]byte, []int) {
276 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{0}
277 }
278 func (m *TaskQueueServiceError) XXX_Unmarshal(b []byte) error {
279 return xxx_messageInfo_TaskQueueServiceError.Unmarshal(m, b)
280 }
281 func (m *TaskQueueServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
282 return xxx_messageInfo_TaskQueueServiceError.Marshal(b, m, deterministic)
283 }
284 func (dst *TaskQueueServiceError) XXX_Merge(src proto.Message) {
285 xxx_messageInfo_TaskQueueServiceError.Merge(dst, src)
286 }
287 func (m *TaskQueueServiceError) XXX_Size() int {
288 return xxx_messageInfo_TaskQueueServiceError.Size(m)
289 }
290 func (m *TaskQueueServiceError) XXX_DiscardUnknown() {
291 xxx_messageInfo_TaskQueueServiceError.DiscardUnknown(m)
292 }
293
294 var xxx_messageInfo_TaskQueueServiceError proto.InternalMessageInfo
295
296 type TaskPayload struct {
297 XXX_NoUnkeyedLiteral struct{} `json:"-"`
298 proto.XXX_InternalExtensions `protobuf_messageset:"1" json:"-"`
299 XXX_unrecognized []byte `json:"-"`
300 XXX_sizecache int32 `json:"-"`
301 }
302
303 func (m *TaskPayload) Reset() { *m = TaskPayload{} }
304 func (m *TaskPayload) String() string { return proto.CompactTextString(m) }
305 func (*TaskPayload) ProtoMessage() {}
306 func (*TaskPayload) Descriptor() ([]byte, []int) {
307 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{1}
308 }
309
310 func (m *TaskPayload) MarshalJSON() ([]byte, error) {
311 return proto.MarshalMessageSetJSON(&m.XXX_InternalExtensions)
312 }
313 func (m *TaskPayload) UnmarshalJSON(buf []byte) error {
314 return proto.UnmarshalMessageSetJSON(buf, &m.XXX_InternalExtensions)
315 }
316
317 var extRange_TaskPayload = []proto.ExtensionRange{
318 {Start: 10, End: 2147483646},
319 }
320
321 func (*TaskPayload) ExtensionRangeArray() []proto.ExtensionRange {
322 return extRange_TaskPayload
323 }
324 func (m *TaskPayload) XXX_Unmarshal(b []byte) error {
325 return xxx_messageInfo_TaskPayload.Unmarshal(m, b)
326 }
327 func (m *TaskPayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
328 return xxx_messageInfo_TaskPayload.Marshal(b, m, deterministic)
329 }
330 func (dst *TaskPayload) XXX_Merge(src proto.Message) {
331 xxx_messageInfo_TaskPayload.Merge(dst, src)
332 }
333 func (m *TaskPayload) XXX_Size() int {
334 return xxx_messageInfo_TaskPayload.Size(m)
335 }
336 func (m *TaskPayload) XXX_DiscardUnknown() {
337 xxx_messageInfo_TaskPayload.DiscardUnknown(m)
338 }
339
340 var xxx_messageInfo_TaskPayload proto.InternalMessageInfo
341
342 type TaskQueueRetryParameters struct {
343 RetryLimit *int32 `protobuf:"varint,1,opt,name=retry_limit,json=retryLimit" json:"retry_limit,omitempty"`
344 AgeLimitSec *int64 `protobuf:"varint,2,opt,name=age_limit_sec,json=ageLimitSec" json:"age_limit_sec,omitempty"`
345 MinBackoffSec *float64 `protobuf:"fixed64,3,opt,name=min_backoff_sec,json=minBackoffSec,def=0.1" json:"min_backoff_sec,omitempty"`
346 MaxBackoffSec *float64 `protobuf:"fixed64,4,opt,name=max_backoff_sec,json=maxBackoffSec,def=3600" json:"max_backoff_sec,omitempty"`
347 MaxDoublings *int32 `protobuf:"varint,5,opt,name=max_doublings,json=maxDoublings,def=16" json:"max_doublings,omitempty"`
348 XXX_NoUnkeyedLiteral struct{} `json:"-"`
349 XXX_unrecognized []byte `json:"-"`
350 XXX_sizecache int32 `json:"-"`
351 }
352
353 func (m *TaskQueueRetryParameters) Reset() { *m = TaskQueueRetryParameters{} }
354 func (m *TaskQueueRetryParameters) String() string { return proto.CompactTextString(m) }
355 func (*TaskQueueRetryParameters) ProtoMessage() {}
356 func (*TaskQueueRetryParameters) Descriptor() ([]byte, []int) {
357 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{2}
358 }
359 func (m *TaskQueueRetryParameters) XXX_Unmarshal(b []byte) error {
360 return xxx_messageInfo_TaskQueueRetryParameters.Unmarshal(m, b)
361 }
362 func (m *TaskQueueRetryParameters) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
363 return xxx_messageInfo_TaskQueueRetryParameters.Marshal(b, m, deterministic)
364 }
365 func (dst *TaskQueueRetryParameters) XXX_Merge(src proto.Message) {
366 xxx_messageInfo_TaskQueueRetryParameters.Merge(dst, src)
367 }
368 func (m *TaskQueueRetryParameters) XXX_Size() int {
369 return xxx_messageInfo_TaskQueueRetryParameters.Size(m)
370 }
371 func (m *TaskQueueRetryParameters) XXX_DiscardUnknown() {
372 xxx_messageInfo_TaskQueueRetryParameters.DiscardUnknown(m)
373 }
374
375 var xxx_messageInfo_TaskQueueRetryParameters proto.InternalMessageInfo
376
377 const Default_TaskQueueRetryParameters_MinBackoffSec float64 = 0.1
378 const Default_TaskQueueRetryParameters_MaxBackoffSec float64 = 3600
379 const Default_TaskQueueRetryParameters_MaxDoublings int32 = 16
380
381 func (m *TaskQueueRetryParameters) GetRetryLimit() int32 {
382 if m != nil && m.RetryLimit != nil {
383 return *m.RetryLimit
384 }
385 return 0
386 }
387
388 func (m *TaskQueueRetryParameters) GetAgeLimitSec() int64 {
389 if m != nil && m.AgeLimitSec != nil {
390 return *m.AgeLimitSec
391 }
392 return 0
393 }
394
395 func (m *TaskQueueRetryParameters) GetMinBackoffSec() float64 {
396 if m != nil && m.MinBackoffSec != nil {
397 return *m.MinBackoffSec
398 }
399 return Default_TaskQueueRetryParameters_MinBackoffSec
400 }
401
402 func (m *TaskQueueRetryParameters) GetMaxBackoffSec() float64 {
403 if m != nil && m.MaxBackoffSec != nil {
404 return *m.MaxBackoffSec
405 }
406 return Default_TaskQueueRetryParameters_MaxBackoffSec
407 }
408
409 func (m *TaskQueueRetryParameters) GetMaxDoublings() int32 {
410 if m != nil && m.MaxDoublings != nil {
411 return *m.MaxDoublings
412 }
413 return Default_TaskQueueRetryParameters_MaxDoublings
414 }
415
416 type TaskQueueAcl struct {
417 UserEmail [][]byte `protobuf:"bytes,1,rep,name=user_email,json=userEmail" json:"user_email,omitempty"`
418 WriterEmail [][]byte `protobuf:"bytes,2,rep,name=writer_email,json=writerEmail" json:"writer_email,omitempty"`
419 XXX_NoUnkeyedLiteral struct{} `json:"-"`
420 XXX_unrecognized []byte `json:"-"`
421 XXX_sizecache int32 `json:"-"`
422 }
423
424 func (m *TaskQueueAcl) Reset() { *m = TaskQueueAcl{} }
425 func (m *TaskQueueAcl) String() string { return proto.CompactTextString(m) }
426 func (*TaskQueueAcl) ProtoMessage() {}
427 func (*TaskQueueAcl) Descriptor() ([]byte, []int) {
428 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{3}
429 }
430 func (m *TaskQueueAcl) XXX_Unmarshal(b []byte) error {
431 return xxx_messageInfo_TaskQueueAcl.Unmarshal(m, b)
432 }
433 func (m *TaskQueueAcl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
434 return xxx_messageInfo_TaskQueueAcl.Marshal(b, m, deterministic)
435 }
436 func (dst *TaskQueueAcl) XXX_Merge(src proto.Message) {
437 xxx_messageInfo_TaskQueueAcl.Merge(dst, src)
438 }
439 func (m *TaskQueueAcl) XXX_Size() int {
440 return xxx_messageInfo_TaskQueueAcl.Size(m)
441 }
442 func (m *TaskQueueAcl) XXX_DiscardUnknown() {
443 xxx_messageInfo_TaskQueueAcl.DiscardUnknown(m)
444 }
445
446 var xxx_messageInfo_TaskQueueAcl proto.InternalMessageInfo
447
448 func (m *TaskQueueAcl) GetUserEmail() [][]byte {
449 if m != nil {
450 return m.UserEmail
451 }
452 return nil
453 }
454
455 func (m *TaskQueueAcl) GetWriterEmail() [][]byte {
456 if m != nil {
457 return m.WriterEmail
458 }
459 return nil
460 }
461
462 type TaskQueueHttpHeader struct {
463 Key []byte `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
464 Value []byte `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
465 XXX_NoUnkeyedLiteral struct{} `json:"-"`
466 XXX_unrecognized []byte `json:"-"`
467 XXX_sizecache int32 `json:"-"`
468 }
469
470 func (m *TaskQueueHttpHeader) Reset() { *m = TaskQueueHttpHeader{} }
471 func (m *TaskQueueHttpHeader) String() string { return proto.CompactTextString(m) }
472 func (*TaskQueueHttpHeader) ProtoMessage() {}
473 func (*TaskQueueHttpHeader) Descriptor() ([]byte, []int) {
474 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{4}
475 }
476 func (m *TaskQueueHttpHeader) XXX_Unmarshal(b []byte) error {
477 return xxx_messageInfo_TaskQueueHttpHeader.Unmarshal(m, b)
478 }
479 func (m *TaskQueueHttpHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
480 return xxx_messageInfo_TaskQueueHttpHeader.Marshal(b, m, deterministic)
481 }
482 func (dst *TaskQueueHttpHeader) XXX_Merge(src proto.Message) {
483 xxx_messageInfo_TaskQueueHttpHeader.Merge(dst, src)
484 }
485 func (m *TaskQueueHttpHeader) XXX_Size() int {
486 return xxx_messageInfo_TaskQueueHttpHeader.Size(m)
487 }
488 func (m *TaskQueueHttpHeader) XXX_DiscardUnknown() {
489 xxx_messageInfo_TaskQueueHttpHeader.DiscardUnknown(m)
490 }
491
492 var xxx_messageInfo_TaskQueueHttpHeader proto.InternalMessageInfo
493
494 func (m *TaskQueueHttpHeader) GetKey() []byte {
495 if m != nil {
496 return m.Key
497 }
498 return nil
499 }
500
501 func (m *TaskQueueHttpHeader) GetValue() []byte {
502 if m != nil {
503 return m.Value
504 }
505 return nil
506 }
507
508 type TaskQueueMode struct {
509 XXX_NoUnkeyedLiteral struct{} `json:"-"`
510 XXX_unrecognized []byte `json:"-"`
511 XXX_sizecache int32 `json:"-"`
512 }
513
514 func (m *TaskQueueMode) Reset() { *m = TaskQueueMode{} }
515 func (m *TaskQueueMode) String() string { return proto.CompactTextString(m) }
516 func (*TaskQueueMode) ProtoMessage() {}
517 func (*TaskQueueMode) Descriptor() ([]byte, []int) {
518 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{5}
519 }
520 func (m *TaskQueueMode) XXX_Unmarshal(b []byte) error {
521 return xxx_messageInfo_TaskQueueMode.Unmarshal(m, b)
522 }
523 func (m *TaskQueueMode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
524 return xxx_messageInfo_TaskQueueMode.Marshal(b, m, deterministic)
525 }
526 func (dst *TaskQueueMode) XXX_Merge(src proto.Message) {
527 xxx_messageInfo_TaskQueueMode.Merge(dst, src)
528 }
529 func (m *TaskQueueMode) XXX_Size() int {
530 return xxx_messageInfo_TaskQueueMode.Size(m)
531 }
532 func (m *TaskQueueMode) XXX_DiscardUnknown() {
533 xxx_messageInfo_TaskQueueMode.DiscardUnknown(m)
534 }
535
536 var xxx_messageInfo_TaskQueueMode proto.InternalMessageInfo
537
538 type TaskQueueAddRequest struct {
539 QueueName []byte `protobuf:"bytes,1,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
540 TaskName []byte `protobuf:"bytes,2,req,name=task_name,json=taskName" json:"task_name,omitempty"`
541 EtaUsec *int64 `protobuf:"varint,3,req,name=eta_usec,json=etaUsec" json:"eta_usec,omitempty"`
542 Method *TaskQueueAddRequest_RequestMethod `protobuf:"varint,5,opt,name=method,enum=appengine.TaskQueueAddRequest_RequestMethod,def=2" json:"method,omitempty"`
543 Url []byte `protobuf:"bytes,4,opt,name=url" json:"url,omitempty"`
544 Header []*TaskQueueAddRequest_Header `protobuf:"group,6,rep,name=Header,json=header" json:"header,omitempty"`
545 Body []byte `protobuf:"bytes,9,opt,name=body" json:"body,omitempty"`
546 Transaction *datastore.Transaction `protobuf:"bytes,10,opt,name=transaction" json:"transaction,omitempty"`
547 AppId []byte `protobuf:"bytes,11,opt,name=app_id,json=appId" json:"app_id,omitempty"`
548 Crontimetable *TaskQueueAddRequest_CronTimetable `protobuf:"group,12,opt,name=CronTimetable,json=crontimetable" json:"crontimetable,omitempty"`
549 Description []byte `protobuf:"bytes,15,opt,name=description" json:"description,omitempty"`
550 Payload *TaskPayload `protobuf:"bytes,16,opt,name=payload" json:"payload,omitempty"`
551 RetryParameters *TaskQueueRetryParameters `protobuf:"bytes,17,opt,name=retry_parameters,json=retryParameters" json:"retry_parameters,omitempty"`
552 Mode *TaskQueueMode_Mode `protobuf:"varint,18,opt,name=mode,enum=appengine.TaskQueueMode_Mode,def=0" json:"mode,omitempty"`
553 Tag []byte `protobuf:"bytes,19,opt,name=tag" json:"tag,omitempty"`
554 XXX_NoUnkeyedLiteral struct{} `json:"-"`
555 XXX_unrecognized []byte `json:"-"`
556 XXX_sizecache int32 `json:"-"`
557 }
558
559 func (m *TaskQueueAddRequest) Reset() { *m = TaskQueueAddRequest{} }
560 func (m *TaskQueueAddRequest) String() string { return proto.CompactTextString(m) }
561 func (*TaskQueueAddRequest) ProtoMessage() {}
562 func (*TaskQueueAddRequest) Descriptor() ([]byte, []int) {
563 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{6}
564 }
565 func (m *TaskQueueAddRequest) XXX_Unmarshal(b []byte) error {
566 return xxx_messageInfo_TaskQueueAddRequest.Unmarshal(m, b)
567 }
568 func (m *TaskQueueAddRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
569 return xxx_messageInfo_TaskQueueAddRequest.Marshal(b, m, deterministic)
570 }
571 func (dst *TaskQueueAddRequest) XXX_Merge(src proto.Message) {
572 xxx_messageInfo_TaskQueueAddRequest.Merge(dst, src)
573 }
574 func (m *TaskQueueAddRequest) XXX_Size() int {
575 return xxx_messageInfo_TaskQueueAddRequest.Size(m)
576 }
577 func (m *TaskQueueAddRequest) XXX_DiscardUnknown() {
578 xxx_messageInfo_TaskQueueAddRequest.DiscardUnknown(m)
579 }
580
581 var xxx_messageInfo_TaskQueueAddRequest proto.InternalMessageInfo
582
583 const Default_TaskQueueAddRequest_Method TaskQueueAddRequest_RequestMethod = TaskQueueAddRequest_POST
584 const Default_TaskQueueAddRequest_Mode TaskQueueMode_Mode = TaskQueueMode_PUSH
585
586 func (m *TaskQueueAddRequest) GetQueueName() []byte {
587 if m != nil {
588 return m.QueueName
589 }
590 return nil
591 }
592
593 func (m *TaskQueueAddRequest) GetTaskName() []byte {
594 if m != nil {
595 return m.TaskName
596 }
597 return nil
598 }
599
600 func (m *TaskQueueAddRequest) GetEtaUsec() int64 {
601 if m != nil && m.EtaUsec != nil {
602 return *m.EtaUsec
603 }
604 return 0
605 }
606
607 func (m *TaskQueueAddRequest) GetMethod() TaskQueueAddRequest_RequestMethod {
608 if m != nil && m.Method != nil {
609 return *m.Method
610 }
611 return Default_TaskQueueAddRequest_Method
612 }
613
614 func (m *TaskQueueAddRequest) GetUrl() []byte {
615 if m != nil {
616 return m.Url
617 }
618 return nil
619 }
620
621 func (m *TaskQueueAddRequest) GetHeader() []*TaskQueueAddRequest_Header {
622 if m != nil {
623 return m.Header
624 }
625 return nil
626 }
627
628 func (m *TaskQueueAddRequest) GetBody() []byte {
629 if m != nil {
630 return m.Body
631 }
632 return nil
633 }
634
635 func (m *TaskQueueAddRequest) GetTransaction() *datastore.Transaction {
636 if m != nil {
637 return m.Transaction
638 }
639 return nil
640 }
641
642 func (m *TaskQueueAddRequest) GetAppId() []byte {
643 if m != nil {
644 return m.AppId
645 }
646 return nil
647 }
648
649 func (m *TaskQueueAddRequest) GetCrontimetable() *TaskQueueAddRequest_CronTimetable {
650 if m != nil {
651 return m.Crontimetable
652 }
653 return nil
654 }
655
656 func (m *TaskQueueAddRequest) GetDescription() []byte {
657 if m != nil {
658 return m.Description
659 }
660 return nil
661 }
662
663 func (m *TaskQueueAddRequest) GetPayload() *TaskPayload {
664 if m != nil {
665 return m.Payload
666 }
667 return nil
668 }
669
670 func (m *TaskQueueAddRequest) GetRetryParameters() *TaskQueueRetryParameters {
671 if m != nil {
672 return m.RetryParameters
673 }
674 return nil
675 }
676
677 func (m *TaskQueueAddRequest) GetMode() TaskQueueMode_Mode {
678 if m != nil && m.Mode != nil {
679 return *m.Mode
680 }
681 return Default_TaskQueueAddRequest_Mode
682 }
683
684 func (m *TaskQueueAddRequest) GetTag() []byte {
685 if m != nil {
686 return m.Tag
687 }
688 return nil
689 }
690
691 type TaskQueueAddRequest_Header struct {
692 Key []byte `protobuf:"bytes,7,req,name=key" json:"key,omitempty"`
693 Value []byte `protobuf:"bytes,8,req,name=value" json:"value,omitempty"`
694 XXX_NoUnkeyedLiteral struct{} `json:"-"`
695 XXX_unrecognized []byte `json:"-"`
696 XXX_sizecache int32 `json:"-"`
697 }
698
699 func (m *TaskQueueAddRequest_Header) Reset() { *m = TaskQueueAddRequest_Header{} }
700 func (m *TaskQueueAddRequest_Header) String() string { return proto.CompactTextString(m) }
701 func (*TaskQueueAddRequest_Header) ProtoMessage() {}
702 func (*TaskQueueAddRequest_Header) Descriptor() ([]byte, []int) {
703 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{6, 0}
704 }
705 func (m *TaskQueueAddRequest_Header) XXX_Unmarshal(b []byte) error {
706 return xxx_messageInfo_TaskQueueAddRequest_Header.Unmarshal(m, b)
707 }
708 func (m *TaskQueueAddRequest_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
709 return xxx_messageInfo_TaskQueueAddRequest_Header.Marshal(b, m, deterministic)
710 }
711 func (dst *TaskQueueAddRequest_Header) XXX_Merge(src proto.Message) {
712 xxx_messageInfo_TaskQueueAddRequest_Header.Merge(dst, src)
713 }
714 func (m *TaskQueueAddRequest_Header) XXX_Size() int {
715 return xxx_messageInfo_TaskQueueAddRequest_Header.Size(m)
716 }
717 func (m *TaskQueueAddRequest_Header) XXX_DiscardUnknown() {
718 xxx_messageInfo_TaskQueueAddRequest_Header.DiscardUnknown(m)
719 }
720
721 var xxx_messageInfo_TaskQueueAddRequest_Header proto.InternalMessageInfo
722
723 func (m *TaskQueueAddRequest_Header) GetKey() []byte {
724 if m != nil {
725 return m.Key
726 }
727 return nil
728 }
729
730 func (m *TaskQueueAddRequest_Header) GetValue() []byte {
731 if m != nil {
732 return m.Value
733 }
734 return nil
735 }
736
737 type TaskQueueAddRequest_CronTimetable struct {
738 Schedule []byte `protobuf:"bytes,13,req,name=schedule" json:"schedule,omitempty"`
739 Timezone []byte `protobuf:"bytes,14,req,name=timezone" json:"timezone,omitempty"`
740 XXX_NoUnkeyedLiteral struct{} `json:"-"`
741 XXX_unrecognized []byte `json:"-"`
742 XXX_sizecache int32 `json:"-"`
743 }
744
745 func (m *TaskQueueAddRequest_CronTimetable) Reset() { *m = TaskQueueAddRequest_CronTimetable{} }
746 func (m *TaskQueueAddRequest_CronTimetable) String() string { return proto.CompactTextString(m) }
747 func (*TaskQueueAddRequest_CronTimetable) ProtoMessage() {}
748 func (*TaskQueueAddRequest_CronTimetable) Descriptor() ([]byte, []int) {
749 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{6, 1}
750 }
751 func (m *TaskQueueAddRequest_CronTimetable) XXX_Unmarshal(b []byte) error {
752 return xxx_messageInfo_TaskQueueAddRequest_CronTimetable.Unmarshal(m, b)
753 }
754 func (m *TaskQueueAddRequest_CronTimetable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
755 return xxx_messageInfo_TaskQueueAddRequest_CronTimetable.Marshal(b, m, deterministic)
756 }
757 func (dst *TaskQueueAddRequest_CronTimetable) XXX_Merge(src proto.Message) {
758 xxx_messageInfo_TaskQueueAddRequest_CronTimetable.Merge(dst, src)
759 }
760 func (m *TaskQueueAddRequest_CronTimetable) XXX_Size() int {
761 return xxx_messageInfo_TaskQueueAddRequest_CronTimetable.Size(m)
762 }
763 func (m *TaskQueueAddRequest_CronTimetable) XXX_DiscardUnknown() {
764 xxx_messageInfo_TaskQueueAddRequest_CronTimetable.DiscardUnknown(m)
765 }
766
767 var xxx_messageInfo_TaskQueueAddRequest_CronTimetable proto.InternalMessageInfo
768
769 func (m *TaskQueueAddRequest_CronTimetable) GetSchedule() []byte {
770 if m != nil {
771 return m.Schedule
772 }
773 return nil
774 }
775
776 func (m *TaskQueueAddRequest_CronTimetable) GetTimezone() []byte {
777 if m != nil {
778 return m.Timezone
779 }
780 return nil
781 }
782
783 type TaskQueueAddResponse struct {
784 ChosenTaskName []byte `protobuf:"bytes,1,opt,name=chosen_task_name,json=chosenTaskName" json:"chosen_task_name,omitempty"`
785 XXX_NoUnkeyedLiteral struct{} `json:"-"`
786 XXX_unrecognized []byte `json:"-"`
787 XXX_sizecache int32 `json:"-"`
788 }
789
790 func (m *TaskQueueAddResponse) Reset() { *m = TaskQueueAddResponse{} }
791 func (m *TaskQueueAddResponse) String() string { return proto.CompactTextString(m) }
792 func (*TaskQueueAddResponse) ProtoMessage() {}
793 func (*TaskQueueAddResponse) Descriptor() ([]byte, []int) {
794 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{7}
795 }
796 func (m *TaskQueueAddResponse) XXX_Unmarshal(b []byte) error {
797 return xxx_messageInfo_TaskQueueAddResponse.Unmarshal(m, b)
798 }
799 func (m *TaskQueueAddResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
800 return xxx_messageInfo_TaskQueueAddResponse.Marshal(b, m, deterministic)
801 }
802 func (dst *TaskQueueAddResponse) XXX_Merge(src proto.Message) {
803 xxx_messageInfo_TaskQueueAddResponse.Merge(dst, src)
804 }
805 func (m *TaskQueueAddResponse) XXX_Size() int {
806 return xxx_messageInfo_TaskQueueAddResponse.Size(m)
807 }
808 func (m *TaskQueueAddResponse) XXX_DiscardUnknown() {
809 xxx_messageInfo_TaskQueueAddResponse.DiscardUnknown(m)
810 }
811
812 var xxx_messageInfo_TaskQueueAddResponse proto.InternalMessageInfo
813
814 func (m *TaskQueueAddResponse) GetChosenTaskName() []byte {
815 if m != nil {
816 return m.ChosenTaskName
817 }
818 return nil
819 }
820
821 type TaskQueueBulkAddRequest struct {
822 AddRequest []*TaskQueueAddRequest `protobuf:"bytes,1,rep,name=add_request,json=addRequest" json:"add_request,omitempty"`
823 XXX_NoUnkeyedLiteral struct{} `json:"-"`
824 XXX_unrecognized []byte `json:"-"`
825 XXX_sizecache int32 `json:"-"`
826 }
827
828 func (m *TaskQueueBulkAddRequest) Reset() { *m = TaskQueueBulkAddRequest{} }
829 func (m *TaskQueueBulkAddRequest) String() string { return proto.CompactTextString(m) }
830 func (*TaskQueueBulkAddRequest) ProtoMessage() {}
831 func (*TaskQueueBulkAddRequest) Descriptor() ([]byte, []int) {
832 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{8}
833 }
834 func (m *TaskQueueBulkAddRequest) XXX_Unmarshal(b []byte) error {
835 return xxx_messageInfo_TaskQueueBulkAddRequest.Unmarshal(m, b)
836 }
837 func (m *TaskQueueBulkAddRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
838 return xxx_messageInfo_TaskQueueBulkAddRequest.Marshal(b, m, deterministic)
839 }
840 func (dst *TaskQueueBulkAddRequest) XXX_Merge(src proto.Message) {
841 xxx_messageInfo_TaskQueueBulkAddRequest.Merge(dst, src)
842 }
843 func (m *TaskQueueBulkAddRequest) XXX_Size() int {
844 return xxx_messageInfo_TaskQueueBulkAddRequest.Size(m)
845 }
846 func (m *TaskQueueBulkAddRequest) XXX_DiscardUnknown() {
847 xxx_messageInfo_TaskQueueBulkAddRequest.DiscardUnknown(m)
848 }
849
850 var xxx_messageInfo_TaskQueueBulkAddRequest proto.InternalMessageInfo
851
852 func (m *TaskQueueBulkAddRequest) GetAddRequest() []*TaskQueueAddRequest {
853 if m != nil {
854 return m.AddRequest
855 }
856 return nil
857 }
858
859 type TaskQueueBulkAddResponse struct {
860 Taskresult []*TaskQueueBulkAddResponse_TaskResult `protobuf:"group,1,rep,name=TaskResult,json=taskresult" json:"taskresult,omitempty"`
861 XXX_NoUnkeyedLiteral struct{} `json:"-"`
862 XXX_unrecognized []byte `json:"-"`
863 XXX_sizecache int32 `json:"-"`
864 }
865
866 func (m *TaskQueueBulkAddResponse) Reset() { *m = TaskQueueBulkAddResponse{} }
867 func (m *TaskQueueBulkAddResponse) String() string { return proto.CompactTextString(m) }
868 func (*TaskQueueBulkAddResponse) ProtoMessage() {}
869 func (*TaskQueueBulkAddResponse) Descriptor() ([]byte, []int) {
870 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{9}
871 }
872 func (m *TaskQueueBulkAddResponse) XXX_Unmarshal(b []byte) error {
873 return xxx_messageInfo_TaskQueueBulkAddResponse.Unmarshal(m, b)
874 }
875 func (m *TaskQueueBulkAddResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
876 return xxx_messageInfo_TaskQueueBulkAddResponse.Marshal(b, m, deterministic)
877 }
878 func (dst *TaskQueueBulkAddResponse) XXX_Merge(src proto.Message) {
879 xxx_messageInfo_TaskQueueBulkAddResponse.Merge(dst, src)
880 }
881 func (m *TaskQueueBulkAddResponse) XXX_Size() int {
882 return xxx_messageInfo_TaskQueueBulkAddResponse.Size(m)
883 }
884 func (m *TaskQueueBulkAddResponse) XXX_DiscardUnknown() {
885 xxx_messageInfo_TaskQueueBulkAddResponse.DiscardUnknown(m)
886 }
887
888 var xxx_messageInfo_TaskQueueBulkAddResponse proto.InternalMessageInfo
889
890 func (m *TaskQueueBulkAddResponse) GetTaskresult() []*TaskQueueBulkAddResponse_TaskResult {
891 if m != nil {
892 return m.Taskresult
893 }
894 return nil
895 }
896
897 type TaskQueueBulkAddResponse_TaskResult struct {
898 Result *TaskQueueServiceError_ErrorCode `protobuf:"varint,2,req,name=result,enum=appengine.TaskQueueServiceError_ErrorCode" json:"result,omitempty"`
899 ChosenTaskName []byte `protobuf:"bytes,3,opt,name=chosen_task_name,json=chosenTaskName" json:"chosen_task_name,omitempty"`
900 XXX_NoUnkeyedLiteral struct{} `json:"-"`
901 XXX_unrecognized []byte `json:"-"`
902 XXX_sizecache int32 `json:"-"`
903 }
904
905 func (m *TaskQueueBulkAddResponse_TaskResult) Reset() { *m = TaskQueueBulkAddResponse_TaskResult{} }
906 func (m *TaskQueueBulkAddResponse_TaskResult) String() string { return proto.CompactTextString(m) }
907 func (*TaskQueueBulkAddResponse_TaskResult) ProtoMessage() {}
908 func (*TaskQueueBulkAddResponse_TaskResult) Descriptor() ([]byte, []int) {
909 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{9, 0}
910 }
911 func (m *TaskQueueBulkAddResponse_TaskResult) XXX_Unmarshal(b []byte) error {
912 return xxx_messageInfo_TaskQueueBulkAddResponse_TaskResult.Unmarshal(m, b)
913 }
914 func (m *TaskQueueBulkAddResponse_TaskResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
915 return xxx_messageInfo_TaskQueueBulkAddResponse_TaskResult.Marshal(b, m, deterministic)
916 }
917 func (dst *TaskQueueBulkAddResponse_TaskResult) XXX_Merge(src proto.Message) {
918 xxx_messageInfo_TaskQueueBulkAddResponse_TaskResult.Merge(dst, src)
919 }
920 func (m *TaskQueueBulkAddResponse_TaskResult) XXX_Size() int {
921 return xxx_messageInfo_TaskQueueBulkAddResponse_TaskResult.Size(m)
922 }
923 func (m *TaskQueueBulkAddResponse_TaskResult) XXX_DiscardUnknown() {
924 xxx_messageInfo_TaskQueueBulkAddResponse_TaskResult.DiscardUnknown(m)
925 }
926
927 var xxx_messageInfo_TaskQueueBulkAddResponse_TaskResult proto.InternalMessageInfo
928
929 func (m *TaskQueueBulkAddResponse_TaskResult) GetResult() TaskQueueServiceError_ErrorCode {
930 if m != nil && m.Result != nil {
931 return *m.Result
932 }
933 return TaskQueueServiceError_OK
934 }
935
936 func (m *TaskQueueBulkAddResponse_TaskResult) GetChosenTaskName() []byte {
937 if m != nil {
938 return m.ChosenTaskName
939 }
940 return nil
941 }
942
943 type TaskQueueDeleteRequest struct {
944 QueueName []byte `protobuf:"bytes,1,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
945 TaskName [][]byte `protobuf:"bytes,2,rep,name=task_name,json=taskName" json:"task_name,omitempty"`
946 AppId []byte `protobuf:"bytes,3,opt,name=app_id,json=appId" json:"app_id,omitempty"`
947 XXX_NoUnkeyedLiteral struct{} `json:"-"`
948 XXX_unrecognized []byte `json:"-"`
949 XXX_sizecache int32 `json:"-"`
950 }
951
952 func (m *TaskQueueDeleteRequest) Reset() { *m = TaskQueueDeleteRequest{} }
953 func (m *TaskQueueDeleteRequest) String() string { return proto.CompactTextString(m) }
954 func (*TaskQueueDeleteRequest) ProtoMessage() {}
955 func (*TaskQueueDeleteRequest) Descriptor() ([]byte, []int) {
956 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{10}
957 }
958 func (m *TaskQueueDeleteRequest) XXX_Unmarshal(b []byte) error {
959 return xxx_messageInfo_TaskQueueDeleteRequest.Unmarshal(m, b)
960 }
961 func (m *TaskQueueDeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
962 return xxx_messageInfo_TaskQueueDeleteRequest.Marshal(b, m, deterministic)
963 }
964 func (dst *TaskQueueDeleteRequest) XXX_Merge(src proto.Message) {
965 xxx_messageInfo_TaskQueueDeleteRequest.Merge(dst, src)
966 }
967 func (m *TaskQueueDeleteRequest) XXX_Size() int {
968 return xxx_messageInfo_TaskQueueDeleteRequest.Size(m)
969 }
970 func (m *TaskQueueDeleteRequest) XXX_DiscardUnknown() {
971 xxx_messageInfo_TaskQueueDeleteRequest.DiscardUnknown(m)
972 }
973
974 var xxx_messageInfo_TaskQueueDeleteRequest proto.InternalMessageInfo
975
976 func (m *TaskQueueDeleteRequest) GetQueueName() []byte {
977 if m != nil {
978 return m.QueueName
979 }
980 return nil
981 }
982
983 func (m *TaskQueueDeleteRequest) GetTaskName() [][]byte {
984 if m != nil {
985 return m.TaskName
986 }
987 return nil
988 }
989
990 func (m *TaskQueueDeleteRequest) GetAppId() []byte {
991 if m != nil {
992 return m.AppId
993 }
994 return nil
995 }
996
997 type TaskQueueDeleteResponse struct {
998 Result []TaskQueueServiceError_ErrorCode `protobuf:"varint,3,rep,name=result,enum=appengine.TaskQueueServiceError_ErrorCode" json:"result,omitempty"`
999 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1000 XXX_unrecognized []byte `json:"-"`
1001 XXX_sizecache int32 `json:"-"`
1002 }
1003
1004 func (m *TaskQueueDeleteResponse) Reset() { *m = TaskQueueDeleteResponse{} }
1005 func (m *TaskQueueDeleteResponse) String() string { return proto.CompactTextString(m) }
1006 func (*TaskQueueDeleteResponse) ProtoMessage() {}
1007 func (*TaskQueueDeleteResponse) Descriptor() ([]byte, []int) {
1008 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{11}
1009 }
1010 func (m *TaskQueueDeleteResponse) XXX_Unmarshal(b []byte) error {
1011 return xxx_messageInfo_TaskQueueDeleteResponse.Unmarshal(m, b)
1012 }
1013 func (m *TaskQueueDeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1014 return xxx_messageInfo_TaskQueueDeleteResponse.Marshal(b, m, deterministic)
1015 }
1016 func (dst *TaskQueueDeleteResponse) XXX_Merge(src proto.Message) {
1017 xxx_messageInfo_TaskQueueDeleteResponse.Merge(dst, src)
1018 }
1019 func (m *TaskQueueDeleteResponse) XXX_Size() int {
1020 return xxx_messageInfo_TaskQueueDeleteResponse.Size(m)
1021 }
1022 func (m *TaskQueueDeleteResponse) XXX_DiscardUnknown() {
1023 xxx_messageInfo_TaskQueueDeleteResponse.DiscardUnknown(m)
1024 }
1025
1026 var xxx_messageInfo_TaskQueueDeleteResponse proto.InternalMessageInfo
1027
1028 func (m *TaskQueueDeleteResponse) GetResult() []TaskQueueServiceError_ErrorCode {
1029 if m != nil {
1030 return m.Result
1031 }
1032 return nil
1033 }
1034
1035 type TaskQueueForceRunRequest struct {
1036 AppId []byte `protobuf:"bytes,1,opt,name=app_id,json=appId" json:"app_id,omitempty"`
1037 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
1038 TaskName []byte `protobuf:"bytes,3,req,name=task_name,json=taskName" json:"task_name,omitempty"`
1039 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1040 XXX_unrecognized []byte `json:"-"`
1041 XXX_sizecache int32 `json:"-"`
1042 }
1043
1044 func (m *TaskQueueForceRunRequest) Reset() { *m = TaskQueueForceRunRequest{} }
1045 func (m *TaskQueueForceRunRequest) String() string { return proto.CompactTextString(m) }
1046 func (*TaskQueueForceRunRequest) ProtoMessage() {}
1047 func (*TaskQueueForceRunRequest) Descriptor() ([]byte, []int) {
1048 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{12}
1049 }
1050 func (m *TaskQueueForceRunRequest) XXX_Unmarshal(b []byte) error {
1051 return xxx_messageInfo_TaskQueueForceRunRequest.Unmarshal(m, b)
1052 }
1053 func (m *TaskQueueForceRunRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1054 return xxx_messageInfo_TaskQueueForceRunRequest.Marshal(b, m, deterministic)
1055 }
1056 func (dst *TaskQueueForceRunRequest) XXX_Merge(src proto.Message) {
1057 xxx_messageInfo_TaskQueueForceRunRequest.Merge(dst, src)
1058 }
1059 func (m *TaskQueueForceRunRequest) XXX_Size() int {
1060 return xxx_messageInfo_TaskQueueForceRunRequest.Size(m)
1061 }
1062 func (m *TaskQueueForceRunRequest) XXX_DiscardUnknown() {
1063 xxx_messageInfo_TaskQueueForceRunRequest.DiscardUnknown(m)
1064 }
1065
1066 var xxx_messageInfo_TaskQueueForceRunRequest proto.InternalMessageInfo
1067
1068 func (m *TaskQueueForceRunRequest) GetAppId() []byte {
1069 if m != nil {
1070 return m.AppId
1071 }
1072 return nil
1073 }
1074
1075 func (m *TaskQueueForceRunRequest) GetQueueName() []byte {
1076 if m != nil {
1077 return m.QueueName
1078 }
1079 return nil
1080 }
1081
1082 func (m *TaskQueueForceRunRequest) GetTaskName() []byte {
1083 if m != nil {
1084 return m.TaskName
1085 }
1086 return nil
1087 }
1088
1089 type TaskQueueForceRunResponse struct {
1090 Result *TaskQueueServiceError_ErrorCode `protobuf:"varint,3,req,name=result,enum=appengine.TaskQueueServiceError_ErrorCode" json:"result,omitempty"`
1091 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1092 XXX_unrecognized []byte `json:"-"`
1093 XXX_sizecache int32 `json:"-"`
1094 }
1095
1096 func (m *TaskQueueForceRunResponse) Reset() { *m = TaskQueueForceRunResponse{} }
1097 func (m *TaskQueueForceRunResponse) String() string { return proto.CompactTextString(m) }
1098 func (*TaskQueueForceRunResponse) ProtoMessage() {}
1099 func (*TaskQueueForceRunResponse) Descriptor() ([]byte, []int) {
1100 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{13}
1101 }
1102 func (m *TaskQueueForceRunResponse) XXX_Unmarshal(b []byte) error {
1103 return xxx_messageInfo_TaskQueueForceRunResponse.Unmarshal(m, b)
1104 }
1105 func (m *TaskQueueForceRunResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1106 return xxx_messageInfo_TaskQueueForceRunResponse.Marshal(b, m, deterministic)
1107 }
1108 func (dst *TaskQueueForceRunResponse) XXX_Merge(src proto.Message) {
1109 xxx_messageInfo_TaskQueueForceRunResponse.Merge(dst, src)
1110 }
1111 func (m *TaskQueueForceRunResponse) XXX_Size() int {
1112 return xxx_messageInfo_TaskQueueForceRunResponse.Size(m)
1113 }
1114 func (m *TaskQueueForceRunResponse) XXX_DiscardUnknown() {
1115 xxx_messageInfo_TaskQueueForceRunResponse.DiscardUnknown(m)
1116 }
1117
1118 var xxx_messageInfo_TaskQueueForceRunResponse proto.InternalMessageInfo
1119
1120 func (m *TaskQueueForceRunResponse) GetResult() TaskQueueServiceError_ErrorCode {
1121 if m != nil && m.Result != nil {
1122 return *m.Result
1123 }
1124 return TaskQueueServiceError_OK
1125 }
1126
1127 type TaskQueueUpdateQueueRequest struct {
1128 AppId []byte `protobuf:"bytes,1,opt,name=app_id,json=appId" json:"app_id,omitempty"`
1129 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
1130 BucketRefillPerSecond *float64 `protobuf:"fixed64,3,req,name=bucket_refill_per_second,json=bucketRefillPerSecond" json:"bucket_refill_per_second,omitempty"`
1131 BucketCapacity *int32 `protobuf:"varint,4,req,name=bucket_capacity,json=bucketCapacity" json:"bucket_capacity,omitempty"`
1132 UserSpecifiedRate *string `protobuf:"bytes,5,opt,name=user_specified_rate,json=userSpecifiedRate" json:"user_specified_rate,omitempty"`
1133 RetryParameters *TaskQueueRetryParameters `protobuf:"bytes,6,opt,name=retry_parameters,json=retryParameters" json:"retry_parameters,omitempty"`
1134 MaxConcurrentRequests *int32 `protobuf:"varint,7,opt,name=max_concurrent_requests,json=maxConcurrentRequests" json:"max_concurrent_requests,omitempty"`
1135 Mode *TaskQueueMode_Mode `protobuf:"varint,8,opt,name=mode,enum=appengine.TaskQueueMode_Mode,def=0" json:"mode,omitempty"`
1136 Acl *TaskQueueAcl `protobuf:"bytes,9,opt,name=acl" json:"acl,omitempty"`
1137 HeaderOverride []*TaskQueueHttpHeader `protobuf:"bytes,10,rep,name=header_override,json=headerOverride" json:"header_override,omitempty"`
1138 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1139 XXX_unrecognized []byte `json:"-"`
1140 XXX_sizecache int32 `json:"-"`
1141 }
1142
1143 func (m *TaskQueueUpdateQueueRequest) Reset() { *m = TaskQueueUpdateQueueRequest{} }
1144 func (m *TaskQueueUpdateQueueRequest) String() string { return proto.CompactTextString(m) }
1145 func (*TaskQueueUpdateQueueRequest) ProtoMessage() {}
1146 func (*TaskQueueUpdateQueueRequest) Descriptor() ([]byte, []int) {
1147 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{14}
1148 }
1149 func (m *TaskQueueUpdateQueueRequest) XXX_Unmarshal(b []byte) error {
1150 return xxx_messageInfo_TaskQueueUpdateQueueRequest.Unmarshal(m, b)
1151 }
1152 func (m *TaskQueueUpdateQueueRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1153 return xxx_messageInfo_TaskQueueUpdateQueueRequest.Marshal(b, m, deterministic)
1154 }
1155 func (dst *TaskQueueUpdateQueueRequest) XXX_Merge(src proto.Message) {
1156 xxx_messageInfo_TaskQueueUpdateQueueRequest.Merge(dst, src)
1157 }
1158 func (m *TaskQueueUpdateQueueRequest) XXX_Size() int {
1159 return xxx_messageInfo_TaskQueueUpdateQueueRequest.Size(m)
1160 }
1161 func (m *TaskQueueUpdateQueueRequest) XXX_DiscardUnknown() {
1162 xxx_messageInfo_TaskQueueUpdateQueueRequest.DiscardUnknown(m)
1163 }
1164
1165 var xxx_messageInfo_TaskQueueUpdateQueueRequest proto.InternalMessageInfo
1166
1167 const Default_TaskQueueUpdateQueueRequest_Mode TaskQueueMode_Mode = TaskQueueMode_PUSH
1168
1169 func (m *TaskQueueUpdateQueueRequest) GetAppId() []byte {
1170 if m != nil {
1171 return m.AppId
1172 }
1173 return nil
1174 }
1175
1176 func (m *TaskQueueUpdateQueueRequest) GetQueueName() []byte {
1177 if m != nil {
1178 return m.QueueName
1179 }
1180 return nil
1181 }
1182
1183 func (m *TaskQueueUpdateQueueRequest) GetBucketRefillPerSecond() float64 {
1184 if m != nil && m.BucketRefillPerSecond != nil {
1185 return *m.BucketRefillPerSecond
1186 }
1187 return 0
1188 }
1189
1190 func (m *TaskQueueUpdateQueueRequest) GetBucketCapacity() int32 {
1191 if m != nil && m.BucketCapacity != nil {
1192 return *m.BucketCapacity
1193 }
1194 return 0
1195 }
1196
1197 func (m *TaskQueueUpdateQueueRequest) GetUserSpecifiedRate() string {
1198 if m != nil && m.UserSpecifiedRate != nil {
1199 return *m.UserSpecifiedRate
1200 }
1201 return ""
1202 }
1203
1204 func (m *TaskQueueUpdateQueueRequest) GetRetryParameters() *TaskQueueRetryParameters {
1205 if m != nil {
1206 return m.RetryParameters
1207 }
1208 return nil
1209 }
1210
1211 func (m *TaskQueueUpdateQueueRequest) GetMaxConcurrentRequests() int32 {
1212 if m != nil && m.MaxConcurrentRequests != nil {
1213 return *m.MaxConcurrentRequests
1214 }
1215 return 0
1216 }
1217
1218 func (m *TaskQueueUpdateQueueRequest) GetMode() TaskQueueMode_Mode {
1219 if m != nil && m.Mode != nil {
1220 return *m.Mode
1221 }
1222 return Default_TaskQueueUpdateQueueRequest_Mode
1223 }
1224
1225 func (m *TaskQueueUpdateQueueRequest) GetAcl() *TaskQueueAcl {
1226 if m != nil {
1227 return m.Acl
1228 }
1229 return nil
1230 }
1231
1232 func (m *TaskQueueUpdateQueueRequest) GetHeaderOverride() []*TaskQueueHttpHeader {
1233 if m != nil {
1234 return m.HeaderOverride
1235 }
1236 return nil
1237 }
1238
1239 type TaskQueueUpdateQueueResponse struct {
1240 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1241 XXX_unrecognized []byte `json:"-"`
1242 XXX_sizecache int32 `json:"-"`
1243 }
1244
1245 func (m *TaskQueueUpdateQueueResponse) Reset() { *m = TaskQueueUpdateQueueResponse{} }
1246 func (m *TaskQueueUpdateQueueResponse) String() string { return proto.CompactTextString(m) }
1247 func (*TaskQueueUpdateQueueResponse) ProtoMessage() {}
1248 func (*TaskQueueUpdateQueueResponse) Descriptor() ([]byte, []int) {
1249 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{15}
1250 }
1251 func (m *TaskQueueUpdateQueueResponse) XXX_Unmarshal(b []byte) error {
1252 return xxx_messageInfo_TaskQueueUpdateQueueResponse.Unmarshal(m, b)
1253 }
1254 func (m *TaskQueueUpdateQueueResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1255 return xxx_messageInfo_TaskQueueUpdateQueueResponse.Marshal(b, m, deterministic)
1256 }
1257 func (dst *TaskQueueUpdateQueueResponse) XXX_Merge(src proto.Message) {
1258 xxx_messageInfo_TaskQueueUpdateQueueResponse.Merge(dst, src)
1259 }
1260 func (m *TaskQueueUpdateQueueResponse) XXX_Size() int {
1261 return xxx_messageInfo_TaskQueueUpdateQueueResponse.Size(m)
1262 }
1263 func (m *TaskQueueUpdateQueueResponse) XXX_DiscardUnknown() {
1264 xxx_messageInfo_TaskQueueUpdateQueueResponse.DiscardUnknown(m)
1265 }
1266
1267 var xxx_messageInfo_TaskQueueUpdateQueueResponse proto.InternalMessageInfo
1268
1269 type TaskQueueFetchQueuesRequest struct {
1270 AppId []byte `protobuf:"bytes,1,opt,name=app_id,json=appId" json:"app_id,omitempty"`
1271 MaxRows *int32 `protobuf:"varint,2,req,name=max_rows,json=maxRows" json:"max_rows,omitempty"`
1272 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1273 XXX_unrecognized []byte `json:"-"`
1274 XXX_sizecache int32 `json:"-"`
1275 }
1276
1277 func (m *TaskQueueFetchQueuesRequest) Reset() { *m = TaskQueueFetchQueuesRequest{} }
1278 func (m *TaskQueueFetchQueuesRequest) String() string { return proto.CompactTextString(m) }
1279 func (*TaskQueueFetchQueuesRequest) ProtoMessage() {}
1280 func (*TaskQueueFetchQueuesRequest) Descriptor() ([]byte, []int) {
1281 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{16}
1282 }
1283 func (m *TaskQueueFetchQueuesRequest) XXX_Unmarshal(b []byte) error {
1284 return xxx_messageInfo_TaskQueueFetchQueuesRequest.Unmarshal(m, b)
1285 }
1286 func (m *TaskQueueFetchQueuesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1287 return xxx_messageInfo_TaskQueueFetchQueuesRequest.Marshal(b, m, deterministic)
1288 }
1289 func (dst *TaskQueueFetchQueuesRequest) XXX_Merge(src proto.Message) {
1290 xxx_messageInfo_TaskQueueFetchQueuesRequest.Merge(dst, src)
1291 }
1292 func (m *TaskQueueFetchQueuesRequest) XXX_Size() int {
1293 return xxx_messageInfo_TaskQueueFetchQueuesRequest.Size(m)
1294 }
1295 func (m *TaskQueueFetchQueuesRequest) XXX_DiscardUnknown() {
1296 xxx_messageInfo_TaskQueueFetchQueuesRequest.DiscardUnknown(m)
1297 }
1298
1299 var xxx_messageInfo_TaskQueueFetchQueuesRequest proto.InternalMessageInfo
1300
1301 func (m *TaskQueueFetchQueuesRequest) GetAppId() []byte {
1302 if m != nil {
1303 return m.AppId
1304 }
1305 return nil
1306 }
1307
1308 func (m *TaskQueueFetchQueuesRequest) GetMaxRows() int32 {
1309 if m != nil && m.MaxRows != nil {
1310 return *m.MaxRows
1311 }
1312 return 0
1313 }
1314
1315 type TaskQueueFetchQueuesResponse struct {
1316 Queue []*TaskQueueFetchQueuesResponse_Queue `protobuf:"group,1,rep,name=Queue,json=queue" json:"queue,omitempty"`
1317 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1318 XXX_unrecognized []byte `json:"-"`
1319 XXX_sizecache int32 `json:"-"`
1320 }
1321
1322 func (m *TaskQueueFetchQueuesResponse) Reset() { *m = TaskQueueFetchQueuesResponse{} }
1323 func (m *TaskQueueFetchQueuesResponse) String() string { return proto.CompactTextString(m) }
1324 func (*TaskQueueFetchQueuesResponse) ProtoMessage() {}
1325 func (*TaskQueueFetchQueuesResponse) Descriptor() ([]byte, []int) {
1326 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{17}
1327 }
1328 func (m *TaskQueueFetchQueuesResponse) XXX_Unmarshal(b []byte) error {
1329 return xxx_messageInfo_TaskQueueFetchQueuesResponse.Unmarshal(m, b)
1330 }
1331 func (m *TaskQueueFetchQueuesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1332 return xxx_messageInfo_TaskQueueFetchQueuesResponse.Marshal(b, m, deterministic)
1333 }
1334 func (dst *TaskQueueFetchQueuesResponse) XXX_Merge(src proto.Message) {
1335 xxx_messageInfo_TaskQueueFetchQueuesResponse.Merge(dst, src)
1336 }
1337 func (m *TaskQueueFetchQueuesResponse) XXX_Size() int {
1338 return xxx_messageInfo_TaskQueueFetchQueuesResponse.Size(m)
1339 }
1340 func (m *TaskQueueFetchQueuesResponse) XXX_DiscardUnknown() {
1341 xxx_messageInfo_TaskQueueFetchQueuesResponse.DiscardUnknown(m)
1342 }
1343
1344 var xxx_messageInfo_TaskQueueFetchQueuesResponse proto.InternalMessageInfo
1345
1346 func (m *TaskQueueFetchQueuesResponse) GetQueue() []*TaskQueueFetchQueuesResponse_Queue {
1347 if m != nil {
1348 return m.Queue
1349 }
1350 return nil
1351 }
1352
1353 type TaskQueueFetchQueuesResponse_Queue struct {
1354 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
1355 BucketRefillPerSecond *float64 `protobuf:"fixed64,3,req,name=bucket_refill_per_second,json=bucketRefillPerSecond" json:"bucket_refill_per_second,omitempty"`
1356 BucketCapacity *float64 `protobuf:"fixed64,4,req,name=bucket_capacity,json=bucketCapacity" json:"bucket_capacity,omitempty"`
1357 UserSpecifiedRate *string `protobuf:"bytes,5,opt,name=user_specified_rate,json=userSpecifiedRate" json:"user_specified_rate,omitempty"`
1358 Paused *bool `protobuf:"varint,6,req,name=paused,def=0" json:"paused,omitempty"`
1359 RetryParameters *TaskQueueRetryParameters `protobuf:"bytes,7,opt,name=retry_parameters,json=retryParameters" json:"retry_parameters,omitempty"`
1360 MaxConcurrentRequests *int32 `protobuf:"varint,8,opt,name=max_concurrent_requests,json=maxConcurrentRequests" json:"max_concurrent_requests,omitempty"`
1361 Mode *TaskQueueMode_Mode `protobuf:"varint,9,opt,name=mode,enum=appengine.TaskQueueMode_Mode,def=0" json:"mode,omitempty"`
1362 Acl *TaskQueueAcl `protobuf:"bytes,10,opt,name=acl" json:"acl,omitempty"`
1363 HeaderOverride []*TaskQueueHttpHeader `protobuf:"bytes,11,rep,name=header_override,json=headerOverride" json:"header_override,omitempty"`
1364 CreatorName *string `protobuf:"bytes,12,opt,name=creator_name,json=creatorName,def=apphosting" json:"creator_name,omitempty"`
1365 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1366 XXX_unrecognized []byte `json:"-"`
1367 XXX_sizecache int32 `json:"-"`
1368 }
1369
1370 func (m *TaskQueueFetchQueuesResponse_Queue) Reset() { *m = TaskQueueFetchQueuesResponse_Queue{} }
1371 func (m *TaskQueueFetchQueuesResponse_Queue) String() string { return proto.CompactTextString(m) }
1372 func (*TaskQueueFetchQueuesResponse_Queue) ProtoMessage() {}
1373 func (*TaskQueueFetchQueuesResponse_Queue) Descriptor() ([]byte, []int) {
1374 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{17, 0}
1375 }
1376 func (m *TaskQueueFetchQueuesResponse_Queue) XXX_Unmarshal(b []byte) error {
1377 return xxx_messageInfo_TaskQueueFetchQueuesResponse_Queue.Unmarshal(m, b)
1378 }
1379 func (m *TaskQueueFetchQueuesResponse_Queue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1380 return xxx_messageInfo_TaskQueueFetchQueuesResponse_Queue.Marshal(b, m, deterministic)
1381 }
1382 func (dst *TaskQueueFetchQueuesResponse_Queue) XXX_Merge(src proto.Message) {
1383 xxx_messageInfo_TaskQueueFetchQueuesResponse_Queue.Merge(dst, src)
1384 }
1385 func (m *TaskQueueFetchQueuesResponse_Queue) XXX_Size() int {
1386 return xxx_messageInfo_TaskQueueFetchQueuesResponse_Queue.Size(m)
1387 }
1388 func (m *TaskQueueFetchQueuesResponse_Queue) XXX_DiscardUnknown() {
1389 xxx_messageInfo_TaskQueueFetchQueuesResponse_Queue.DiscardUnknown(m)
1390 }
1391
1392 var xxx_messageInfo_TaskQueueFetchQueuesResponse_Queue proto.InternalMessageInfo
1393
1394 const Default_TaskQueueFetchQueuesResponse_Queue_Paused bool = false
1395 const Default_TaskQueueFetchQueuesResponse_Queue_Mode TaskQueueMode_Mode = TaskQueueMode_PUSH
1396 const Default_TaskQueueFetchQueuesResponse_Queue_CreatorName string = "apphosting"
1397
1398 func (m *TaskQueueFetchQueuesResponse_Queue) GetQueueName() []byte {
1399 if m != nil {
1400 return m.QueueName
1401 }
1402 return nil
1403 }
1404
1405 func (m *TaskQueueFetchQueuesResponse_Queue) GetBucketRefillPerSecond() float64 {
1406 if m != nil && m.BucketRefillPerSecond != nil {
1407 return *m.BucketRefillPerSecond
1408 }
1409 return 0
1410 }
1411
1412 func (m *TaskQueueFetchQueuesResponse_Queue) GetBucketCapacity() float64 {
1413 if m != nil && m.BucketCapacity != nil {
1414 return *m.BucketCapacity
1415 }
1416 return 0
1417 }
1418
1419 func (m *TaskQueueFetchQueuesResponse_Queue) GetUserSpecifiedRate() string {
1420 if m != nil && m.UserSpecifiedRate != nil {
1421 return *m.UserSpecifiedRate
1422 }
1423 return ""
1424 }
1425
1426 func (m *TaskQueueFetchQueuesResponse_Queue) GetPaused() bool {
1427 if m != nil && m.Paused != nil {
1428 return *m.Paused
1429 }
1430 return Default_TaskQueueFetchQueuesResponse_Queue_Paused
1431 }
1432
1433 func (m *TaskQueueFetchQueuesResponse_Queue) GetRetryParameters() *TaskQueueRetryParameters {
1434 if m != nil {
1435 return m.RetryParameters
1436 }
1437 return nil
1438 }
1439
1440 func (m *TaskQueueFetchQueuesResponse_Queue) GetMaxConcurrentRequests() int32 {
1441 if m != nil && m.MaxConcurrentRequests != nil {
1442 return *m.MaxConcurrentRequests
1443 }
1444 return 0
1445 }
1446
1447 func (m *TaskQueueFetchQueuesResponse_Queue) GetMode() TaskQueueMode_Mode {
1448 if m != nil && m.Mode != nil {
1449 return *m.Mode
1450 }
1451 return Default_TaskQueueFetchQueuesResponse_Queue_Mode
1452 }
1453
1454 func (m *TaskQueueFetchQueuesResponse_Queue) GetAcl() *TaskQueueAcl {
1455 if m != nil {
1456 return m.Acl
1457 }
1458 return nil
1459 }
1460
1461 func (m *TaskQueueFetchQueuesResponse_Queue) GetHeaderOverride() []*TaskQueueHttpHeader {
1462 if m != nil {
1463 return m.HeaderOverride
1464 }
1465 return nil
1466 }
1467
1468 func (m *TaskQueueFetchQueuesResponse_Queue) GetCreatorName() string {
1469 if m != nil && m.CreatorName != nil {
1470 return *m.CreatorName
1471 }
1472 return Default_TaskQueueFetchQueuesResponse_Queue_CreatorName
1473 }
1474
1475 type TaskQueueFetchQueueStatsRequest struct {
1476 AppId []byte `protobuf:"bytes,1,opt,name=app_id,json=appId" json:"app_id,omitempty"`
1477 QueueName [][]byte `protobuf:"bytes,2,rep,name=queue_name,json=queueName" json:"queue_name,omitempty"`
1478 MaxNumTasks *int32 `protobuf:"varint,3,opt,name=max_num_tasks,json=maxNumTasks,def=0" json:"max_num_tasks,omitempty"`
1479 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1480 XXX_unrecognized []byte `json:"-"`
1481 XXX_sizecache int32 `json:"-"`
1482 }
1483
1484 func (m *TaskQueueFetchQueueStatsRequest) Reset() { *m = TaskQueueFetchQueueStatsRequest{} }
1485 func (m *TaskQueueFetchQueueStatsRequest) String() string { return proto.CompactTextString(m) }
1486 func (*TaskQueueFetchQueueStatsRequest) ProtoMessage() {}
1487 func (*TaskQueueFetchQueueStatsRequest) Descriptor() ([]byte, []int) {
1488 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{18}
1489 }
1490 func (m *TaskQueueFetchQueueStatsRequest) XXX_Unmarshal(b []byte) error {
1491 return xxx_messageInfo_TaskQueueFetchQueueStatsRequest.Unmarshal(m, b)
1492 }
1493 func (m *TaskQueueFetchQueueStatsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1494 return xxx_messageInfo_TaskQueueFetchQueueStatsRequest.Marshal(b, m, deterministic)
1495 }
1496 func (dst *TaskQueueFetchQueueStatsRequest) XXX_Merge(src proto.Message) {
1497 xxx_messageInfo_TaskQueueFetchQueueStatsRequest.Merge(dst, src)
1498 }
1499 func (m *TaskQueueFetchQueueStatsRequest) XXX_Size() int {
1500 return xxx_messageInfo_TaskQueueFetchQueueStatsRequest.Size(m)
1501 }
1502 func (m *TaskQueueFetchQueueStatsRequest) XXX_DiscardUnknown() {
1503 xxx_messageInfo_TaskQueueFetchQueueStatsRequest.DiscardUnknown(m)
1504 }
1505
1506 var xxx_messageInfo_TaskQueueFetchQueueStatsRequest proto.InternalMessageInfo
1507
1508 const Default_TaskQueueFetchQueueStatsRequest_MaxNumTasks int32 = 0
1509
1510 func (m *TaskQueueFetchQueueStatsRequest) GetAppId() []byte {
1511 if m != nil {
1512 return m.AppId
1513 }
1514 return nil
1515 }
1516
1517 func (m *TaskQueueFetchQueueStatsRequest) GetQueueName() [][]byte {
1518 if m != nil {
1519 return m.QueueName
1520 }
1521 return nil
1522 }
1523
1524 func (m *TaskQueueFetchQueueStatsRequest) GetMaxNumTasks() int32 {
1525 if m != nil && m.MaxNumTasks != nil {
1526 return *m.MaxNumTasks
1527 }
1528 return Default_TaskQueueFetchQueueStatsRequest_MaxNumTasks
1529 }
1530
1531 type TaskQueueScannerQueueInfo struct {
1532 ExecutedLastMinute *int64 `protobuf:"varint,1,req,name=executed_last_minute,json=executedLastMinute" json:"executed_last_minute,omitempty"`
1533 ExecutedLastHour *int64 `protobuf:"varint,2,req,name=executed_last_hour,json=executedLastHour" json:"executed_last_hour,omitempty"`
1534 SamplingDurationSeconds *float64 `protobuf:"fixed64,3,req,name=sampling_duration_seconds,json=samplingDurationSeconds" json:"sampling_duration_seconds,omitempty"`
1535 RequestsInFlight *int32 `protobuf:"varint,4,opt,name=requests_in_flight,json=requestsInFlight" json:"requests_in_flight,omitempty"`
1536 EnforcedRate *float64 `protobuf:"fixed64,5,opt,name=enforced_rate,json=enforcedRate" json:"enforced_rate,omitempty"`
1537 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1538 XXX_unrecognized []byte `json:"-"`
1539 XXX_sizecache int32 `json:"-"`
1540 }
1541
1542 func (m *TaskQueueScannerQueueInfo) Reset() { *m = TaskQueueScannerQueueInfo{} }
1543 func (m *TaskQueueScannerQueueInfo) String() string { return proto.CompactTextString(m) }
1544 func (*TaskQueueScannerQueueInfo) ProtoMessage() {}
1545 func (*TaskQueueScannerQueueInfo) Descriptor() ([]byte, []int) {
1546 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{19}
1547 }
1548 func (m *TaskQueueScannerQueueInfo) XXX_Unmarshal(b []byte) error {
1549 return xxx_messageInfo_TaskQueueScannerQueueInfo.Unmarshal(m, b)
1550 }
1551 func (m *TaskQueueScannerQueueInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1552 return xxx_messageInfo_TaskQueueScannerQueueInfo.Marshal(b, m, deterministic)
1553 }
1554 func (dst *TaskQueueScannerQueueInfo) XXX_Merge(src proto.Message) {
1555 xxx_messageInfo_TaskQueueScannerQueueInfo.Merge(dst, src)
1556 }
1557 func (m *TaskQueueScannerQueueInfo) XXX_Size() int {
1558 return xxx_messageInfo_TaskQueueScannerQueueInfo.Size(m)
1559 }
1560 func (m *TaskQueueScannerQueueInfo) XXX_DiscardUnknown() {
1561 xxx_messageInfo_TaskQueueScannerQueueInfo.DiscardUnknown(m)
1562 }
1563
1564 var xxx_messageInfo_TaskQueueScannerQueueInfo proto.InternalMessageInfo
1565
1566 func (m *TaskQueueScannerQueueInfo) GetExecutedLastMinute() int64 {
1567 if m != nil && m.ExecutedLastMinute != nil {
1568 return *m.ExecutedLastMinute
1569 }
1570 return 0
1571 }
1572
1573 func (m *TaskQueueScannerQueueInfo) GetExecutedLastHour() int64 {
1574 if m != nil && m.ExecutedLastHour != nil {
1575 return *m.ExecutedLastHour
1576 }
1577 return 0
1578 }
1579
1580 func (m *TaskQueueScannerQueueInfo) GetSamplingDurationSeconds() float64 {
1581 if m != nil && m.SamplingDurationSeconds != nil {
1582 return *m.SamplingDurationSeconds
1583 }
1584 return 0
1585 }
1586
1587 func (m *TaskQueueScannerQueueInfo) GetRequestsInFlight() int32 {
1588 if m != nil && m.RequestsInFlight != nil {
1589 return *m.RequestsInFlight
1590 }
1591 return 0
1592 }
1593
1594 func (m *TaskQueueScannerQueueInfo) GetEnforcedRate() float64 {
1595 if m != nil && m.EnforcedRate != nil {
1596 return *m.EnforcedRate
1597 }
1598 return 0
1599 }
1600
1601 type TaskQueueFetchQueueStatsResponse struct {
1602 Queuestats []*TaskQueueFetchQueueStatsResponse_QueueStats `protobuf:"group,1,rep,name=QueueStats,json=queuestats" json:"queuestats,omitempty"`
1603 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1604 XXX_unrecognized []byte `json:"-"`
1605 XXX_sizecache int32 `json:"-"`
1606 }
1607
1608 func (m *TaskQueueFetchQueueStatsResponse) Reset() { *m = TaskQueueFetchQueueStatsResponse{} }
1609 func (m *TaskQueueFetchQueueStatsResponse) String() string { return proto.CompactTextString(m) }
1610 func (*TaskQueueFetchQueueStatsResponse) ProtoMessage() {}
1611 func (*TaskQueueFetchQueueStatsResponse) Descriptor() ([]byte, []int) {
1612 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{20}
1613 }
1614 func (m *TaskQueueFetchQueueStatsResponse) XXX_Unmarshal(b []byte) error {
1615 return xxx_messageInfo_TaskQueueFetchQueueStatsResponse.Unmarshal(m, b)
1616 }
1617 func (m *TaskQueueFetchQueueStatsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1618 return xxx_messageInfo_TaskQueueFetchQueueStatsResponse.Marshal(b, m, deterministic)
1619 }
1620 func (dst *TaskQueueFetchQueueStatsResponse) XXX_Merge(src proto.Message) {
1621 xxx_messageInfo_TaskQueueFetchQueueStatsResponse.Merge(dst, src)
1622 }
1623 func (m *TaskQueueFetchQueueStatsResponse) XXX_Size() int {
1624 return xxx_messageInfo_TaskQueueFetchQueueStatsResponse.Size(m)
1625 }
1626 func (m *TaskQueueFetchQueueStatsResponse) XXX_DiscardUnknown() {
1627 xxx_messageInfo_TaskQueueFetchQueueStatsResponse.DiscardUnknown(m)
1628 }
1629
1630 var xxx_messageInfo_TaskQueueFetchQueueStatsResponse proto.InternalMessageInfo
1631
1632 func (m *TaskQueueFetchQueueStatsResponse) GetQueuestats() []*TaskQueueFetchQueueStatsResponse_QueueStats {
1633 if m != nil {
1634 return m.Queuestats
1635 }
1636 return nil
1637 }
1638
1639 type TaskQueueFetchQueueStatsResponse_QueueStats struct {
1640 NumTasks *int32 `protobuf:"varint,2,req,name=num_tasks,json=numTasks" json:"num_tasks,omitempty"`
1641 OldestEtaUsec *int64 `protobuf:"varint,3,req,name=oldest_eta_usec,json=oldestEtaUsec" json:"oldest_eta_usec,omitempty"`
1642 ScannerInfo *TaskQueueScannerQueueInfo `protobuf:"bytes,4,opt,name=scanner_info,json=scannerInfo" json:"scanner_info,omitempty"`
1643 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1644 XXX_unrecognized []byte `json:"-"`
1645 XXX_sizecache int32 `json:"-"`
1646 }
1647
1648 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) Reset() {
1649 *m = TaskQueueFetchQueueStatsResponse_QueueStats{}
1650 }
1651 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) String() string {
1652 return proto.CompactTextString(m)
1653 }
1654 func (*TaskQueueFetchQueueStatsResponse_QueueStats) ProtoMessage() {}
1655 func (*TaskQueueFetchQueueStatsResponse_QueueStats) Descriptor() ([]byte, []int) {
1656 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{20, 0}
1657 }
1658 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) XXX_Unmarshal(b []byte) error {
1659 return xxx_messageInfo_TaskQueueFetchQueueStatsResponse_QueueStats.Unmarshal(m, b)
1660 }
1661 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1662 return xxx_messageInfo_TaskQueueFetchQueueStatsResponse_QueueStats.Marshal(b, m, deterministic)
1663 }
1664 func (dst *TaskQueueFetchQueueStatsResponse_QueueStats) XXX_Merge(src proto.Message) {
1665 xxx_messageInfo_TaskQueueFetchQueueStatsResponse_QueueStats.Merge(dst, src)
1666 }
1667 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) XXX_Size() int {
1668 return xxx_messageInfo_TaskQueueFetchQueueStatsResponse_QueueStats.Size(m)
1669 }
1670 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) XXX_DiscardUnknown() {
1671 xxx_messageInfo_TaskQueueFetchQueueStatsResponse_QueueStats.DiscardUnknown(m)
1672 }
1673
1674 var xxx_messageInfo_TaskQueueFetchQueueStatsResponse_QueueStats proto.InternalMessageInfo
1675
1676 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) GetNumTasks() int32 {
1677 if m != nil && m.NumTasks != nil {
1678 return *m.NumTasks
1679 }
1680 return 0
1681 }
1682
1683 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) GetOldestEtaUsec() int64 {
1684 if m != nil && m.OldestEtaUsec != nil {
1685 return *m.OldestEtaUsec
1686 }
1687 return 0
1688 }
1689
1690 func (m *TaskQueueFetchQueueStatsResponse_QueueStats) GetScannerInfo() *TaskQueueScannerQueueInfo {
1691 if m != nil {
1692 return m.ScannerInfo
1693 }
1694 return nil
1695 }
1696
1697 type TaskQueuePauseQueueRequest struct {
1698 AppId []byte `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
1699 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
1700 Pause *bool `protobuf:"varint,3,req,name=pause" json:"pause,omitempty"`
1701 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1702 XXX_unrecognized []byte `json:"-"`
1703 XXX_sizecache int32 `json:"-"`
1704 }
1705
1706 func (m *TaskQueuePauseQueueRequest) Reset() { *m = TaskQueuePauseQueueRequest{} }
1707 func (m *TaskQueuePauseQueueRequest) String() string { return proto.CompactTextString(m) }
1708 func (*TaskQueuePauseQueueRequest) ProtoMessage() {}
1709 func (*TaskQueuePauseQueueRequest) Descriptor() ([]byte, []int) {
1710 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{21}
1711 }
1712 func (m *TaskQueuePauseQueueRequest) XXX_Unmarshal(b []byte) error {
1713 return xxx_messageInfo_TaskQueuePauseQueueRequest.Unmarshal(m, b)
1714 }
1715 func (m *TaskQueuePauseQueueRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1716 return xxx_messageInfo_TaskQueuePauseQueueRequest.Marshal(b, m, deterministic)
1717 }
1718 func (dst *TaskQueuePauseQueueRequest) XXX_Merge(src proto.Message) {
1719 xxx_messageInfo_TaskQueuePauseQueueRequest.Merge(dst, src)
1720 }
1721 func (m *TaskQueuePauseQueueRequest) XXX_Size() int {
1722 return xxx_messageInfo_TaskQueuePauseQueueRequest.Size(m)
1723 }
1724 func (m *TaskQueuePauseQueueRequest) XXX_DiscardUnknown() {
1725 xxx_messageInfo_TaskQueuePauseQueueRequest.DiscardUnknown(m)
1726 }
1727
1728 var xxx_messageInfo_TaskQueuePauseQueueRequest proto.InternalMessageInfo
1729
1730 func (m *TaskQueuePauseQueueRequest) GetAppId() []byte {
1731 if m != nil {
1732 return m.AppId
1733 }
1734 return nil
1735 }
1736
1737 func (m *TaskQueuePauseQueueRequest) GetQueueName() []byte {
1738 if m != nil {
1739 return m.QueueName
1740 }
1741 return nil
1742 }
1743
1744 func (m *TaskQueuePauseQueueRequest) GetPause() bool {
1745 if m != nil && m.Pause != nil {
1746 return *m.Pause
1747 }
1748 return false
1749 }
1750
1751 type TaskQueuePauseQueueResponse struct {
1752 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1753 XXX_unrecognized []byte `json:"-"`
1754 XXX_sizecache int32 `json:"-"`
1755 }
1756
1757 func (m *TaskQueuePauseQueueResponse) Reset() { *m = TaskQueuePauseQueueResponse{} }
1758 func (m *TaskQueuePauseQueueResponse) String() string { return proto.CompactTextString(m) }
1759 func (*TaskQueuePauseQueueResponse) ProtoMessage() {}
1760 func (*TaskQueuePauseQueueResponse) Descriptor() ([]byte, []int) {
1761 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{22}
1762 }
1763 func (m *TaskQueuePauseQueueResponse) XXX_Unmarshal(b []byte) error {
1764 return xxx_messageInfo_TaskQueuePauseQueueResponse.Unmarshal(m, b)
1765 }
1766 func (m *TaskQueuePauseQueueResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1767 return xxx_messageInfo_TaskQueuePauseQueueResponse.Marshal(b, m, deterministic)
1768 }
1769 func (dst *TaskQueuePauseQueueResponse) XXX_Merge(src proto.Message) {
1770 xxx_messageInfo_TaskQueuePauseQueueResponse.Merge(dst, src)
1771 }
1772 func (m *TaskQueuePauseQueueResponse) XXX_Size() int {
1773 return xxx_messageInfo_TaskQueuePauseQueueResponse.Size(m)
1774 }
1775 func (m *TaskQueuePauseQueueResponse) XXX_DiscardUnknown() {
1776 xxx_messageInfo_TaskQueuePauseQueueResponse.DiscardUnknown(m)
1777 }
1778
1779 var xxx_messageInfo_TaskQueuePauseQueueResponse proto.InternalMessageInfo
1780
1781 type TaskQueuePurgeQueueRequest struct {
1782 AppId []byte `protobuf:"bytes,1,opt,name=app_id,json=appId" json:"app_id,omitempty"`
1783 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
1784 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1785 XXX_unrecognized []byte `json:"-"`
1786 XXX_sizecache int32 `json:"-"`
1787 }
1788
1789 func (m *TaskQueuePurgeQueueRequest) Reset() { *m = TaskQueuePurgeQueueRequest{} }
1790 func (m *TaskQueuePurgeQueueRequest) String() string { return proto.CompactTextString(m) }
1791 func (*TaskQueuePurgeQueueRequest) ProtoMessage() {}
1792 func (*TaskQueuePurgeQueueRequest) Descriptor() ([]byte, []int) {
1793 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{23}
1794 }
1795 func (m *TaskQueuePurgeQueueRequest) XXX_Unmarshal(b []byte) error {
1796 return xxx_messageInfo_TaskQueuePurgeQueueRequest.Unmarshal(m, b)
1797 }
1798 func (m *TaskQueuePurgeQueueRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1799 return xxx_messageInfo_TaskQueuePurgeQueueRequest.Marshal(b, m, deterministic)
1800 }
1801 func (dst *TaskQueuePurgeQueueRequest) XXX_Merge(src proto.Message) {
1802 xxx_messageInfo_TaskQueuePurgeQueueRequest.Merge(dst, src)
1803 }
1804 func (m *TaskQueuePurgeQueueRequest) XXX_Size() int {
1805 return xxx_messageInfo_TaskQueuePurgeQueueRequest.Size(m)
1806 }
1807 func (m *TaskQueuePurgeQueueRequest) XXX_DiscardUnknown() {
1808 xxx_messageInfo_TaskQueuePurgeQueueRequest.DiscardUnknown(m)
1809 }
1810
1811 var xxx_messageInfo_TaskQueuePurgeQueueRequest proto.InternalMessageInfo
1812
1813 func (m *TaskQueuePurgeQueueRequest) GetAppId() []byte {
1814 if m != nil {
1815 return m.AppId
1816 }
1817 return nil
1818 }
1819
1820 func (m *TaskQueuePurgeQueueRequest) GetQueueName() []byte {
1821 if m != nil {
1822 return m.QueueName
1823 }
1824 return nil
1825 }
1826
1827 type TaskQueuePurgeQueueResponse struct {
1828 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1829 XXX_unrecognized []byte `json:"-"`
1830 XXX_sizecache int32 `json:"-"`
1831 }
1832
1833 func (m *TaskQueuePurgeQueueResponse) Reset() { *m = TaskQueuePurgeQueueResponse{} }
1834 func (m *TaskQueuePurgeQueueResponse) String() string { return proto.CompactTextString(m) }
1835 func (*TaskQueuePurgeQueueResponse) ProtoMessage() {}
1836 func (*TaskQueuePurgeQueueResponse) Descriptor() ([]byte, []int) {
1837 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{24}
1838 }
1839 func (m *TaskQueuePurgeQueueResponse) XXX_Unmarshal(b []byte) error {
1840 return xxx_messageInfo_TaskQueuePurgeQueueResponse.Unmarshal(m, b)
1841 }
1842 func (m *TaskQueuePurgeQueueResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1843 return xxx_messageInfo_TaskQueuePurgeQueueResponse.Marshal(b, m, deterministic)
1844 }
1845 func (dst *TaskQueuePurgeQueueResponse) XXX_Merge(src proto.Message) {
1846 xxx_messageInfo_TaskQueuePurgeQueueResponse.Merge(dst, src)
1847 }
1848 func (m *TaskQueuePurgeQueueResponse) XXX_Size() int {
1849 return xxx_messageInfo_TaskQueuePurgeQueueResponse.Size(m)
1850 }
1851 func (m *TaskQueuePurgeQueueResponse) XXX_DiscardUnknown() {
1852 xxx_messageInfo_TaskQueuePurgeQueueResponse.DiscardUnknown(m)
1853 }
1854
1855 var xxx_messageInfo_TaskQueuePurgeQueueResponse proto.InternalMessageInfo
1856
1857 type TaskQueueDeleteQueueRequest struct {
1858 AppId []byte `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
1859 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
1860 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1861 XXX_unrecognized []byte `json:"-"`
1862 XXX_sizecache int32 `json:"-"`
1863 }
1864
1865 func (m *TaskQueueDeleteQueueRequest) Reset() { *m = TaskQueueDeleteQueueRequest{} }
1866 func (m *TaskQueueDeleteQueueRequest) String() string { return proto.CompactTextString(m) }
1867 func (*TaskQueueDeleteQueueRequest) ProtoMessage() {}
1868 func (*TaskQueueDeleteQueueRequest) Descriptor() ([]byte, []int) {
1869 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{25}
1870 }
1871 func (m *TaskQueueDeleteQueueRequest) XXX_Unmarshal(b []byte) error {
1872 return xxx_messageInfo_TaskQueueDeleteQueueRequest.Unmarshal(m, b)
1873 }
1874 func (m *TaskQueueDeleteQueueRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1875 return xxx_messageInfo_TaskQueueDeleteQueueRequest.Marshal(b, m, deterministic)
1876 }
1877 func (dst *TaskQueueDeleteQueueRequest) XXX_Merge(src proto.Message) {
1878 xxx_messageInfo_TaskQueueDeleteQueueRequest.Merge(dst, src)
1879 }
1880 func (m *TaskQueueDeleteQueueRequest) XXX_Size() int {
1881 return xxx_messageInfo_TaskQueueDeleteQueueRequest.Size(m)
1882 }
1883 func (m *TaskQueueDeleteQueueRequest) XXX_DiscardUnknown() {
1884 xxx_messageInfo_TaskQueueDeleteQueueRequest.DiscardUnknown(m)
1885 }
1886
1887 var xxx_messageInfo_TaskQueueDeleteQueueRequest proto.InternalMessageInfo
1888
1889 func (m *TaskQueueDeleteQueueRequest) GetAppId() []byte {
1890 if m != nil {
1891 return m.AppId
1892 }
1893 return nil
1894 }
1895
1896 func (m *TaskQueueDeleteQueueRequest) GetQueueName() []byte {
1897 if m != nil {
1898 return m.QueueName
1899 }
1900 return nil
1901 }
1902
1903 type TaskQueueDeleteQueueResponse struct {
1904 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1905 XXX_unrecognized []byte `json:"-"`
1906 XXX_sizecache int32 `json:"-"`
1907 }
1908
1909 func (m *TaskQueueDeleteQueueResponse) Reset() { *m = TaskQueueDeleteQueueResponse{} }
1910 func (m *TaskQueueDeleteQueueResponse) String() string { return proto.CompactTextString(m) }
1911 func (*TaskQueueDeleteQueueResponse) ProtoMessage() {}
1912 func (*TaskQueueDeleteQueueResponse) Descriptor() ([]byte, []int) {
1913 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{26}
1914 }
1915 func (m *TaskQueueDeleteQueueResponse) XXX_Unmarshal(b []byte) error {
1916 return xxx_messageInfo_TaskQueueDeleteQueueResponse.Unmarshal(m, b)
1917 }
1918 func (m *TaskQueueDeleteQueueResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1919 return xxx_messageInfo_TaskQueueDeleteQueueResponse.Marshal(b, m, deterministic)
1920 }
1921 func (dst *TaskQueueDeleteQueueResponse) XXX_Merge(src proto.Message) {
1922 xxx_messageInfo_TaskQueueDeleteQueueResponse.Merge(dst, src)
1923 }
1924 func (m *TaskQueueDeleteQueueResponse) XXX_Size() int {
1925 return xxx_messageInfo_TaskQueueDeleteQueueResponse.Size(m)
1926 }
1927 func (m *TaskQueueDeleteQueueResponse) XXX_DiscardUnknown() {
1928 xxx_messageInfo_TaskQueueDeleteQueueResponse.DiscardUnknown(m)
1929 }
1930
1931 var xxx_messageInfo_TaskQueueDeleteQueueResponse proto.InternalMessageInfo
1932
1933 type TaskQueueDeleteGroupRequest struct {
1934 AppId []byte `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
1935 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1936 XXX_unrecognized []byte `json:"-"`
1937 XXX_sizecache int32 `json:"-"`
1938 }
1939
1940 func (m *TaskQueueDeleteGroupRequest) Reset() { *m = TaskQueueDeleteGroupRequest{} }
1941 func (m *TaskQueueDeleteGroupRequest) String() string { return proto.CompactTextString(m) }
1942 func (*TaskQueueDeleteGroupRequest) ProtoMessage() {}
1943 func (*TaskQueueDeleteGroupRequest) Descriptor() ([]byte, []int) {
1944 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{27}
1945 }
1946 func (m *TaskQueueDeleteGroupRequest) XXX_Unmarshal(b []byte) error {
1947 return xxx_messageInfo_TaskQueueDeleteGroupRequest.Unmarshal(m, b)
1948 }
1949 func (m *TaskQueueDeleteGroupRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1950 return xxx_messageInfo_TaskQueueDeleteGroupRequest.Marshal(b, m, deterministic)
1951 }
1952 func (dst *TaskQueueDeleteGroupRequest) XXX_Merge(src proto.Message) {
1953 xxx_messageInfo_TaskQueueDeleteGroupRequest.Merge(dst, src)
1954 }
1955 func (m *TaskQueueDeleteGroupRequest) XXX_Size() int {
1956 return xxx_messageInfo_TaskQueueDeleteGroupRequest.Size(m)
1957 }
1958 func (m *TaskQueueDeleteGroupRequest) XXX_DiscardUnknown() {
1959 xxx_messageInfo_TaskQueueDeleteGroupRequest.DiscardUnknown(m)
1960 }
1961
1962 var xxx_messageInfo_TaskQueueDeleteGroupRequest proto.InternalMessageInfo
1963
1964 func (m *TaskQueueDeleteGroupRequest) GetAppId() []byte {
1965 if m != nil {
1966 return m.AppId
1967 }
1968 return nil
1969 }
1970
1971 type TaskQueueDeleteGroupResponse struct {
1972 XXX_NoUnkeyedLiteral struct{} `json:"-"`
1973 XXX_unrecognized []byte `json:"-"`
1974 XXX_sizecache int32 `json:"-"`
1975 }
1976
1977 func (m *TaskQueueDeleteGroupResponse) Reset() { *m = TaskQueueDeleteGroupResponse{} }
1978 func (m *TaskQueueDeleteGroupResponse) String() string { return proto.CompactTextString(m) }
1979 func (*TaskQueueDeleteGroupResponse) ProtoMessage() {}
1980 func (*TaskQueueDeleteGroupResponse) Descriptor() ([]byte, []int) {
1981 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{28}
1982 }
1983 func (m *TaskQueueDeleteGroupResponse) XXX_Unmarshal(b []byte) error {
1984 return xxx_messageInfo_TaskQueueDeleteGroupResponse.Unmarshal(m, b)
1985 }
1986 func (m *TaskQueueDeleteGroupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
1987 return xxx_messageInfo_TaskQueueDeleteGroupResponse.Marshal(b, m, deterministic)
1988 }
1989 func (dst *TaskQueueDeleteGroupResponse) XXX_Merge(src proto.Message) {
1990 xxx_messageInfo_TaskQueueDeleteGroupResponse.Merge(dst, src)
1991 }
1992 func (m *TaskQueueDeleteGroupResponse) XXX_Size() int {
1993 return xxx_messageInfo_TaskQueueDeleteGroupResponse.Size(m)
1994 }
1995 func (m *TaskQueueDeleteGroupResponse) XXX_DiscardUnknown() {
1996 xxx_messageInfo_TaskQueueDeleteGroupResponse.DiscardUnknown(m)
1997 }
1998
1999 var xxx_messageInfo_TaskQueueDeleteGroupResponse proto.InternalMessageInfo
2000
2001 type TaskQueueQueryTasksRequest struct {
2002 AppId []byte `protobuf:"bytes,1,opt,name=app_id,json=appId" json:"app_id,omitempty"`
2003 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
2004 StartTaskName []byte `protobuf:"bytes,3,opt,name=start_task_name,json=startTaskName" json:"start_task_name,omitempty"`
2005 StartEtaUsec *int64 `protobuf:"varint,4,opt,name=start_eta_usec,json=startEtaUsec" json:"start_eta_usec,omitempty"`
2006 StartTag []byte `protobuf:"bytes,6,opt,name=start_tag,json=startTag" json:"start_tag,omitempty"`
2007 MaxRows *int32 `protobuf:"varint,5,opt,name=max_rows,json=maxRows,def=1" json:"max_rows,omitempty"`
2008 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2009 XXX_unrecognized []byte `json:"-"`
2010 XXX_sizecache int32 `json:"-"`
2011 }
2012
2013 func (m *TaskQueueQueryTasksRequest) Reset() { *m = TaskQueueQueryTasksRequest{} }
2014 func (m *TaskQueueQueryTasksRequest) String() string { return proto.CompactTextString(m) }
2015 func (*TaskQueueQueryTasksRequest) ProtoMessage() {}
2016 func (*TaskQueueQueryTasksRequest) Descriptor() ([]byte, []int) {
2017 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{29}
2018 }
2019 func (m *TaskQueueQueryTasksRequest) XXX_Unmarshal(b []byte) error {
2020 return xxx_messageInfo_TaskQueueQueryTasksRequest.Unmarshal(m, b)
2021 }
2022 func (m *TaskQueueQueryTasksRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2023 return xxx_messageInfo_TaskQueueQueryTasksRequest.Marshal(b, m, deterministic)
2024 }
2025 func (dst *TaskQueueQueryTasksRequest) XXX_Merge(src proto.Message) {
2026 xxx_messageInfo_TaskQueueQueryTasksRequest.Merge(dst, src)
2027 }
2028 func (m *TaskQueueQueryTasksRequest) XXX_Size() int {
2029 return xxx_messageInfo_TaskQueueQueryTasksRequest.Size(m)
2030 }
2031 func (m *TaskQueueQueryTasksRequest) XXX_DiscardUnknown() {
2032 xxx_messageInfo_TaskQueueQueryTasksRequest.DiscardUnknown(m)
2033 }
2034
2035 var xxx_messageInfo_TaskQueueQueryTasksRequest proto.InternalMessageInfo
2036
2037 const Default_TaskQueueQueryTasksRequest_MaxRows int32 = 1
2038
2039 func (m *TaskQueueQueryTasksRequest) GetAppId() []byte {
2040 if m != nil {
2041 return m.AppId
2042 }
2043 return nil
2044 }
2045
2046 func (m *TaskQueueQueryTasksRequest) GetQueueName() []byte {
2047 if m != nil {
2048 return m.QueueName
2049 }
2050 return nil
2051 }
2052
2053 func (m *TaskQueueQueryTasksRequest) GetStartTaskName() []byte {
2054 if m != nil {
2055 return m.StartTaskName
2056 }
2057 return nil
2058 }
2059
2060 func (m *TaskQueueQueryTasksRequest) GetStartEtaUsec() int64 {
2061 if m != nil && m.StartEtaUsec != nil {
2062 return *m.StartEtaUsec
2063 }
2064 return 0
2065 }
2066
2067 func (m *TaskQueueQueryTasksRequest) GetStartTag() []byte {
2068 if m != nil {
2069 return m.StartTag
2070 }
2071 return nil
2072 }
2073
2074 func (m *TaskQueueQueryTasksRequest) GetMaxRows() int32 {
2075 if m != nil && m.MaxRows != nil {
2076 return *m.MaxRows
2077 }
2078 return Default_TaskQueueQueryTasksRequest_MaxRows
2079 }
2080
2081 type TaskQueueQueryTasksResponse struct {
2082 Task []*TaskQueueQueryTasksResponse_Task `protobuf:"group,1,rep,name=Task,json=task" json:"task,omitempty"`
2083 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2084 XXX_unrecognized []byte `json:"-"`
2085 XXX_sizecache int32 `json:"-"`
2086 }
2087
2088 func (m *TaskQueueQueryTasksResponse) Reset() { *m = TaskQueueQueryTasksResponse{} }
2089 func (m *TaskQueueQueryTasksResponse) String() string { return proto.CompactTextString(m) }
2090 func (*TaskQueueQueryTasksResponse) ProtoMessage() {}
2091 func (*TaskQueueQueryTasksResponse) Descriptor() ([]byte, []int) {
2092 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{30}
2093 }
2094 func (m *TaskQueueQueryTasksResponse) XXX_Unmarshal(b []byte) error {
2095 return xxx_messageInfo_TaskQueueQueryTasksResponse.Unmarshal(m, b)
2096 }
2097 func (m *TaskQueueQueryTasksResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2098 return xxx_messageInfo_TaskQueueQueryTasksResponse.Marshal(b, m, deterministic)
2099 }
2100 func (dst *TaskQueueQueryTasksResponse) XXX_Merge(src proto.Message) {
2101 xxx_messageInfo_TaskQueueQueryTasksResponse.Merge(dst, src)
2102 }
2103 func (m *TaskQueueQueryTasksResponse) XXX_Size() int {
2104 return xxx_messageInfo_TaskQueueQueryTasksResponse.Size(m)
2105 }
2106 func (m *TaskQueueQueryTasksResponse) XXX_DiscardUnknown() {
2107 xxx_messageInfo_TaskQueueQueryTasksResponse.DiscardUnknown(m)
2108 }
2109
2110 var xxx_messageInfo_TaskQueueQueryTasksResponse proto.InternalMessageInfo
2111
2112 func (m *TaskQueueQueryTasksResponse) GetTask() []*TaskQueueQueryTasksResponse_Task {
2113 if m != nil {
2114 return m.Task
2115 }
2116 return nil
2117 }
2118
2119 type TaskQueueQueryTasksResponse_Task struct {
2120 TaskName []byte `protobuf:"bytes,2,req,name=task_name,json=taskName" json:"task_name,omitempty"`
2121 EtaUsec *int64 `protobuf:"varint,3,req,name=eta_usec,json=etaUsec" json:"eta_usec,omitempty"`
2122 Url []byte `protobuf:"bytes,4,opt,name=url" json:"url,omitempty"`
2123 Method *TaskQueueQueryTasksResponse_Task_RequestMethod `protobuf:"varint,5,opt,name=method,enum=appengine.TaskQueueQueryTasksResponse_Task_RequestMethod" json:"method,omitempty"`
2124 RetryCount *int32 `protobuf:"varint,6,opt,name=retry_count,json=retryCount,def=0" json:"retry_count,omitempty"`
2125 Header []*TaskQueueQueryTasksResponse_Task_Header `protobuf:"group,7,rep,name=Header,json=header" json:"header,omitempty"`
2126 BodySize *int32 `protobuf:"varint,10,opt,name=body_size,json=bodySize" json:"body_size,omitempty"`
2127 Body []byte `protobuf:"bytes,11,opt,name=body" json:"body,omitempty"`
2128 CreationTimeUsec *int64 `protobuf:"varint,12,req,name=creation_time_usec,json=creationTimeUsec" json:"creation_time_usec,omitempty"`
2129 Crontimetable *TaskQueueQueryTasksResponse_Task_CronTimetable `protobuf:"group,13,opt,name=CronTimetable,json=crontimetable" json:"crontimetable,omitempty"`
2130 Runlog *TaskQueueQueryTasksResponse_Task_RunLog `protobuf:"group,16,opt,name=RunLog,json=runlog" json:"runlog,omitempty"`
2131 Description []byte `protobuf:"bytes,21,opt,name=description" json:"description,omitempty"`
2132 Payload *TaskPayload `protobuf:"bytes,22,opt,name=payload" json:"payload,omitempty"`
2133 RetryParameters *TaskQueueRetryParameters `protobuf:"bytes,23,opt,name=retry_parameters,json=retryParameters" json:"retry_parameters,omitempty"`
2134 FirstTryUsec *int64 `protobuf:"varint,24,opt,name=first_try_usec,json=firstTryUsec" json:"first_try_usec,omitempty"`
2135 Tag []byte `protobuf:"bytes,25,opt,name=tag" json:"tag,omitempty"`
2136 ExecutionCount *int32 `protobuf:"varint,26,opt,name=execution_count,json=executionCount,def=0" json:"execution_count,omitempty"`
2137 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2138 XXX_unrecognized []byte `json:"-"`
2139 XXX_sizecache int32 `json:"-"`
2140 }
2141
2142 func (m *TaskQueueQueryTasksResponse_Task) Reset() { *m = TaskQueueQueryTasksResponse_Task{} }
2143 func (m *TaskQueueQueryTasksResponse_Task) String() string { return proto.CompactTextString(m) }
2144 func (*TaskQueueQueryTasksResponse_Task) ProtoMessage() {}
2145 func (*TaskQueueQueryTasksResponse_Task) Descriptor() ([]byte, []int) {
2146 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{30, 0}
2147 }
2148 func (m *TaskQueueQueryTasksResponse_Task) XXX_Unmarshal(b []byte) error {
2149 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task.Unmarshal(m, b)
2150 }
2151 func (m *TaskQueueQueryTasksResponse_Task) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2152 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task.Marshal(b, m, deterministic)
2153 }
2154 func (dst *TaskQueueQueryTasksResponse_Task) XXX_Merge(src proto.Message) {
2155 xxx_messageInfo_TaskQueueQueryTasksResponse_Task.Merge(dst, src)
2156 }
2157 func (m *TaskQueueQueryTasksResponse_Task) XXX_Size() int {
2158 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task.Size(m)
2159 }
2160 func (m *TaskQueueQueryTasksResponse_Task) XXX_DiscardUnknown() {
2161 xxx_messageInfo_TaskQueueQueryTasksResponse_Task.DiscardUnknown(m)
2162 }
2163
2164 var xxx_messageInfo_TaskQueueQueryTasksResponse_Task proto.InternalMessageInfo
2165
2166 const Default_TaskQueueQueryTasksResponse_Task_RetryCount int32 = 0
2167 const Default_TaskQueueQueryTasksResponse_Task_ExecutionCount int32 = 0
2168
2169 func (m *TaskQueueQueryTasksResponse_Task) GetTaskName() []byte {
2170 if m != nil {
2171 return m.TaskName
2172 }
2173 return nil
2174 }
2175
2176 func (m *TaskQueueQueryTasksResponse_Task) GetEtaUsec() int64 {
2177 if m != nil && m.EtaUsec != nil {
2178 return *m.EtaUsec
2179 }
2180 return 0
2181 }
2182
2183 func (m *TaskQueueQueryTasksResponse_Task) GetUrl() []byte {
2184 if m != nil {
2185 return m.Url
2186 }
2187 return nil
2188 }
2189
2190 func (m *TaskQueueQueryTasksResponse_Task) GetMethod() TaskQueueQueryTasksResponse_Task_RequestMethod {
2191 if m != nil && m.Method != nil {
2192 return *m.Method
2193 }
2194 return TaskQueueQueryTasksResponse_Task_GET
2195 }
2196
2197 func (m *TaskQueueQueryTasksResponse_Task) GetRetryCount() int32 {
2198 if m != nil && m.RetryCount != nil {
2199 return *m.RetryCount
2200 }
2201 return Default_TaskQueueQueryTasksResponse_Task_RetryCount
2202 }
2203
2204 func (m *TaskQueueQueryTasksResponse_Task) GetHeader() []*TaskQueueQueryTasksResponse_Task_Header {
2205 if m != nil {
2206 return m.Header
2207 }
2208 return nil
2209 }
2210
2211 func (m *TaskQueueQueryTasksResponse_Task) GetBodySize() int32 {
2212 if m != nil && m.BodySize != nil {
2213 return *m.BodySize
2214 }
2215 return 0
2216 }
2217
2218 func (m *TaskQueueQueryTasksResponse_Task) GetBody() []byte {
2219 if m != nil {
2220 return m.Body
2221 }
2222 return nil
2223 }
2224
2225 func (m *TaskQueueQueryTasksResponse_Task) GetCreationTimeUsec() int64 {
2226 if m != nil && m.CreationTimeUsec != nil {
2227 return *m.CreationTimeUsec
2228 }
2229 return 0
2230 }
2231
2232 func (m *TaskQueueQueryTasksResponse_Task) GetCrontimetable() *TaskQueueQueryTasksResponse_Task_CronTimetable {
2233 if m != nil {
2234 return m.Crontimetable
2235 }
2236 return nil
2237 }
2238
2239 func (m *TaskQueueQueryTasksResponse_Task) GetRunlog() *TaskQueueQueryTasksResponse_Task_RunLog {
2240 if m != nil {
2241 return m.Runlog
2242 }
2243 return nil
2244 }
2245
2246 func (m *TaskQueueQueryTasksResponse_Task) GetDescription() []byte {
2247 if m != nil {
2248 return m.Description
2249 }
2250 return nil
2251 }
2252
2253 func (m *TaskQueueQueryTasksResponse_Task) GetPayload() *TaskPayload {
2254 if m != nil {
2255 return m.Payload
2256 }
2257 return nil
2258 }
2259
2260 func (m *TaskQueueQueryTasksResponse_Task) GetRetryParameters() *TaskQueueRetryParameters {
2261 if m != nil {
2262 return m.RetryParameters
2263 }
2264 return nil
2265 }
2266
2267 func (m *TaskQueueQueryTasksResponse_Task) GetFirstTryUsec() int64 {
2268 if m != nil && m.FirstTryUsec != nil {
2269 return *m.FirstTryUsec
2270 }
2271 return 0
2272 }
2273
2274 func (m *TaskQueueQueryTasksResponse_Task) GetTag() []byte {
2275 if m != nil {
2276 return m.Tag
2277 }
2278 return nil
2279 }
2280
2281 func (m *TaskQueueQueryTasksResponse_Task) GetExecutionCount() int32 {
2282 if m != nil && m.ExecutionCount != nil {
2283 return *m.ExecutionCount
2284 }
2285 return Default_TaskQueueQueryTasksResponse_Task_ExecutionCount
2286 }
2287
2288 type TaskQueueQueryTasksResponse_Task_Header struct {
2289 Key []byte `protobuf:"bytes,8,req,name=key" json:"key,omitempty"`
2290 Value []byte `protobuf:"bytes,9,req,name=value" json:"value,omitempty"`
2291 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2292 XXX_unrecognized []byte `json:"-"`
2293 XXX_sizecache int32 `json:"-"`
2294 }
2295
2296 func (m *TaskQueueQueryTasksResponse_Task_Header) Reset() {
2297 *m = TaskQueueQueryTasksResponse_Task_Header{}
2298 }
2299 func (m *TaskQueueQueryTasksResponse_Task_Header) String() string { return proto.CompactTextString(m) }
2300 func (*TaskQueueQueryTasksResponse_Task_Header) ProtoMessage() {}
2301 func (*TaskQueueQueryTasksResponse_Task_Header) Descriptor() ([]byte, []int) {
2302 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{30, 0, 0}
2303 }
2304 func (m *TaskQueueQueryTasksResponse_Task_Header) XXX_Unmarshal(b []byte) error {
2305 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_Header.Unmarshal(m, b)
2306 }
2307 func (m *TaskQueueQueryTasksResponse_Task_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2308 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_Header.Marshal(b, m, deterministic)
2309 }
2310 func (dst *TaskQueueQueryTasksResponse_Task_Header) XXX_Merge(src proto.Message) {
2311 xxx_messageInfo_TaskQueueQueryTasksResponse_Task_Header.Merge(dst, src)
2312 }
2313 func (m *TaskQueueQueryTasksResponse_Task_Header) XXX_Size() int {
2314 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_Header.Size(m)
2315 }
2316 func (m *TaskQueueQueryTasksResponse_Task_Header) XXX_DiscardUnknown() {
2317 xxx_messageInfo_TaskQueueQueryTasksResponse_Task_Header.DiscardUnknown(m)
2318 }
2319
2320 var xxx_messageInfo_TaskQueueQueryTasksResponse_Task_Header proto.InternalMessageInfo
2321
2322 func (m *TaskQueueQueryTasksResponse_Task_Header) GetKey() []byte {
2323 if m != nil {
2324 return m.Key
2325 }
2326 return nil
2327 }
2328
2329 func (m *TaskQueueQueryTasksResponse_Task_Header) GetValue() []byte {
2330 if m != nil {
2331 return m.Value
2332 }
2333 return nil
2334 }
2335
2336 type TaskQueueQueryTasksResponse_Task_CronTimetable struct {
2337 Schedule []byte `protobuf:"bytes,14,req,name=schedule" json:"schedule,omitempty"`
2338 Timezone []byte `protobuf:"bytes,15,req,name=timezone" json:"timezone,omitempty"`
2339 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2340 XXX_unrecognized []byte `json:"-"`
2341 XXX_sizecache int32 `json:"-"`
2342 }
2343
2344 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) Reset() {
2345 *m = TaskQueueQueryTasksResponse_Task_CronTimetable{}
2346 }
2347 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) String() string {
2348 return proto.CompactTextString(m)
2349 }
2350 func (*TaskQueueQueryTasksResponse_Task_CronTimetable) ProtoMessage() {}
2351 func (*TaskQueueQueryTasksResponse_Task_CronTimetable) Descriptor() ([]byte, []int) {
2352 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{30, 0, 1}
2353 }
2354 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) XXX_Unmarshal(b []byte) error {
2355 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_CronTimetable.Unmarshal(m, b)
2356 }
2357 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2358 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_CronTimetable.Marshal(b, m, deterministic)
2359 }
2360 func (dst *TaskQueueQueryTasksResponse_Task_CronTimetable) XXX_Merge(src proto.Message) {
2361 xxx_messageInfo_TaskQueueQueryTasksResponse_Task_CronTimetable.Merge(dst, src)
2362 }
2363 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) XXX_Size() int {
2364 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_CronTimetable.Size(m)
2365 }
2366 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) XXX_DiscardUnknown() {
2367 xxx_messageInfo_TaskQueueQueryTasksResponse_Task_CronTimetable.DiscardUnknown(m)
2368 }
2369
2370 var xxx_messageInfo_TaskQueueQueryTasksResponse_Task_CronTimetable proto.InternalMessageInfo
2371
2372 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) GetSchedule() []byte {
2373 if m != nil {
2374 return m.Schedule
2375 }
2376 return nil
2377 }
2378
2379 func (m *TaskQueueQueryTasksResponse_Task_CronTimetable) GetTimezone() []byte {
2380 if m != nil {
2381 return m.Timezone
2382 }
2383 return nil
2384 }
2385
2386 type TaskQueueQueryTasksResponse_Task_RunLog struct {
2387 DispatchedUsec *int64 `protobuf:"varint,17,req,name=dispatched_usec,json=dispatchedUsec" json:"dispatched_usec,omitempty"`
2388 LagUsec *int64 `protobuf:"varint,18,req,name=lag_usec,json=lagUsec" json:"lag_usec,omitempty"`
2389 ElapsedUsec *int64 `protobuf:"varint,19,req,name=elapsed_usec,json=elapsedUsec" json:"elapsed_usec,omitempty"`
2390 ResponseCode *int64 `protobuf:"varint,20,opt,name=response_code,json=responseCode" json:"response_code,omitempty"`
2391 RetryReason *string `protobuf:"bytes,27,opt,name=retry_reason,json=retryReason" json:"retry_reason,omitempty"`
2392 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2393 XXX_unrecognized []byte `json:"-"`
2394 XXX_sizecache int32 `json:"-"`
2395 }
2396
2397 func (m *TaskQueueQueryTasksResponse_Task_RunLog) Reset() {
2398 *m = TaskQueueQueryTasksResponse_Task_RunLog{}
2399 }
2400 func (m *TaskQueueQueryTasksResponse_Task_RunLog) String() string { return proto.CompactTextString(m) }
2401 func (*TaskQueueQueryTasksResponse_Task_RunLog) ProtoMessage() {}
2402 func (*TaskQueueQueryTasksResponse_Task_RunLog) Descriptor() ([]byte, []int) {
2403 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{30, 0, 2}
2404 }
2405 func (m *TaskQueueQueryTasksResponse_Task_RunLog) XXX_Unmarshal(b []byte) error {
2406 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_RunLog.Unmarshal(m, b)
2407 }
2408 func (m *TaskQueueQueryTasksResponse_Task_RunLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2409 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_RunLog.Marshal(b, m, deterministic)
2410 }
2411 func (dst *TaskQueueQueryTasksResponse_Task_RunLog) XXX_Merge(src proto.Message) {
2412 xxx_messageInfo_TaskQueueQueryTasksResponse_Task_RunLog.Merge(dst, src)
2413 }
2414 func (m *TaskQueueQueryTasksResponse_Task_RunLog) XXX_Size() int {
2415 return xxx_messageInfo_TaskQueueQueryTasksResponse_Task_RunLog.Size(m)
2416 }
2417 func (m *TaskQueueQueryTasksResponse_Task_RunLog) XXX_DiscardUnknown() {
2418 xxx_messageInfo_TaskQueueQueryTasksResponse_Task_RunLog.DiscardUnknown(m)
2419 }
2420
2421 var xxx_messageInfo_TaskQueueQueryTasksResponse_Task_RunLog proto.InternalMessageInfo
2422
2423 func (m *TaskQueueQueryTasksResponse_Task_RunLog) GetDispatchedUsec() int64 {
2424 if m != nil && m.DispatchedUsec != nil {
2425 return *m.DispatchedUsec
2426 }
2427 return 0
2428 }
2429
2430 func (m *TaskQueueQueryTasksResponse_Task_RunLog) GetLagUsec() int64 {
2431 if m != nil && m.LagUsec != nil {
2432 return *m.LagUsec
2433 }
2434 return 0
2435 }
2436
2437 func (m *TaskQueueQueryTasksResponse_Task_RunLog) GetElapsedUsec() int64 {
2438 if m != nil && m.ElapsedUsec != nil {
2439 return *m.ElapsedUsec
2440 }
2441 return 0
2442 }
2443
2444 func (m *TaskQueueQueryTasksResponse_Task_RunLog) GetResponseCode() int64 {
2445 if m != nil && m.ResponseCode != nil {
2446 return *m.ResponseCode
2447 }
2448 return 0
2449 }
2450
2451 func (m *TaskQueueQueryTasksResponse_Task_RunLog) GetRetryReason() string {
2452 if m != nil && m.RetryReason != nil {
2453 return *m.RetryReason
2454 }
2455 return ""
2456 }
2457
2458 type TaskQueueFetchTaskRequest struct {
2459 AppId []byte `protobuf:"bytes,1,opt,name=app_id,json=appId" json:"app_id,omitempty"`
2460 QueueName []byte `protobuf:"bytes,2,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
2461 TaskName []byte `protobuf:"bytes,3,req,name=task_name,json=taskName" json:"task_name,omitempty"`
2462 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2463 XXX_unrecognized []byte `json:"-"`
2464 XXX_sizecache int32 `json:"-"`
2465 }
2466
2467 func (m *TaskQueueFetchTaskRequest) Reset() { *m = TaskQueueFetchTaskRequest{} }
2468 func (m *TaskQueueFetchTaskRequest) String() string { return proto.CompactTextString(m) }
2469 func (*TaskQueueFetchTaskRequest) ProtoMessage() {}
2470 func (*TaskQueueFetchTaskRequest) Descriptor() ([]byte, []int) {
2471 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{31}
2472 }
2473 func (m *TaskQueueFetchTaskRequest) XXX_Unmarshal(b []byte) error {
2474 return xxx_messageInfo_TaskQueueFetchTaskRequest.Unmarshal(m, b)
2475 }
2476 func (m *TaskQueueFetchTaskRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2477 return xxx_messageInfo_TaskQueueFetchTaskRequest.Marshal(b, m, deterministic)
2478 }
2479 func (dst *TaskQueueFetchTaskRequest) XXX_Merge(src proto.Message) {
2480 xxx_messageInfo_TaskQueueFetchTaskRequest.Merge(dst, src)
2481 }
2482 func (m *TaskQueueFetchTaskRequest) XXX_Size() int {
2483 return xxx_messageInfo_TaskQueueFetchTaskRequest.Size(m)
2484 }
2485 func (m *TaskQueueFetchTaskRequest) XXX_DiscardUnknown() {
2486 xxx_messageInfo_TaskQueueFetchTaskRequest.DiscardUnknown(m)
2487 }
2488
2489 var xxx_messageInfo_TaskQueueFetchTaskRequest proto.InternalMessageInfo
2490
2491 func (m *TaskQueueFetchTaskRequest) GetAppId() []byte {
2492 if m != nil {
2493 return m.AppId
2494 }
2495 return nil
2496 }
2497
2498 func (m *TaskQueueFetchTaskRequest) GetQueueName() []byte {
2499 if m != nil {
2500 return m.QueueName
2501 }
2502 return nil
2503 }
2504
2505 func (m *TaskQueueFetchTaskRequest) GetTaskName() []byte {
2506 if m != nil {
2507 return m.TaskName
2508 }
2509 return nil
2510 }
2511
2512 type TaskQueueFetchTaskResponse struct {
2513 Task *TaskQueueQueryTasksResponse `protobuf:"bytes,1,req,name=task" json:"task,omitempty"`
2514 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2515 XXX_unrecognized []byte `json:"-"`
2516 XXX_sizecache int32 `json:"-"`
2517 }
2518
2519 func (m *TaskQueueFetchTaskResponse) Reset() { *m = TaskQueueFetchTaskResponse{} }
2520 func (m *TaskQueueFetchTaskResponse) String() string { return proto.CompactTextString(m) }
2521 func (*TaskQueueFetchTaskResponse) ProtoMessage() {}
2522 func (*TaskQueueFetchTaskResponse) Descriptor() ([]byte, []int) {
2523 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{32}
2524 }
2525 func (m *TaskQueueFetchTaskResponse) XXX_Unmarshal(b []byte) error {
2526 return xxx_messageInfo_TaskQueueFetchTaskResponse.Unmarshal(m, b)
2527 }
2528 func (m *TaskQueueFetchTaskResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2529 return xxx_messageInfo_TaskQueueFetchTaskResponse.Marshal(b, m, deterministic)
2530 }
2531 func (dst *TaskQueueFetchTaskResponse) XXX_Merge(src proto.Message) {
2532 xxx_messageInfo_TaskQueueFetchTaskResponse.Merge(dst, src)
2533 }
2534 func (m *TaskQueueFetchTaskResponse) XXX_Size() int {
2535 return xxx_messageInfo_TaskQueueFetchTaskResponse.Size(m)
2536 }
2537 func (m *TaskQueueFetchTaskResponse) XXX_DiscardUnknown() {
2538 xxx_messageInfo_TaskQueueFetchTaskResponse.DiscardUnknown(m)
2539 }
2540
2541 var xxx_messageInfo_TaskQueueFetchTaskResponse proto.InternalMessageInfo
2542
2543 func (m *TaskQueueFetchTaskResponse) GetTask() *TaskQueueQueryTasksResponse {
2544 if m != nil {
2545 return m.Task
2546 }
2547 return nil
2548 }
2549
2550 type TaskQueueUpdateStorageLimitRequest struct {
2551 AppId []byte `protobuf:"bytes,1,req,name=app_id,json=appId" json:"app_id,omitempty"`
2552 Limit *int64 `protobuf:"varint,2,req,name=limit" json:"limit,omitempty"`
2553 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2554 XXX_unrecognized []byte `json:"-"`
2555 XXX_sizecache int32 `json:"-"`
2556 }
2557
2558 func (m *TaskQueueUpdateStorageLimitRequest) Reset() { *m = TaskQueueUpdateStorageLimitRequest{} }
2559 func (m *TaskQueueUpdateStorageLimitRequest) String() string { return proto.CompactTextString(m) }
2560 func (*TaskQueueUpdateStorageLimitRequest) ProtoMessage() {}
2561 func (*TaskQueueUpdateStorageLimitRequest) Descriptor() ([]byte, []int) {
2562 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{33}
2563 }
2564 func (m *TaskQueueUpdateStorageLimitRequest) XXX_Unmarshal(b []byte) error {
2565 return xxx_messageInfo_TaskQueueUpdateStorageLimitRequest.Unmarshal(m, b)
2566 }
2567 func (m *TaskQueueUpdateStorageLimitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2568 return xxx_messageInfo_TaskQueueUpdateStorageLimitRequest.Marshal(b, m, deterministic)
2569 }
2570 func (dst *TaskQueueUpdateStorageLimitRequest) XXX_Merge(src proto.Message) {
2571 xxx_messageInfo_TaskQueueUpdateStorageLimitRequest.Merge(dst, src)
2572 }
2573 func (m *TaskQueueUpdateStorageLimitRequest) XXX_Size() int {
2574 return xxx_messageInfo_TaskQueueUpdateStorageLimitRequest.Size(m)
2575 }
2576 func (m *TaskQueueUpdateStorageLimitRequest) XXX_DiscardUnknown() {
2577 xxx_messageInfo_TaskQueueUpdateStorageLimitRequest.DiscardUnknown(m)
2578 }
2579
2580 var xxx_messageInfo_TaskQueueUpdateStorageLimitRequest proto.InternalMessageInfo
2581
2582 func (m *TaskQueueUpdateStorageLimitRequest) GetAppId() []byte {
2583 if m != nil {
2584 return m.AppId
2585 }
2586 return nil
2587 }
2588
2589 func (m *TaskQueueUpdateStorageLimitRequest) GetLimit() int64 {
2590 if m != nil && m.Limit != nil {
2591 return *m.Limit
2592 }
2593 return 0
2594 }
2595
2596 type TaskQueueUpdateStorageLimitResponse struct {
2597 NewLimit *int64 `protobuf:"varint,1,req,name=new_limit,json=newLimit" json:"new_limit,omitempty"`
2598 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2599 XXX_unrecognized []byte `json:"-"`
2600 XXX_sizecache int32 `json:"-"`
2601 }
2602
2603 func (m *TaskQueueUpdateStorageLimitResponse) Reset() { *m = TaskQueueUpdateStorageLimitResponse{} }
2604 func (m *TaskQueueUpdateStorageLimitResponse) String() string { return proto.CompactTextString(m) }
2605 func (*TaskQueueUpdateStorageLimitResponse) ProtoMessage() {}
2606 func (*TaskQueueUpdateStorageLimitResponse) Descriptor() ([]byte, []int) {
2607 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{34}
2608 }
2609 func (m *TaskQueueUpdateStorageLimitResponse) XXX_Unmarshal(b []byte) error {
2610 return xxx_messageInfo_TaskQueueUpdateStorageLimitResponse.Unmarshal(m, b)
2611 }
2612 func (m *TaskQueueUpdateStorageLimitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2613 return xxx_messageInfo_TaskQueueUpdateStorageLimitResponse.Marshal(b, m, deterministic)
2614 }
2615 func (dst *TaskQueueUpdateStorageLimitResponse) XXX_Merge(src proto.Message) {
2616 xxx_messageInfo_TaskQueueUpdateStorageLimitResponse.Merge(dst, src)
2617 }
2618 func (m *TaskQueueUpdateStorageLimitResponse) XXX_Size() int {
2619 return xxx_messageInfo_TaskQueueUpdateStorageLimitResponse.Size(m)
2620 }
2621 func (m *TaskQueueUpdateStorageLimitResponse) XXX_DiscardUnknown() {
2622 xxx_messageInfo_TaskQueueUpdateStorageLimitResponse.DiscardUnknown(m)
2623 }
2624
2625 var xxx_messageInfo_TaskQueueUpdateStorageLimitResponse proto.InternalMessageInfo
2626
2627 func (m *TaskQueueUpdateStorageLimitResponse) GetNewLimit() int64 {
2628 if m != nil && m.NewLimit != nil {
2629 return *m.NewLimit
2630 }
2631 return 0
2632 }
2633
2634 type TaskQueueQueryAndOwnTasksRequest struct {
2635 QueueName []byte `protobuf:"bytes,1,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
2636 LeaseSeconds *float64 `protobuf:"fixed64,2,req,name=lease_seconds,json=leaseSeconds" json:"lease_seconds,omitempty"`
2637 MaxTasks *int64 `protobuf:"varint,3,req,name=max_tasks,json=maxTasks" json:"max_tasks,omitempty"`
2638 GroupByTag *bool `protobuf:"varint,4,opt,name=group_by_tag,json=groupByTag,def=0" json:"group_by_tag,omitempty"`
2639 Tag []byte `protobuf:"bytes,5,opt,name=tag" json:"tag,omitempty"`
2640 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2641 XXX_unrecognized []byte `json:"-"`
2642 XXX_sizecache int32 `json:"-"`
2643 }
2644
2645 func (m *TaskQueueQueryAndOwnTasksRequest) Reset() { *m = TaskQueueQueryAndOwnTasksRequest{} }
2646 func (m *TaskQueueQueryAndOwnTasksRequest) String() string { return proto.CompactTextString(m) }
2647 func (*TaskQueueQueryAndOwnTasksRequest) ProtoMessage() {}
2648 func (*TaskQueueQueryAndOwnTasksRequest) Descriptor() ([]byte, []int) {
2649 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{35}
2650 }
2651 func (m *TaskQueueQueryAndOwnTasksRequest) XXX_Unmarshal(b []byte) error {
2652 return xxx_messageInfo_TaskQueueQueryAndOwnTasksRequest.Unmarshal(m, b)
2653 }
2654 func (m *TaskQueueQueryAndOwnTasksRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2655 return xxx_messageInfo_TaskQueueQueryAndOwnTasksRequest.Marshal(b, m, deterministic)
2656 }
2657 func (dst *TaskQueueQueryAndOwnTasksRequest) XXX_Merge(src proto.Message) {
2658 xxx_messageInfo_TaskQueueQueryAndOwnTasksRequest.Merge(dst, src)
2659 }
2660 func (m *TaskQueueQueryAndOwnTasksRequest) XXX_Size() int {
2661 return xxx_messageInfo_TaskQueueQueryAndOwnTasksRequest.Size(m)
2662 }
2663 func (m *TaskQueueQueryAndOwnTasksRequest) XXX_DiscardUnknown() {
2664 xxx_messageInfo_TaskQueueQueryAndOwnTasksRequest.DiscardUnknown(m)
2665 }
2666
2667 var xxx_messageInfo_TaskQueueQueryAndOwnTasksRequest proto.InternalMessageInfo
2668
2669 const Default_TaskQueueQueryAndOwnTasksRequest_GroupByTag bool = false
2670
2671 func (m *TaskQueueQueryAndOwnTasksRequest) GetQueueName() []byte {
2672 if m != nil {
2673 return m.QueueName
2674 }
2675 return nil
2676 }
2677
2678 func (m *TaskQueueQueryAndOwnTasksRequest) GetLeaseSeconds() float64 {
2679 if m != nil && m.LeaseSeconds != nil {
2680 return *m.LeaseSeconds
2681 }
2682 return 0
2683 }
2684
2685 func (m *TaskQueueQueryAndOwnTasksRequest) GetMaxTasks() int64 {
2686 if m != nil && m.MaxTasks != nil {
2687 return *m.MaxTasks
2688 }
2689 return 0
2690 }
2691
2692 func (m *TaskQueueQueryAndOwnTasksRequest) GetGroupByTag() bool {
2693 if m != nil && m.GroupByTag != nil {
2694 return *m.GroupByTag
2695 }
2696 return Default_TaskQueueQueryAndOwnTasksRequest_GroupByTag
2697 }
2698
2699 func (m *TaskQueueQueryAndOwnTasksRequest) GetTag() []byte {
2700 if m != nil {
2701 return m.Tag
2702 }
2703 return nil
2704 }
2705
2706 type TaskQueueQueryAndOwnTasksResponse struct {
2707 Task []*TaskQueueQueryAndOwnTasksResponse_Task `protobuf:"group,1,rep,name=Task,json=task" json:"task,omitempty"`
2708 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2709 XXX_unrecognized []byte `json:"-"`
2710 XXX_sizecache int32 `json:"-"`
2711 }
2712
2713 func (m *TaskQueueQueryAndOwnTasksResponse) Reset() { *m = TaskQueueQueryAndOwnTasksResponse{} }
2714 func (m *TaskQueueQueryAndOwnTasksResponse) String() string { return proto.CompactTextString(m) }
2715 func (*TaskQueueQueryAndOwnTasksResponse) ProtoMessage() {}
2716 func (*TaskQueueQueryAndOwnTasksResponse) Descriptor() ([]byte, []int) {
2717 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{36}
2718 }
2719 func (m *TaskQueueQueryAndOwnTasksResponse) XXX_Unmarshal(b []byte) error {
2720 return xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse.Unmarshal(m, b)
2721 }
2722 func (m *TaskQueueQueryAndOwnTasksResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2723 return xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse.Marshal(b, m, deterministic)
2724 }
2725 func (dst *TaskQueueQueryAndOwnTasksResponse) XXX_Merge(src proto.Message) {
2726 xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse.Merge(dst, src)
2727 }
2728 func (m *TaskQueueQueryAndOwnTasksResponse) XXX_Size() int {
2729 return xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse.Size(m)
2730 }
2731 func (m *TaskQueueQueryAndOwnTasksResponse) XXX_DiscardUnknown() {
2732 xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse.DiscardUnknown(m)
2733 }
2734
2735 var xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse proto.InternalMessageInfo
2736
2737 func (m *TaskQueueQueryAndOwnTasksResponse) GetTask() []*TaskQueueQueryAndOwnTasksResponse_Task {
2738 if m != nil {
2739 return m.Task
2740 }
2741 return nil
2742 }
2743
2744 type TaskQueueQueryAndOwnTasksResponse_Task struct {
2745 TaskName []byte `protobuf:"bytes,2,req,name=task_name,json=taskName" json:"task_name,omitempty"`
2746 EtaUsec *int64 `protobuf:"varint,3,req,name=eta_usec,json=etaUsec" json:"eta_usec,omitempty"`
2747 RetryCount *int32 `protobuf:"varint,4,opt,name=retry_count,json=retryCount,def=0" json:"retry_count,omitempty"`
2748 Body []byte `protobuf:"bytes,5,opt,name=body" json:"body,omitempty"`
2749 Tag []byte `protobuf:"bytes,6,opt,name=tag" json:"tag,omitempty"`
2750 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2751 XXX_unrecognized []byte `json:"-"`
2752 XXX_sizecache int32 `json:"-"`
2753 }
2754
2755 func (m *TaskQueueQueryAndOwnTasksResponse_Task) Reset() {
2756 *m = TaskQueueQueryAndOwnTasksResponse_Task{}
2757 }
2758 func (m *TaskQueueQueryAndOwnTasksResponse_Task) String() string { return proto.CompactTextString(m) }
2759 func (*TaskQueueQueryAndOwnTasksResponse_Task) ProtoMessage() {}
2760 func (*TaskQueueQueryAndOwnTasksResponse_Task) Descriptor() ([]byte, []int) {
2761 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{36, 0}
2762 }
2763 func (m *TaskQueueQueryAndOwnTasksResponse_Task) XXX_Unmarshal(b []byte) error {
2764 return xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse_Task.Unmarshal(m, b)
2765 }
2766 func (m *TaskQueueQueryAndOwnTasksResponse_Task) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2767 return xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse_Task.Marshal(b, m, deterministic)
2768 }
2769 func (dst *TaskQueueQueryAndOwnTasksResponse_Task) XXX_Merge(src proto.Message) {
2770 xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse_Task.Merge(dst, src)
2771 }
2772 func (m *TaskQueueQueryAndOwnTasksResponse_Task) XXX_Size() int {
2773 return xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse_Task.Size(m)
2774 }
2775 func (m *TaskQueueQueryAndOwnTasksResponse_Task) XXX_DiscardUnknown() {
2776 xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse_Task.DiscardUnknown(m)
2777 }
2778
2779 var xxx_messageInfo_TaskQueueQueryAndOwnTasksResponse_Task proto.InternalMessageInfo
2780
2781 const Default_TaskQueueQueryAndOwnTasksResponse_Task_RetryCount int32 = 0
2782
2783 func (m *TaskQueueQueryAndOwnTasksResponse_Task) GetTaskName() []byte {
2784 if m != nil {
2785 return m.TaskName
2786 }
2787 return nil
2788 }
2789
2790 func (m *TaskQueueQueryAndOwnTasksResponse_Task) GetEtaUsec() int64 {
2791 if m != nil && m.EtaUsec != nil {
2792 return *m.EtaUsec
2793 }
2794 return 0
2795 }
2796
2797 func (m *TaskQueueQueryAndOwnTasksResponse_Task) GetRetryCount() int32 {
2798 if m != nil && m.RetryCount != nil {
2799 return *m.RetryCount
2800 }
2801 return Default_TaskQueueQueryAndOwnTasksResponse_Task_RetryCount
2802 }
2803
2804 func (m *TaskQueueQueryAndOwnTasksResponse_Task) GetBody() []byte {
2805 if m != nil {
2806 return m.Body
2807 }
2808 return nil
2809 }
2810
2811 func (m *TaskQueueQueryAndOwnTasksResponse_Task) GetTag() []byte {
2812 if m != nil {
2813 return m.Tag
2814 }
2815 return nil
2816 }
2817
2818 type TaskQueueModifyTaskLeaseRequest struct {
2819 QueueName []byte `protobuf:"bytes,1,req,name=queue_name,json=queueName" json:"queue_name,omitempty"`
2820 TaskName []byte `protobuf:"bytes,2,req,name=task_name,json=taskName" json:"task_name,omitempty"`
2821 EtaUsec *int64 `protobuf:"varint,3,req,name=eta_usec,json=etaUsec" json:"eta_usec,omitempty"`
2822 LeaseSeconds *float64 `protobuf:"fixed64,4,req,name=lease_seconds,json=leaseSeconds" json:"lease_seconds,omitempty"`
2823 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2824 XXX_unrecognized []byte `json:"-"`
2825 XXX_sizecache int32 `json:"-"`
2826 }
2827
2828 func (m *TaskQueueModifyTaskLeaseRequest) Reset() { *m = TaskQueueModifyTaskLeaseRequest{} }
2829 func (m *TaskQueueModifyTaskLeaseRequest) String() string { return proto.CompactTextString(m) }
2830 func (*TaskQueueModifyTaskLeaseRequest) ProtoMessage() {}
2831 func (*TaskQueueModifyTaskLeaseRequest) Descriptor() ([]byte, []int) {
2832 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{37}
2833 }
2834 func (m *TaskQueueModifyTaskLeaseRequest) XXX_Unmarshal(b []byte) error {
2835 return xxx_messageInfo_TaskQueueModifyTaskLeaseRequest.Unmarshal(m, b)
2836 }
2837 func (m *TaskQueueModifyTaskLeaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2838 return xxx_messageInfo_TaskQueueModifyTaskLeaseRequest.Marshal(b, m, deterministic)
2839 }
2840 func (dst *TaskQueueModifyTaskLeaseRequest) XXX_Merge(src proto.Message) {
2841 xxx_messageInfo_TaskQueueModifyTaskLeaseRequest.Merge(dst, src)
2842 }
2843 func (m *TaskQueueModifyTaskLeaseRequest) XXX_Size() int {
2844 return xxx_messageInfo_TaskQueueModifyTaskLeaseRequest.Size(m)
2845 }
2846 func (m *TaskQueueModifyTaskLeaseRequest) XXX_DiscardUnknown() {
2847 xxx_messageInfo_TaskQueueModifyTaskLeaseRequest.DiscardUnknown(m)
2848 }
2849
2850 var xxx_messageInfo_TaskQueueModifyTaskLeaseRequest proto.InternalMessageInfo
2851
2852 func (m *TaskQueueModifyTaskLeaseRequest) GetQueueName() []byte {
2853 if m != nil {
2854 return m.QueueName
2855 }
2856 return nil
2857 }
2858
2859 func (m *TaskQueueModifyTaskLeaseRequest) GetTaskName() []byte {
2860 if m != nil {
2861 return m.TaskName
2862 }
2863 return nil
2864 }
2865
2866 func (m *TaskQueueModifyTaskLeaseRequest) GetEtaUsec() int64 {
2867 if m != nil && m.EtaUsec != nil {
2868 return *m.EtaUsec
2869 }
2870 return 0
2871 }
2872
2873 func (m *TaskQueueModifyTaskLeaseRequest) GetLeaseSeconds() float64 {
2874 if m != nil && m.LeaseSeconds != nil {
2875 return *m.LeaseSeconds
2876 }
2877 return 0
2878 }
2879
2880 type TaskQueueModifyTaskLeaseResponse struct {
2881 UpdatedEtaUsec *int64 `protobuf:"varint,1,req,name=updated_eta_usec,json=updatedEtaUsec" json:"updated_eta_usec,omitempty"`
2882 XXX_NoUnkeyedLiteral struct{} `json:"-"`
2883 XXX_unrecognized []byte `json:"-"`
2884 XXX_sizecache int32 `json:"-"`
2885 }
2886
2887 func (m *TaskQueueModifyTaskLeaseResponse) Reset() { *m = TaskQueueModifyTaskLeaseResponse{} }
2888 func (m *TaskQueueModifyTaskLeaseResponse) String() string { return proto.CompactTextString(m) }
2889 func (*TaskQueueModifyTaskLeaseResponse) ProtoMessage() {}
2890 func (*TaskQueueModifyTaskLeaseResponse) Descriptor() ([]byte, []int) {
2891 return fileDescriptor_taskqueue_service_05300f6f4e69f490, []int{38}
2892 }
2893 func (m *TaskQueueModifyTaskLeaseResponse) XXX_Unmarshal(b []byte) error {
2894 return xxx_messageInfo_TaskQueueModifyTaskLeaseResponse.Unmarshal(m, b)
2895 }
2896 func (m *TaskQueueModifyTaskLeaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
2897 return xxx_messageInfo_TaskQueueModifyTaskLeaseResponse.Marshal(b, m, deterministic)
2898 }
2899 func (dst *TaskQueueModifyTaskLeaseResponse) XXX_Merge(src proto.Message) {
2900 xxx_messageInfo_TaskQueueModifyTaskLeaseResponse.Merge(dst, src)
2901 }
2902 func (m *TaskQueueModifyTaskLeaseResponse) XXX_Size() int {
2903 return xxx_messageInfo_TaskQueueModifyTaskLeaseResponse.Size(m)
2904 }
2905 func (m *TaskQueueModifyTaskLeaseResponse) XXX_DiscardUnknown() {
2906 xxx_messageInfo_TaskQueueModifyTaskLeaseResponse.DiscardUnknown(m)
2907 }
2908
2909 var xxx_messageInfo_TaskQueueModifyTaskLeaseResponse proto.InternalMessageInfo
2910
2911 func (m *TaskQueueModifyTaskLeaseResponse) GetUpdatedEtaUsec() int64 {
2912 if m != nil && m.UpdatedEtaUsec != nil {
2913 return *m.UpdatedEtaUsec
2914 }
2915 return 0
2916 }
2917
2918 func init() {
2919 proto.RegisterType((*TaskQueueServiceError)(nil), "appengine.TaskQueueServiceError")
2920 proto.RegisterType((*TaskPayload)(nil), "appengine.TaskPayload")
2921 proto.RegisterType((*TaskQueueRetryParameters)(nil), "appengine.TaskQueueRetryParameters")
2922 proto.RegisterType((*TaskQueueAcl)(nil), "appengine.TaskQueueAcl")
2923 proto.RegisterType((*TaskQueueHttpHeader)(nil), "appengine.TaskQueueHttpHeader")
2924 proto.RegisterType((*TaskQueueMode)(nil), "appengine.TaskQueueMode")
2925 proto.RegisterType((*TaskQueueAddRequest)(nil), "appengine.TaskQueueAddRequest")
2926 proto.RegisterType((*TaskQueueAddRequest_Header)(nil), "appengine.TaskQueueAddRequest.Header")
2927 proto.RegisterType((*TaskQueueAddRequest_CronTimetable)(nil), "appengine.TaskQueueAddRequest.CronTimetable")
2928 proto.RegisterType((*TaskQueueAddResponse)(nil), "appengine.TaskQueueAddResponse")
2929 proto.RegisterType((*TaskQueueBulkAddRequest)(nil), "appengine.TaskQueueBulkAddRequest")
2930 proto.RegisterType((*TaskQueueBulkAddResponse)(nil), "appengine.TaskQueueBulkAddResponse")
2931 proto.RegisterType((*TaskQueueBulkAddResponse_TaskResult)(nil), "appengine.TaskQueueBulkAddResponse.TaskResult")
2932 proto.RegisterType((*TaskQueueDeleteRequest)(nil), "appengine.TaskQueueDeleteRequest")
2933 proto.RegisterType((*TaskQueueDeleteResponse)(nil), "appengine.TaskQueueDeleteResponse")
2934 proto.RegisterType((*TaskQueueForceRunRequest)(nil), "appengine.TaskQueueForceRunRequest")
2935 proto.RegisterType((*TaskQueueForceRunResponse)(nil), "appengine.TaskQueueForceRunResponse")
2936 proto.RegisterType((*TaskQueueUpdateQueueRequest)(nil), "appengine.TaskQueueUpdateQueueRequest")
2937 proto.RegisterType((*TaskQueueUpdateQueueResponse)(nil), "appengine.TaskQueueUpdateQueueResponse")
2938 proto.RegisterType((*TaskQueueFetchQueuesRequest)(nil), "appengine.TaskQueueFetchQueuesRequest")
2939 proto.RegisterType((*TaskQueueFetchQueuesResponse)(nil), "appengine.TaskQueueFetchQueuesResponse")
2940 proto.RegisterType((*TaskQueueFetchQueuesResponse_Queue)(nil), "appengine.TaskQueueFetchQueuesResponse.Queue")
2941 proto.RegisterType((*TaskQueueFetchQueueStatsRequest)(nil), "appengine.TaskQueueFetchQueueStatsRequest")
2942 proto.RegisterType((*TaskQueueScannerQueueInfo)(nil), "appengine.TaskQueueScannerQueueInfo")
2943 proto.RegisterType((*TaskQueueFetchQueueStatsResponse)(nil), "appengine.TaskQueueFetchQueueStatsResponse")
2944 proto.RegisterType((*TaskQueueFetchQueueStatsResponse_QueueStats)(nil), "appengine.TaskQueueFetchQueueStatsResponse.QueueStats")
2945 proto.RegisterType((*TaskQueuePauseQueueRequest)(nil), "appengine.TaskQueuePauseQueueRequest")
2946 proto.RegisterType((*TaskQueuePauseQueueResponse)(nil), "appengine.TaskQueuePauseQueueResponse")
2947 proto.RegisterType((*TaskQueuePurgeQueueRequest)(nil), "appengine.TaskQueuePurgeQueueRequest")
2948 proto.RegisterType((*TaskQueuePurgeQueueResponse)(nil), "appengine.TaskQueuePurgeQueueResponse")
2949 proto.RegisterType((*TaskQueueDeleteQueueRequest)(nil), "appengine.TaskQueueDeleteQueueRequest")
2950 proto.RegisterType((*TaskQueueDeleteQueueResponse)(nil), "appengine.TaskQueueDeleteQueueResponse")
2951 proto.RegisterType((*TaskQueueDeleteGroupRequest)(nil), "appengine.TaskQueueDeleteGroupRequest")
2952 proto.RegisterType((*TaskQueueDeleteGroupResponse)(nil), "appengine.TaskQueueDeleteGroupResponse")
2953 proto.RegisterType((*TaskQueueQueryTasksRequest)(nil), "appengine.TaskQueueQueryTasksRequest")
2954 proto.RegisterType((*TaskQueueQueryTasksResponse)(nil), "appengine.TaskQueueQueryTasksResponse")
2955 proto.RegisterType((*TaskQueueQueryTasksResponse_Task)(nil), "appengine.TaskQueueQueryTasksResponse.Task")
2956 proto.RegisterType((*TaskQueueQueryTasksResponse_Task_Header)(nil), "appengine.TaskQueueQueryTasksResponse.Task.Header")
2957 proto.RegisterType((*TaskQueueQueryTasksResponse_Task_CronTimetable)(nil), "appengine.TaskQueueQueryTasksResponse.Task.CronTimetable")
2958 proto.RegisterType((*TaskQueueQueryTasksResponse_Task_RunLog)(nil), "appengine.TaskQueueQueryTasksResponse.Task.RunLog")
2959 proto.RegisterType((*TaskQueueFetchTaskRequest)(nil), "appengine.TaskQueueFetchTaskRequest")
2960 proto.RegisterType((*TaskQueueFetchTaskResponse)(nil), "appengine.TaskQueueFetchTaskResponse")
2961 proto.RegisterType((*TaskQueueUpdateStorageLimitRequest)(nil), "appengine.TaskQueueUpdateStorageLimitRequest")
2962 proto.RegisterType((*TaskQueueUpdateStorageLimitResponse)(nil), "appengine.TaskQueueUpdateStorageLimitResponse")
2963 proto.RegisterType((*TaskQueueQueryAndOwnTasksRequest)(nil), "appengine.TaskQueueQueryAndOwnTasksRequest")
2964 proto.RegisterType((*TaskQueueQueryAndOwnTasksResponse)(nil), "appengine.TaskQueueQueryAndOwnTasksResponse")
2965 proto.RegisterType((*TaskQueueQueryAndOwnTasksResponse_Task)(nil), "appengine.TaskQueueQueryAndOwnTasksResponse.Task")
2966 proto.RegisterType((*TaskQueueModifyTaskLeaseRequest)(nil), "appengine.TaskQueueModifyTaskLeaseRequest")
2967 proto.RegisterType((*TaskQueueModifyTaskLeaseResponse)(nil), "appengine.TaskQueueModifyTaskLeaseResponse")
2968 }
2969
2970 func init() {
2971 proto.RegisterFile("google.golang.org/appengine/v2/internal/taskqueue/taskqueue_service.proto", fileDescriptor_taskqueue_service_05300f6f4e69f490)
2972 }
2973
2974 var fileDescriptor_taskqueue_service_05300f6f4e69f490 = []byte{
2975 // 2747 bytes of a gzipped FileDescriptorProto
2976 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x39, 0x4d, 0x73, 0xdb, 0xd6,
2977 0xb5, 0x01, 0xbf, 0x44, 0x1e, 0x7e, 0xc1, 0xd7, 0xb2, 0x44, 0x51, 0x71, 0x22, 0xc3, 0xf9, 0xd0,
2978 0x4b, 0xfc, 0x14, 0x59, 0x79, 0xe3, 0xbc, 0xa7, 0x99, 0x4c, 0x1e, 0x24, 0xc2, 0x32, 0x63, 0x8a,
2979 0xa4, 0x2f, 0xa1, 0x34, 0xce, 0x4c, 0x07, 0x73, 0x45, 0x5c, 0x51, 0x18, 0x81, 0x00, 0x83, 0x0f,
2980 0x5b, 0xf2, 0xa2, 0xab, 0xae, 0x3a, 0x5d, 0x74, 0xd3, 0xe9, 0x4c, 0x66, 0xba, 0xea, 0xf4, 0x37,
2981 0x74, 0xd7, 0xfe, 0x90, 0x2e, 0x3b, 0xd3, 0x3f, 0xd0, 0x55, 0xa7, 0x0b, 0x77, 0xee, 0xbd, 0x00,
2982 0x08, 0x4a, 0xb4, 0x6c, 0x4b, 0x49, 0x37, 0x12, 0x70, 0xce, 0xb9, 0xe7, 0xdc, 0xf3, 0x7d, 0x70,
2983 0x08, 0x0f, 0x47, 0xae, 0x3b, 0xb2, 0xe9, 0xc6, 0xc8, 0xb5, 0x89, 0x33, 0xda, 0x70, 0xbd, 0xd1,
2984 0x67, 0x64, 0x32, 0xa1, 0xce, 0xc8, 0x72, 0xe8, 0x67, 0x96, 0x13, 0x50, 0xcf, 0x21, 0xf6, 0x67,
2985 0x01, 0xf1, 0x4f, 0xbe, 0x0f, 0x69, 0x48, 0xa7, 0x4f, 0x86, 0x4f, 0xbd, 0x67, 0xd6, 0x90, 0x6e,
2986 0x4c, 0x3c, 0x37, 0x70, 0x51, 0x29, 0x39, 0xd5, 0x54, 0xdf, 0x88, 0xa5, 0x49, 0x02, 0xe2, 0x07,
2987 0xae, 0x47, 0xa7, 0x4f, 0xc6, 0xb3, 0xcf, 0x05, 0x37, 0xe5, 0xb7, 0x79, 0xb8, 0xa5, 0x13, 0xff,
2988 0xe4, 0x09, 0x93, 0x34, 0x10, 0x82, 0x34, 0xcf, 0x73, 0x3d, 0xe5, 0x5f, 0x39, 0x28, 0xf1, 0xa7,
2989 0x5d, 0xd7, 0xa4, 0xa8, 0x00, 0x99, 0xde, 0x63, 0xf9, 0x1d, 0x74, 0x03, 0xaa, 0x07, 0xdd, 0xc7,
2990 0xdd, 0xde, 0xcf, 0xba, 0xc6, 0x93, 0x03, 0xed, 0x40, 0x93, 0x25, 0x74, 0x13, 0xea, 0x3a, 0x56,
2991 0xbb, 0x83, 0xb6, 0xd6, 0xd5, 0x0d, 0x0d, 0xe3, 0x1e, 0x96, 0x33, 0x08, 0x41, 0xad, 0xdd, 0xd5,
2992 0x35, 0xdc, 0x55, 0x3b, 0x11, 0x2c, 0xcb, 0x60, 0xba, 0x3a, 0x78, 0x6c, 0xe8, 0xbd, 0x9e, 0xd1,
2993 0x51, 0xf1, 0x9e, 0x26, 0xe7, 0xd0, 0x2d, 0xb8, 0xd1, 0xee, 0x7e, 0xa3, 0x76, 0xda, 0x2d, 0x83,
2994 0xe3, 0xba, 0xea, 0xbe, 0x26, 0xe7, 0xd1, 0x12, 0xa0, 0x18, 0xcc, 0xc5, 0x08, 0x78, 0x01, 0xd5,
2995 0xa1, 0x1c, 0xc3, 0x0f, 0x70, 0x47, 0x5e, 0xb8, 0x48, 0x88, 0x55, 0x5d, 0x93, 0x8b, 0x8c, 0x6f,
2996 0x5f, 0xc3, 0xfb, 0xed, 0xc1, 0xa0, 0xdd, 0xeb, 0x1a, 0x2d, 0xad, 0xdb, 0xd6, 0x5a, 0x72, 0x09,
2997 0x2d, 0xc3, 0x4d, 0x2e, 0x46, 0xed, 0x60, 0x4d, 0x6d, 0x3d, 0x35, 0xb4, 0x6f, 0xdb, 0x03, 0x7d,
2998 0x20, 0x03, 0x57, 0xa2, 0xb7, 0xbf, 0x33, 0xd0, 0x7b, 0x5d, 0x4d, 0x5c, 0x45, 0x2e, 0xa7, 0xa5,
2999 0x69, 0xba, 0x2a, 0x57, 0x18, 0x55, 0x0c, 0xc0, 0xda, 0x93, 0x03, 0x6d, 0xa0, 0xcb, 0x55, 0x24,
3000 0x43, 0x25, 0x36, 0x09, 0x3f, 0x57, 0x43, 0x8b, 0x20, 0xa7, 0x98, 0x09, 0x3b, 0xd5, 0x99, 0xec,
3001 0xd6, 0x41, 0xbf, 0xd3, 0xde, 0x55, 0x75, 0x2d, 0xa5, 0xac, 0x8c, 0xca, 0xb0, 0x30, 0x78, 0xdc,
3002 0xee, 0xf7, 0xb5, 0x96, 0x7c, 0x83, 0x1b, 0xa9, 0xd7, 0x33, 0xf6, 0xd5, 0xee, 0x53, 0x4e, 0x34,
3003 0x90, 0x51, 0x5a, 0x6c, 0x5f, 0x7d, 0xda, 0xe9, 0xa9, 0x2d, 0xf9, 0x26, 0x7a, 0x17, 0x1a, 0xd3,
3004 0xbb, 0xe8, 0xf8, 0xa9, 0xd1, 0x57, 0xb1, 0xba, 0xaf, 0xe9, 0x1a, 0x1e, 0xc8, 0x8b, 0x17, 0xed,
3005 0xb2, 0xdf, 0x6b, 0x69, 0xf2, 0x2d, 0x76, 0x35, 0x75, 0xb7, 0x63, 0x74, 0x7a, 0xbd, 0xc7, 0x07,
3006 0xfd, 0xc8, 0x33, 0x4b, 0xe8, 0x2e, 0xbc, 0xcf, 0x5d, 0xa8, 0xee, 0xea, 0xed, 0x1e, 0x73, 0x59,
3007 0xa4, 0x5d, 0xca, 0x55, 0xcb, 0xa8, 0x09, 0x4b, 0xed, 0xee, 0x6e, 0x0f, 0x63, 0x6d, 0x57, 0x37,
3008 0x76, 0xb1, 0xa6, 0xea, 0x3d, 0x2c, 0x54, 0x68, 0x30, 0x71, 0x5c, 0xa3, 0x8e, 0xa6, 0x0e, 0x34,
3009 0x43, 0xfb, 0xb6, 0xdf, 0xc6, 0x5a, 0x4b, 0x5e, 0x61, 0xb6, 0x11, 0xe2, 0xfb, 0xea, 0xc1, 0x40,
3010 0x6b, 0xc9, 0xcd, 0xb4, 0x4d, 0x75, 0x75, 0x4f, 0x5e, 0x45, 0x8b, 0x50, 0x6f, 0xa9, 0xba, 0x3a,
3011 0xd0, 0x7b, 0x58, 0x8b, 0x2e, 0xf4, 0x9b, 0xae, 0xb2, 0x0a, 0x65, 0x16, 0x96, 0x7d, 0x72, 0x66,
3012 0xbb, 0xc4, 0xfc, 0xa4, 0x58, 0x04, 0xf9, 0xe5, 0xcb, 0x97, 0x2f, 0x17, 0xb6, 0x33, 0x45, 0x49,
3013 0xf9, 0x9b, 0x04, 0x8d, 0x24, 0x68, 0x31, 0x0d, 0xbc, 0xb3, 0x3e, 0xf1, 0xc8, 0x98, 0x06, 0xd4,
3014 0xf3, 0xd1, 0xfb, 0x50, 0xf6, 0x18, 0xc8, 0xb0, 0xad, 0xb1, 0x15, 0x34, 0xa4, 0x35, 0x69, 0x3d,
3015 0x8f, 0x81, 0x83, 0x3a, 0x0c, 0x82, 0x14, 0xa8, 0x92, 0x11, 0x15, 0x68, 0xc3, 0xa7, 0xc3, 0x46,
3016 0x66, 0x4d, 0x5a, 0xcf, 0xe2, 0x32, 0x19, 0x51, 0x4e, 0x30, 0xa0, 0x43, 0xf4, 0x29, 0xd4, 0xc7,
3017 0x96, 0x63, 0x1c, 0x92, 0xe1, 0x89, 0x7b, 0x74, 0xc4, 0xa9, 0xb2, 0x6b, 0xd2, 0xba, 0xb4, 0x9d,
3018 0xdd, 0xdc, 0xb8, 0x8f, 0xab, 0x63, 0xcb, 0xd9, 0x11, 0x28, 0x46, 0x7c, 0x0f, 0xea, 0x63, 0x72,
3019 0x3a, 0x43, 0x9c, 0xe3, 0xc4, 0xb9, 0xcf, 0x1f, 0x6c, 0x6e, 0xe2, 0xea, 0x98, 0x9c, 0xa6, 0xa8,
3020 0x3f, 0x06, 0x06, 0x30, 0x4c, 0x37, 0x3c, 0xb4, 0x2d, 0x67, 0xe4, 0x37, 0xf2, 0xec, 0x86, 0xdb,
3021 0x99, 0xfb, 0x0f, 0x70, 0x65, 0x4c, 0x4e, 0x5b, 0x31, 0x5c, 0xe9, 0x43, 0x25, 0x51, 0x52, 0x1d,
3022 0xda, 0xe8, 0x36, 0x40, 0xe8, 0x53, 0xcf, 0xa0, 0x63, 0x62, 0xd9, 0x0d, 0x69, 0x2d, 0xbb, 0x5e,
3023 0xc1, 0x25, 0x06, 0xd1, 0x18, 0x00, 0xdd, 0x81, 0xca, 0x73, 0xcf, 0x0a, 0x12, 0x82, 0x0c, 0x27,
3024 0x28, 0x0b, 0x18, 0x27, 0x51, 0xbe, 0x84, 0x9b, 0x09, 0xc7, 0x47, 0x41, 0x30, 0x79, 0x44, 0x89,
3025 0x49, 0x3d, 0x24, 0x43, 0xf6, 0x84, 0x9e, 0x35, 0xa4, 0xb5, 0xcc, 0x7a, 0x05, 0xb3, 0x47, 0xb4,
3026 0x08, 0xf9, 0x67, 0xc4, 0x0e, 0x69, 0x23, 0xc3, 0x61, 0xe2, 0x45, 0xf9, 0x14, 0xaa, 0xc9, 0xf1,
3027 0x7d, 0xd7, 0xa4, 0x4a, 0x13, 0x72, 0xec, 0x3f, 0x2a, 0x42, 0xae, 0x7f, 0x30, 0x78, 0x24, 0xbf,
3028 0x23, 0x9e, 0x3a, 0x1d, 0x59, 0x52, 0xfe, 0x51, 0x48, 0x09, 0x53, 0x4d, 0x13, 0xd3, 0xef, 0x43,
3029 0xea, 0x07, 0x4c, 0x0b, 0x51, 0xd5, 0x1c, 0x32, 0xa6, 0x91, 0xcc, 0x12, 0x87, 0x74, 0xc9, 0x98,
3030 0xa2, 0x55, 0x28, 0xb1, 0xc2, 0x27, 0xb0, 0x42, 0x7a, 0x91, 0x01, 0x38, 0x72, 0x05, 0x8a, 0x34,
3031 0x20, 0x46, 0x28, 0xdc, 0x91, 0x59, 0xcf, 0xe2, 0x05, 0x1a, 0x90, 0x03, 0x9f, 0x0e, 0xd1, 0xd7,
3032 0x50, 0x18, 0xd3, 0xe0, 0xd8, 0x35, 0xb9, 0x39, 0x6b, 0x5b, 0xf7, 0x36, 0x92, 0x4a, 0xb8, 0x31,
3033 0xe7, 0x1a, 0x1b, 0xd1, 0xff, 0x7d, 0x7e, 0x66, 0x3b, 0xd7, 0xef, 0x0d, 0x74, 0x1c, 0x71, 0x60,
3034 0xf6, 0x08, 0x3d, 0x9b, 0xfb, 0xb0, 0x82, 0xd9, 0x23, 0xfa, 0x12, 0x0a, 0xc7, 0xdc, 0x56, 0x8d,
3035 0xc2, 0x5a, 0x76, 0x1d, 0xb6, 0x3e, 0x7c, 0x0d, 0x77, 0x61, 0x58, 0x1c, 0x1d, 0x42, 0x4b, 0x90,
3036 0x3b, 0x74, 0xcd, 0xb3, 0x46, 0x89, 0x71, 0xdc, 0xc9, 0x14, 0x25, 0xcc, 0xdf, 0xd1, 0xff, 0x42,
3037 0x39, 0xf0, 0x88, 0xe3, 0x93, 0x61, 0x60, 0xb9, 0x4e, 0x03, 0xd6, 0xa4, 0xf5, 0xf2, 0xd6, 0x52,
3038 0x9a, 0xf7, 0x14, 0x8b, 0xd3, 0xa4, 0xe8, 0x16, 0x14, 0xc8, 0x64, 0x62, 0x58, 0x66, 0xa3, 0xcc,
3039 0x6f, 0x99, 0x27, 0x93, 0x49, 0xdb, 0x44, 0x18, 0xaa, 0x43, 0xcf, 0x75, 0x02, 0x6b, 0x4c, 0x03,
3040 0x72, 0x68, 0xd3, 0x46, 0x65, 0x4d, 0x5a, 0x87, 0xd7, 0x1a, 0x63, 0xd7, 0x73, 0x1d, 0x3d, 0x3e,
3041 0x83, 0x67, 0x59, 0xa0, 0x35, 0x28, 0x9b, 0xd4, 0x1f, 0x7a, 0xd6, 0x84, 0x5f, 0xb2, 0xce, 0xe5,
3042 0xa5, 0x41, 0x68, 0x13, 0x16, 0x26, 0x22, 0x4f, 0x1b, 0xf2, 0x45, 0x15, 0xa6, 0x59, 0x8c, 0x63,
3043 0x32, 0xd4, 0x05, 0x59, 0xe4, 0xe8, 0x24, 0xc9, 0xdb, 0xc6, 0x0d, 0x7e, 0xf4, 0xee, 0xbc, 0xab,
3044 0x9e, 0x4b, 0x71, 0x5c, 0xf7, 0xce, 0xe5, 0xfc, 0x17, 0x90, 0x1b, 0xbb, 0x26, 0x6d, 0x20, 0xee,
3045 0xfb, 0xdb, 0xf3, 0x78, 0xb0, 0x40, 0xdd, 0x60, 0x7f, 0xb6, 0x79, 0xac, 0x62, 0x7e, 0x80, 0xb9,
3046 0x3a, 0x20, 0xa3, 0xc6, 0x4d, 0xe1, 0xea, 0x80, 0x8c, 0x9a, 0x9b, 0x50, 0x98, 0x4d, 0x8b, 0x85,
3047 0x39, 0x69, 0x51, 0x4c, 0xa5, 0x45, 0x73, 0x0f, 0xaa, 0x33, 0x06, 0x44, 0x4d, 0x28, 0xfa, 0xc3,
3048 0x63, 0x6a, 0x86, 0x36, 0x6d, 0x54, 0x45, 0x08, 0xc7, 0xef, 0x0c, 0xc7, 0x4c, 0xfb, 0xc2, 0x75,
3049 0x68, 0xa3, 0x16, 0x85, 0x77, 0xf4, 0xae, 0xa8, 0x50, 0x9d, 0x09, 0x4b, 0xb4, 0x00, 0xd9, 0x3d,
3050 0x4d, 0x97, 0x25, 0x9e, 0x56, 0xbd, 0x81, 0x2e, 0x67, 0xd8, 0xd3, 0x23, 0x4d, 0x6d, 0xc9, 0x59,
3051 0x86, 0xec, 0x1f, 0xe8, 0x72, 0x0e, 0x01, 0x14, 0x5a, 0x5a, 0x47, 0xd3, 0x35, 0x39, 0xaf, 0xfc,
3052 0x3f, 0x2c, 0xce, 0x3a, 0xd8, 0x9f, 0xb8, 0x8e, 0x4f, 0xd1, 0x3a, 0xc8, 0xc3, 0x63, 0xd7, 0xa7,
3053 0x8e, 0x31, 0xcd, 0x2e, 0x89, 0x2b, 0x5d, 0x13, 0x70, 0x3d, 0xca, 0x31, 0xe5, 0x3b, 0x58, 0x4e,
3054 0x38, 0xec, 0x84, 0xf6, 0x49, 0x2a, 0x75, 0xbf, 0x82, 0x32, 0x31, 0x4d, 0xc3, 0x13, 0xaf, 0xbc,
3055 0x02, 0x95, 0xb7, 0xde, 0xbb, 0x3c, 0xb6, 0x30, 0x90, 0xe4, 0x59, 0xf9, 0x7b, 0xba, 0x6e, 0x27,
3056 0xcc, 0xa3, 0x2b, 0x76, 0x01, 0xd8, 0xdd, 0x3c, 0xea, 0x87, 0xb6, 0x60, 0x0e, 0x5b, 0x1b, 0xf3,
3057 0x98, 0x9f, 0x3b, 0xc8, 0x11, 0x98, 0x9f, 0xc2, 0x29, 0x0e, 0xcd, 0x17, 0x00, 0x53, 0x0c, 0xda,
3058 0x81, 0x42, 0xc4, 0x99, 0x15, 0x95, 0xda, 0xd6, 0x27, 0xf3, 0x38, 0xa7, 0xe7, 0x9f, 0x8d, 0x64,
3059 0xf6, 0xc1, 0xd1, 0xc9, 0xb9, 0x46, 0xcc, 0xce, 0x35, 0xe2, 0x09, 0x2c, 0x25, 0x4c, 0x5b, 0xd4,
3060 0xa6, 0x01, 0xbd, 0x5a, 0xf9, 0xcb, 0xce, 0x94, 0xbf, 0x69, 0xd2, 0x67, 0x53, 0x49, 0xaf, 0xfc,
3061 0x3c, 0xe5, 0xb1, 0x58, 0x58, 0x64, 0xd3, 0xa9, 0xd6, 0xd9, 0xb5, 0xec, 0xd5, 0xb4, 0x56, 0xc6,
3062 0x29, 0x9f, 0x3d, 0x74, 0xbd, 0x21, 0xc5, 0xa1, 0x13, 0x6b, 0x33, 0xbd, 0x91, 0x94, 0x2e, 0x43,
3063 0xb3, 0x4a, 0x66, 0x2e, 0x55, 0x32, 0x3b, 0x5b, 0xe3, 0x15, 0x03, 0x56, 0xe6, 0x88, 0x9b, 0xa3,
3064 0xcf, 0x15, 0xbd, 0xa8, 0xfc, 0x90, 0x83, 0xd5, 0x84, 0xf6, 0x60, 0x62, 0x92, 0x80, 0x46, 0x45,
3065 0xe6, 0x3a, 0x3a, 0x7d, 0x01, 0x8d, 0xc3, 0x70, 0x78, 0x42, 0x03, 0xc3, 0xa3, 0x47, 0x96, 0x6d,
3066 0x1b, 0x13, 0xea, 0xb1, 0x49, 0xc0, 0x75, 0x4c, 0x7e, 0x57, 0x09, 0xdf, 0x12, 0x78, 0xcc, 0xd1,
3067 0x7d, 0xea, 0x0d, 0x38, 0x12, 0x7d, 0x0c, 0xf5, 0xe8, 0xe0, 0x90, 0x4c, 0xc8, 0xd0, 0x0a, 0xce,
3068 0x1a, 0xb9, 0xb5, 0xcc, 0x7a, 0x1e, 0xd7, 0x04, 0x78, 0x37, 0x82, 0xa2, 0x0d, 0xb8, 0xc9, 0xdb,
3069 0xbf, 0x3f, 0xa1, 0x43, 0xeb, 0xc8, 0xa2, 0xa6, 0xe1, 0x91, 0x80, 0xf2, 0x76, 0x57, 0xc2, 0x37,
3070 0x18, 0x6a, 0x10, 0x63, 0x30, 0x09, 0xe8, 0xdc, 0x1a, 0x5b, 0xb8, 0x46, 0x8d, 0x7d, 0x00, 0xcb,
3071 0x6c, 0x6e, 0x19, 0xba, 0xce, 0x30, 0xf4, 0x3c, 0xea, 0x04, 0x71, 0x21, 0xf0, 0x1b, 0x0b, 0x7c,
3072 0xc6, 0xba, 0x35, 0x26, 0xa7, 0xbb, 0x09, 0x36, 0x32, 0xe7, 0xb4, 0x36, 0x17, 0xdf, 0xb6, 0x36,
3073 0xff, 0x17, 0x64, 0xc9, 0xd0, 0xe6, 0x4d, 0xb3, 0xbc, 0xb5, 0x3c, 0xb7, 0xcc, 0x0c, 0x6d, 0xcc,
3074 0x68, 0xd0, 0x1e, 0xd4, 0x45, 0xab, 0x35, 0xdc, 0x67, 0xd4, 0xf3, 0x2c, 0x93, 0x36, 0xe0, 0xd5,
3075 0xd5, 0x69, 0x3a, 0xfa, 0xe0, 0x9a, 0x38, 0xd6, 0x8b, 0x4e, 0x29, 0xef, 0xc1, 0xbb, 0xf3, 0x63,
3076 0x43, 0x04, 0xa0, 0xd2, 0x4b, 0xc5, 0xce, 0x43, 0x1a, 0x0c, 0x8f, 0xf9, 0x93, 0xff, 0x9a, 0xd8,
3077 0x59, 0x81, 0x22, 0x33, 0x9d, 0xe7, 0x3e, 0xf7, 0x79, 0xe4, 0xe4, 0xf1, 0xc2, 0x98, 0x9c, 0x62,
3078 0xf7, 0xb9, 0xaf, 0xfc, 0x31, 0x9f, 0x92, 0x38, 0xc3, 0x31, 0x0a, 0xf9, 0x5d, 0xc8, 0xf3, 0x28,
3079 0x8b, 0x2a, 0xe2, 0x7f, 0xcf, 0x53, 0x68, 0xce, 0xb9, 0x0d, 0x71, 0x6f, 0x71, 0xb6, 0xf9, 0x97,
3080 0x1c, 0xe4, 0x39, 0xe0, 0x3f, 0x1d, 0xc6, 0xd2, 0xb5, 0xc3, 0xf8, 0x36, 0x14, 0x26, 0x24, 0xf4,
3081 0xa9, 0xd9, 0x28, 0xac, 0x65, 0xd6, 0x8b, 0xdb, 0xf9, 0x23, 0x62, 0xfb, 0x14, 0x47, 0xc0, 0xb9,
3082 0x51, 0xbe, 0xf0, 0xd3, 0x44, 0x79, 0xf1, 0x4d, 0xa2, 0xbc, 0x74, 0xc5, 0x28, 0x87, 0xab, 0x45,
3083 0x79, 0xf9, 0x2a, 0x51, 0x8e, 0xee, 0x43, 0x65, 0xe8, 0x51, 0x12, 0xb8, 0x9e, 0x08, 0x03, 0x36,
3084 0x25, 0x96, 0xb6, 0x81, 0x4c, 0x26, 0xc7, 0xae, 0x1f, 0x58, 0xce, 0x88, 0xcf, 0xa8, 0xe5, 0x88,
3085 0x86, 0x97, 0xe5, 0x5f, 0xc0, 0xfb, 0x73, 0xc2, 0x6d, 0x10, 0x90, 0xc0, 0x7f, 0xcb, 0xc2, 0x99,
3086 0x9d, 0x8d, 0xb8, 0x0f, 0xc5, 0xe7, 0x90, 0x13, 0x8e, 0x79, 0x57, 0xf5, 0x79, 0x6f, 0xcb, 0x6f,
3087 0x4b, 0x9b, 0xb8, 0x3c, 0x26, 0xa7, 0xdd, 0x70, 0xcc, 0xc4, 0xfa, 0xca, 0xaf, 0x32, 0xa9, 0xbe,
3088 0x30, 0x18, 0x12, 0xc7, 0xa1, 0x1e, 0x7f, 0x6e, 0x3b, 0x47, 0x2e, 0xda, 0x84, 0x45, 0x7a, 0x4a,
3089 0x87, 0x61, 0x40, 0x4d, 0xc3, 0x26, 0x7e, 0x60, 0x8c, 0x2d, 0x27, 0x0c, 0x44, 0x7f, 0xcd, 0x62,
3090 0x14, 0xe3, 0x3a, 0xc4, 0x0f, 0xf6, 0x39, 0x06, 0xdd, 0x03, 0x34, 0x7b, 0xe2, 0xd8, 0x0d, 0x3d,
3091 0x9e, 0x0f, 0x59, 0x2c, 0xa7, 0xe9, 0x1f, 0xb9, 0xa1, 0x87, 0xb6, 0x61, 0xc5, 0x27, 0xe3, 0x09,
3092 0xfb, 0x2e, 0x33, 0xcc, 0xd0, 0x23, 0x6c, 0xec, 0x8d, 0xd2, 0xc2, 0x8f, 0xf2, 0x62, 0x39, 0x26,
3093 0x68, 0x45, 0x78, 0x91, 0x18, 0x3e, 0x93, 0x14, 0x87, 0x90, 0x61, 0x39, 0xc6, 0x91, 0x6d, 0x8d,
3094 0x8e, 0x03, 0xfe, 0x71, 0x91, 0xc7, 0x72, 0x8c, 0x69, 0x3b, 0x0f, 0x39, 0x1c, 0xdd, 0x85, 0x2a,
3095 0x75, 0x8e, 0x58, 0xdf, 0x4b, 0x25, 0x86, 0x84, 0x2b, 0x31, 0x90, 0xe5, 0x84, 0xf2, 0xbb, 0x0c,
3096 0xac, 0xbd, 0xda, 0x1b, 0x51, 0xe1, 0xf8, 0x26, 0xb2, 0xbb, 0xcf, 0xa0, 0x51, 0xf5, 0x78, 0x70,
3097 0x79, 0xf5, 0x98, 0x61, 0xb0, 0x91, 0x02, 0xa5, 0x38, 0x35, 0x7f, 0x90, 0x00, 0xa6, 0x28, 0xd6,
3098 0xcc, 0xa7, 0xbe, 0x13, 0xc5, 0xad, 0xe8, 0x44, 0x5e, 0x43, 0x1f, 0x41, 0xdd, 0xb5, 0x4d, 0xea,
3099 0x07, 0xc6, 0xb9, 0xef, 0xb6, 0xaa, 0x00, 0x6b, 0xd1, 0xd7, 0xdb, 0x1e, 0x54, 0x7c, 0xe1, 0x53,
3100 0xc3, 0x72, 0x8e, 0x5c, 0x6e, 0x9d, 0xf2, 0xd6, 0x07, 0x73, 0xbb, 0xfb, 0x39, 0xdf, 0xe3, 0x72,
3101 0x74, 0x92, 0xbd, 0x28, 0xc7, 0xd0, 0x4c, 0x28, 0xfb, 0xac, 0x42, 0xbc, 0xb2, 0xb5, 0x67, 0xde,
3102 0xb8, 0xb5, 0x2f, 0x42, 0x9e, 0x17, 0x1b, 0x7e, 0xf5, 0x22, 0x16, 0x2f, 0xca, 0xed, 0x54, 0x27,
3103 0x48, 0x4b, 0x8a, 0x1a, 0x05, 0x4e, 0x5f, 0x24, 0xf4, 0x46, 0x3f, 0xc2, 0x8c, 0x31, 0x2b, 0x32,
3104 0xc5, 0x33, 0x12, 0x39, 0x48, 0xa1, 0xc5, 0x1c, 0x78, 0x7d, 0xe5, 0x67, 0x1a, 0xe2, 0x0c, 0xd3,
3105 0x48, 0xe8, 0xff, 0x5c, 0x10, 0xba, 0xe7, 0xb9, 0xe1, 0xe4, 0x72, 0xa1, 0x73, 0xb8, 0x46, 0xa7,
3106 0x22, 0xae, 0x7f, 0x95, 0x52, 0xe6, 0x7b, 0x12, 0x52, 0xef, 0x8c, 0xc7, 0xd3, 0xf5, 0x46, 0xb4,
3107 0x8f, 0xa0, 0xee, 0x07, 0xc4, 0x0b, 0x2e, 0x4c, 0xef, 0x55, 0x0e, 0x8e, 0x87, 0x77, 0xf4, 0x01,
3108 0xd4, 0x04, 0x5d, 0x12, 0xb3, 0x39, 0xbe, 0x20, 0xaa, 0x70, 0x68, 0x1c, 0xb2, 0xab, 0x50, 0x8a,
3109 0xb9, 0x8d, 0xf8, 0x5c, 0xc5, 0xbe, 0xf2, 0x04, 0x9f, 0x11, 0x7a, 0x37, 0xd5, 0xf0, 0xc5, 0x7a,
3110 0x47, 0xba, 0x3f, 0xed, 0xf9, 0xbf, 0x84, 0x94, 0xd1, 0xd2, 0xda, 0x45, 0x99, 0xfb, 0x15, 0xe4,
3111 0xd8, 0x15, 0xa3, 0x9c, 0xfd, 0x74, 0x5e, 0x16, 0x5c, 0x3c, 0x25, 0x3e, 0x83, 0xf8, 0xc1, 0xe6,
3112 0x1f, 0x4a, 0x90, 0x63, 0xaf, 0x57, 0xde, 0xa6, 0x5c, 0xdc, 0x80, 0x3c, 0x39, 0xb7, 0x5f, 0xf9,
3113 0xbf, 0xb7, 0xb8, 0xd5, 0xec, 0xb2, 0x25, 0x59, 0xb3, 0x28, 0xf1, 0xa2, 0x6e, 0xe8, 0x86, 0x4e,
3114 0xc0, 0x6d, 0xc8, 0xeb, 0xbe, 0xd8, 0xd5, 0xed, 0x32, 0x20, 0xfa, 0x3a, 0x59, 0xbc, 0x2c, 0x70,
3115 0x63, 0x6c, 0xbd, 0x8d, 0xd8, 0x73, 0x5b, 0x98, 0x55, 0x28, 0x1d, 0xba, 0xe6, 0x99, 0xe1, 0x5b,
3116 0x2f, 0x28, 0xef, 0xb7, 0x79, 0x5c, 0x64, 0x80, 0x81, 0xf5, 0x82, 0x26, 0x2b, 0x9a, 0xf2, 0xb9,
3117 0x15, 0xcd, 0x3d, 0x40, 0xbc, 0x0d, 0xb2, 0x82, 0xcf, 0x3e, 0xd4, 0x85, 0xb9, 0x2a, 0xa2, 0x4f,
3118 0xc4, 0x18, 0xf6, 0xe9, 0xcf, 0xed, 0x66, 0x9c, 0xdf, 0xbf, 0x54, 0xf9, 0xfe, 0xe5, 0xad, 0x8c,
3119 0x75, 0xe9, 0x32, 0xe6, 0x6b, 0x28, 0x78, 0xa1, 0x63, 0xbb, 0x23, 0xbe, 0x69, 0x79, 0x4b, 0x7b,
3120 0xe0, 0xd0, 0xe9, 0xb8, 0x23, 0x1c, 0x71, 0x38, 0xbf, 0xd8, 0xb9, 0x75, 0xe9, 0x62, 0x67, 0xe9,
3121 0xea, 0x8b, 0x9d, 0xe5, 0x6b, 0x8c, 0x63, 0x1f, 0x40, 0xed, 0xc8, 0xf2, 0xfc, 0xc0, 0x60, 0x3c,
3122 0xb9, 0xe9, 0x1b, 0x22, 0x17, 0x39, 0x54, 0xf7, 0xce, 0xe2, 0x70, 0x65, 0x59, 0xb8, 0x92, 0x6c,
3123 0x71, 0xd0, 0x27, 0x50, 0x17, 0x4d, 0x9c, 0xf9, 0x4d, 0xc4, 0x57, 0x33, 0x8e, 0xaf, 0x5a, 0x82,
3124 0xe1, 0x31, 0x76, 0x71, 0xe3, 0x53, 0x9c, 0xb3, 0xf1, 0x29, 0xbd, 0xf1, 0xc6, 0xa7, 0x76, 0xc9,
3125 0xc6, 0xa7, 0x3e, 0xbb, 0xf1, 0x69, 0xfe, 0x49, 0x82, 0x82, 0xf0, 0x0a, 0x1b, 0xa0, 0x4d, 0xcb,
3126 0x9f, 0x90, 0x80, 0x9d, 0x13, 0xaa, 0xde, 0xe0, 0x51, 0x56, 0x9b, 0x82, 0xb9, 0xb2, 0x2b, 0x50,
3127 0xb4, 0xc9, 0x48, 0x50, 0x20, 0x91, 0xb6, 0x36, 0x19, 0x71, 0xd4, 0x1d, 0xa8, 0x50, 0x9b, 0x4c,
3128 0xfc, 0x98, 0xc1, 0x4d, 0x8e, 0x2e, 0x47, 0x30, 0x4e, 0x72, 0x17, 0xaa, 0x5e, 0x14, 0x14, 0xc6,
3129 0x90, 0x0d, 0xac, 0x8b, 0xc2, 0x9e, 0x31, 0x90, 0xff, 0xd8, 0x73, 0x07, 0x2a, 0xc2, 0x8b, 0x1e,
3130 0x25, 0xbe, 0xeb, 0x34, 0x56, 0xf9, 0x70, 0x2e, 0xb2, 0x15, 0x73, 0xd0, 0x8f, 0xb1, 0xab, 0x72,
3131 0xd2, 0x5f, 0xfa, 0x6c, 0x06, 0x11, 0xeb, 0x9a, 0x9f, 0x6c, 0xb3, 0xf0, 0x6d, 0xaa, 0xa7, 0xa4,
3132 0xe4, 0x45, 0x45, 0x77, 0x3b, 0x29, 0xba, 0x99, 0xf5, 0xf2, 0xd6, 0x47, 0x6f, 0x96, 0x57, 0xa2,
3133 0xde, 0x2a, 0x4f, 0x40, 0x39, 0xf7, 0xd5, 0x38, 0x08, 0x5c, 0x2f, 0xfe, 0x3d, 0xe1, 0x35, 0x0d,
3134 0x78, 0x11, 0xf2, 0xe2, 0x97, 0x0a, 0x31, 0x7c, 0x8a, 0x17, 0x65, 0x07, 0xee, 0x5e, 0xca, 0x32,
3135 0xba, 0x35, 0x9b, 0xbe, 0xe8, 0xf3, 0xe4, 0xa7, 0x0e, 0xc6, 0xa0, 0xe8, 0xd0, 0xe7, 0x9c, 0x48,
3136 0xf9, 0xb3, 0x94, 0x1a, 0x13, 0xf9, 0xe5, 0x55, 0xc7, 0xec, 0x3d, 0x77, 0x66, 0x7a, 0xe9, 0x6b,
3137 0x16, 0x52, 0x77, 0xa1, 0x6a, 0x53, 0xe2, 0xd3, 0x64, 0xda, 0xcd, 0xf0, 0x69, 0xb7, 0xc2, 0x81,
3138 0xf1, 0x88, 0xbb, 0x0a, 0x25, 0xd6, 0xee, 0xe2, 0xf9, 0x9d, 0xdf, 0x62, 0x4c, 0x4e, 0xc5, 0x0c,
3139 0xf8, 0x31, 0x54, 0x46, 0xac, 0xb9, 0x1b, 0x87, 0x67, 0xbc, 0x57, 0xb2, 0xa6, 0x92, 0x7c, 0xc6,
3140 0x01, 0x47, 0xed, 0x9c, 0xb1, 0xa6, 0x19, 0x65, 0x71, 0x3e, 0xc9, 0x62, 0xe5, 0x9f, 0x12, 0xdc,
3141 0xb9, 0x44, 0x81, 0xc8, 0x06, 0xda, 0x4c, 0xbb, 0xbc, 0xff, 0x4a, 0xcf, 0xcd, 0x39, 0x9b, 0x6e,
3142 0x9a, 0xbf, 0x96, 0xae, 0xd9, 0x34, 0xcf, 0xf5, 0xb3, 0xdc, 0xbc, 0x7e, 0x16, 0xb7, 0x99, 0xfc,
3143 0xb9, 0x36, 0x13, 0xe9, 0x5e, 0x98, 0xea, 0xfe, 0x7b, 0x29, 0xf5, 0xc5, 0xb5, 0xef, 0x9a, 0xd6,
3144 0x11, 0x0f, 0xbd, 0x0e, 0xb3, 0xfb, 0x4f, 0xfc, 0x5b, 0xca, 0x05, 0x9f, 0xe7, 0x2e, 0xfa, 0x5c,
3145 0xe9, 0xa4, 0x62, 0xeb, 0xc2, 0xf5, 0xa6, 0x5b, 0xe7, 0x90, 0xc7, 0xae, 0x39, 0x9d, 0xa5, 0x44,
3146 0x90, 0xd6, 0x22, 0x78, 0x34, 0x4d, 0xed, 0x94, 0xbf, 0x2b, 0x25, 0xbf, 0x77, 0xff, 0x3b, 0x00,
3147 0x00, 0xff, 0xff, 0x67, 0xac, 0x35, 0x53, 0x2a, 0x1f, 0x00, 0x00,
3148 }
0 syntax = "proto2";
1 option go_package = "taskqueue";
2
3 import "google.golang.org/appengine/v2/internal/datastore/datastore_v3.proto";
4
5 package appengine;
6
7 message TaskQueueServiceError {
8 enum ErrorCode {
9 OK = 0;
10 UNKNOWN_QUEUE = 1;
11 TRANSIENT_ERROR = 2;
12 INTERNAL_ERROR = 3;
13 TASK_TOO_LARGE = 4;
14 INVALID_TASK_NAME = 5;
15 INVALID_QUEUE_NAME = 6;
16 INVALID_URL = 7;
17 INVALID_QUEUE_RATE = 8;
18 PERMISSION_DENIED = 9;
19 TASK_ALREADY_EXISTS = 10;
20 TOMBSTONED_TASK = 11;
21 INVALID_ETA = 12;
22 INVALID_REQUEST = 13;
23 UNKNOWN_TASK = 14;
24 TOMBSTONED_QUEUE = 15;
25 DUPLICATE_TASK_NAME = 16;
26 SKIPPED = 17;
27 TOO_MANY_TASKS = 18;
28 INVALID_PAYLOAD = 19;
29 INVALID_RETRY_PARAMETERS = 20;
30 INVALID_QUEUE_MODE = 21;
31 ACL_LOOKUP_ERROR = 22;
32 TRANSACTIONAL_REQUEST_TOO_LARGE = 23;
33 INCORRECT_CREATOR_NAME = 24;
34 TASK_LEASE_EXPIRED = 25;
35 QUEUE_PAUSED = 26;
36 INVALID_TAG = 27;
37
38 // Reserved range for the Datastore error codes.
39 // Original Datastore error code is shifted by DATASTORE_ERROR offset.
40 DATASTORE_ERROR = 10000;
41 }
42 }
43
44 message TaskPayload {
45 extensions 10 to max;
46 option message_set_wire_format = true;
47 }
48
49 message TaskQueueRetryParameters {
50 optional int32 retry_limit = 1;
51 optional int64 age_limit_sec = 2;
52
53 optional double min_backoff_sec = 3 [default = 0.1];
54 optional double max_backoff_sec = 4 [default = 3600];
55 optional int32 max_doublings = 5 [default = 16];
56 }
57
58 message TaskQueueAcl {
59 repeated bytes user_email = 1;
60 repeated bytes writer_email = 2;
61 }
62
63 message TaskQueueHttpHeader {
64 required bytes key = 1;
65 required bytes value = 2;
66 }
67
68 message TaskQueueMode {
69 enum Mode {
70 PUSH = 0;
71 PULL = 1;
72 }
73 }
74
75 message TaskQueueAddRequest {
76 required bytes queue_name = 1;
77 required bytes task_name = 2;
78 required int64 eta_usec = 3;
79
80 enum RequestMethod {
81 GET = 1;
82 POST = 2;
83 HEAD = 3;
84 PUT = 4;
85 DELETE = 5;
86 }
87 optional RequestMethod method = 5 [default=POST];
88
89 optional bytes url = 4;
90
91 repeated group Header = 6 {
92 required bytes key = 7;
93 required bytes value = 8;
94 }
95
96 optional bytes body = 9 [ctype=CORD];
97 optional Transaction transaction = 10;
98 optional bytes app_id = 11;
99
100 optional group CronTimetable = 12 {
101 required bytes schedule = 13;
102 required bytes timezone = 14;
103 }
104
105 optional bytes description = 15;
106 optional TaskPayload payload = 16;
107 optional TaskQueueRetryParameters retry_parameters = 17;
108 optional TaskQueueMode.Mode mode = 18 [default=PUSH];
109 optional bytes tag = 19;
110 }
111
112 message TaskQueueAddResponse {
113 optional bytes chosen_task_name = 1;
114 }
115
116 message TaskQueueBulkAddRequest {
117 repeated TaskQueueAddRequest add_request = 1;
118 }
119
120 message TaskQueueBulkAddResponse {
121 repeated group TaskResult = 1 {
122 required TaskQueueServiceError.ErrorCode result = 2;
123 optional bytes chosen_task_name = 3;
124 }
125 }
126
127 message TaskQueueDeleteRequest {
128 required bytes queue_name = 1;
129 repeated bytes task_name = 2;
130 optional bytes app_id = 3;
131 }
132
133 message TaskQueueDeleteResponse {
134 repeated TaskQueueServiceError.ErrorCode result = 3;
135 }
136
137 message TaskQueueForceRunRequest {
138 optional bytes app_id = 1;
139 required bytes queue_name = 2;
140 required bytes task_name = 3;
141 }
142
143 message TaskQueueForceRunResponse {
144 required TaskQueueServiceError.ErrorCode result = 3;
145 }
146
147 message TaskQueueUpdateQueueRequest {
148 optional bytes app_id = 1;
149 required bytes queue_name = 2;
150 required double bucket_refill_per_second = 3;
151 required int32 bucket_capacity = 4;
152 optional string user_specified_rate = 5;
153 optional TaskQueueRetryParameters retry_parameters = 6;
154 optional int32 max_concurrent_requests = 7;
155 optional TaskQueueMode.Mode mode = 8 [default = PUSH];
156 optional TaskQueueAcl acl = 9;
157 repeated TaskQueueHttpHeader header_override = 10;
158 }
159
160 message TaskQueueUpdateQueueResponse {
161 }
162
163 message TaskQueueFetchQueuesRequest {
164 optional bytes app_id = 1;
165 required int32 max_rows = 2;
166 }
167
168 message TaskQueueFetchQueuesResponse {
169 repeated group Queue = 1 {
170 required bytes queue_name = 2;
171 required double bucket_refill_per_second = 3;
172 required double bucket_capacity = 4;
173 optional string user_specified_rate = 5;
174 required bool paused = 6 [default=false];
175 optional TaskQueueRetryParameters retry_parameters = 7;
176 optional int32 max_concurrent_requests = 8;
177 optional TaskQueueMode.Mode mode = 9 [default = PUSH];
178 optional TaskQueueAcl acl = 10;
179 repeated TaskQueueHttpHeader header_override = 11;
180 optional string creator_name = 12 [ctype=CORD, default="apphosting"];
181 }
182 }
183
184 message TaskQueueFetchQueueStatsRequest {
185 optional bytes app_id = 1;
186 repeated bytes queue_name = 2;
187 optional int32 max_num_tasks = 3 [default = 0];
188 }
189
190 message TaskQueueScannerQueueInfo {
191 required int64 executed_last_minute = 1;
192 required int64 executed_last_hour = 2;
193 required double sampling_duration_seconds = 3;
194 optional int32 requests_in_flight = 4;
195 optional double enforced_rate = 5;
196 }
197
198 message TaskQueueFetchQueueStatsResponse {
199 repeated group QueueStats = 1 {
200 required int32 num_tasks = 2;
201 required int64 oldest_eta_usec = 3;
202 optional TaskQueueScannerQueueInfo scanner_info = 4;
203 }
204 }
205 message TaskQueuePauseQueueRequest {
206 required bytes app_id = 1;
207 required bytes queue_name = 2;
208 required bool pause = 3;
209 }
210
211 message TaskQueuePauseQueueResponse {
212 }
213
214 message TaskQueuePurgeQueueRequest {
215 optional bytes app_id = 1;
216 required bytes queue_name = 2;
217 }
218
219 message TaskQueuePurgeQueueResponse {
220 }
221
222 message TaskQueueDeleteQueueRequest {
223 required bytes app_id = 1;
224 required bytes queue_name = 2;
225 }
226
227 message TaskQueueDeleteQueueResponse {
228 }
229
230 message TaskQueueDeleteGroupRequest {
231 required bytes app_id = 1;
232 }
233
234 message TaskQueueDeleteGroupResponse {
235 }
236
237 message TaskQueueQueryTasksRequest {
238 optional bytes app_id = 1;
239 required bytes queue_name = 2;
240
241 optional bytes start_task_name = 3;
242 optional int64 start_eta_usec = 4;
243 optional bytes start_tag = 6;
244 optional int32 max_rows = 5 [default = 1];
245 }
246
247 message TaskQueueQueryTasksResponse {
248 repeated group Task = 1 {
249 required bytes task_name = 2;
250 required int64 eta_usec = 3;
251 optional bytes url = 4;
252
253 enum RequestMethod {
254 GET = 1;
255 POST = 2;
256 HEAD = 3;
257 PUT = 4;
258 DELETE = 5;
259 }
260 optional RequestMethod method = 5;
261
262 optional int32 retry_count = 6 [default=0];
263
264 repeated group Header = 7 {
265 required bytes key = 8;
266 required bytes value = 9;
267 }
268
269 optional int32 body_size = 10;
270 optional bytes body = 11 [ctype=CORD];
271 required int64 creation_time_usec = 12;
272
273 optional group CronTimetable = 13 {
274 required bytes schedule = 14;
275 required bytes timezone = 15;
276 }
277
278 optional group RunLog = 16 {
279 required int64 dispatched_usec = 17;
280 required int64 lag_usec = 18;
281 required int64 elapsed_usec = 19;
282 optional int64 response_code = 20;
283 optional string retry_reason = 27;
284 }
285
286 optional bytes description = 21;
287 optional TaskPayload payload = 22;
288 optional TaskQueueRetryParameters retry_parameters = 23;
289 optional int64 first_try_usec = 24;
290 optional bytes tag = 25;
291 optional int32 execution_count = 26 [default=0];
292 }
293 }
294
295 message TaskQueueFetchTaskRequest {
296 optional bytes app_id = 1;
297 required bytes queue_name = 2;
298 required bytes task_name = 3;
299 }
300
301 message TaskQueueFetchTaskResponse {
302 required TaskQueueQueryTasksResponse task = 1;
303 }
304
305 message TaskQueueUpdateStorageLimitRequest {
306 required bytes app_id = 1;
307 required int64 limit = 2;
308 }
309
310 message TaskQueueUpdateStorageLimitResponse {
311 required int64 new_limit = 1;
312 }
313
314 message TaskQueueQueryAndOwnTasksRequest {
315 required bytes queue_name = 1;
316 required double lease_seconds = 2;
317 required int64 max_tasks = 3;
318 optional bool group_by_tag = 4 [default=false];
319 optional bytes tag = 5;
320 }
321
322 message TaskQueueQueryAndOwnTasksResponse {
323 repeated group Task = 1 {
324 required bytes task_name = 2;
325 required int64 eta_usec = 3;
326 optional int32 retry_count = 4 [default=0];
327 optional bytes body = 5 [ctype=CORD];
328 optional bytes tag = 6;
329 }
330 }
331
332 message TaskQueueModifyTaskLeaseRequest {
333 required bytes queue_name = 1;
334 required bytes task_name = 2;
335 required int64 eta_usec = 3;
336 required double lease_seconds = 4;
337 }
338
339 message TaskQueueModifyTaskLeaseResponse {
340 required int64 updated_eta_usec = 1;
341 }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package internal
5
6 // This file implements hooks for applying datastore transactions.
7
8 import (
9 netcontext "context"
10 "errors"
11 "reflect"
12
13 "github.com/golang/protobuf/proto"
14
15 basepb "google.golang.org/appengine/v2/internal/base"
16 pb "google.golang.org/appengine/v2/internal/datastore"
17 )
18
19 var transactionSetters = make(map[reflect.Type]reflect.Value)
20
21 // RegisterTransactionSetter registers a function that sets transaction information
22 // in a protocol buffer message. f should be a function with two arguments,
23 // the first being a protocol buffer type, and the second being *datastore.Transaction.
24 func RegisterTransactionSetter(f interface{}) {
25 v := reflect.ValueOf(f)
26 transactionSetters[v.Type().In(0)] = v
27 }
28
29 // applyTransaction applies the transaction t to message pb
30 // by using the relevant setter passed to RegisterTransactionSetter.
31 func applyTransaction(pb proto.Message, t *pb.Transaction) {
32 v := reflect.ValueOf(pb)
33 if f, ok := transactionSetters[v.Type()]; ok {
34 f.Call([]reflect.Value{v, reflect.ValueOf(t)})
35 }
36 }
37
38 var transactionKey = "used for *Transaction"
39
40 func transactionFromContext(ctx netcontext.Context) *transaction {
41 t, _ := ctx.Value(&transactionKey).(*transaction)
42 return t
43 }
44
45 func withTransaction(ctx netcontext.Context, t *transaction) netcontext.Context {
46 return netcontext.WithValue(ctx, &transactionKey, t)
47 }
48
49 type transaction struct {
50 transaction pb.Transaction
51 finished bool
52 }
53
54 var ErrConcurrentTransaction = errors.New("internal: concurrent transaction")
55
56 func RunTransactionOnce(c netcontext.Context, f func(netcontext.Context) error, xg bool, readOnly bool, previousTransaction *pb.Transaction) (*pb.Transaction, error) {
57 if transactionFromContext(c) != nil {
58 return nil, errors.New("nested transactions are not supported")
59 }
60
61 // Begin the transaction.
62 t := &transaction{}
63 req := &pb.BeginTransactionRequest{
64 App: proto.String(FullyQualifiedAppID(c)),
65 }
66 if xg {
67 req.AllowMultipleEg = proto.Bool(true)
68 }
69 if previousTransaction != nil {
70 req.PreviousTransaction = previousTransaction
71 }
72 if readOnly {
73 req.Mode = pb.BeginTransactionRequest_READ_ONLY.Enum()
74 } else {
75 req.Mode = pb.BeginTransactionRequest_READ_WRITE.Enum()
76 }
77 if err := Call(c, "datastore_v3", "BeginTransaction", req, &t.transaction); err != nil {
78 return nil, err
79 }
80
81 // Call f, rolling back the transaction if f returns a non-nil error, or panics.
82 // The panic is not recovered.
83 defer func() {
84 if t.finished {
85 return
86 }
87 t.finished = true
88 // Ignore the error return value, since we are already returning a non-nil
89 // error (or we're panicking).
90 Call(c, "datastore_v3", "Rollback", &t.transaction, &basepb.VoidProto{})
91 }()
92 if err := f(withTransaction(c, t)); err != nil {
93 return &t.transaction, err
94 }
95 t.finished = true
96
97 // Commit the transaction.
98 res := &pb.CommitResponse{}
99 err := Call(c, "datastore_v3", "Commit", &t.transaction, res)
100 if ae, ok := err.(*APIError); ok {
101 /* TODO: restore this conditional
102 if appengine.IsDevAppServer() {
103 */
104 // The Python Dev AppServer raises an ApplicationError with error code 2 (which is
105 // Error.CONCURRENT_TRANSACTION) and message "Concurrency exception.".
106 if ae.Code == int32(pb.Error_BAD_REQUEST) && ae.Detail == "ApplicationError: 2 Concurrency exception." {
107 return &t.transaction, ErrConcurrentTransaction
108 }
109 if ae.Code == int32(pb.Error_CONCURRENT_TRANSACTION) {
110 return &t.transaction, ErrConcurrentTransaction
111 }
112 }
113 return &t.transaction, err
114 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto
2
3 package urlfetch
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type URLFetchServiceError_ErrorCode int32
21
22 const (
23 URLFetchServiceError_OK URLFetchServiceError_ErrorCode = 0
24 URLFetchServiceError_INVALID_URL URLFetchServiceError_ErrorCode = 1
25 URLFetchServiceError_FETCH_ERROR URLFetchServiceError_ErrorCode = 2
26 URLFetchServiceError_UNSPECIFIED_ERROR URLFetchServiceError_ErrorCode = 3
27 URLFetchServiceError_RESPONSE_TOO_LARGE URLFetchServiceError_ErrorCode = 4
28 URLFetchServiceError_DEADLINE_EXCEEDED URLFetchServiceError_ErrorCode = 5
29 URLFetchServiceError_SSL_CERTIFICATE_ERROR URLFetchServiceError_ErrorCode = 6
30 URLFetchServiceError_DNS_ERROR URLFetchServiceError_ErrorCode = 7
31 URLFetchServiceError_CLOSED URLFetchServiceError_ErrorCode = 8
32 URLFetchServiceError_INTERNAL_TRANSIENT_ERROR URLFetchServiceError_ErrorCode = 9
33 URLFetchServiceError_TOO_MANY_REDIRECTS URLFetchServiceError_ErrorCode = 10
34 URLFetchServiceError_MALFORMED_REPLY URLFetchServiceError_ErrorCode = 11
35 URLFetchServiceError_CONNECTION_ERROR URLFetchServiceError_ErrorCode = 12
36 )
37
38 var URLFetchServiceError_ErrorCode_name = map[int32]string{
39 0: "OK",
40 1: "INVALID_URL",
41 2: "FETCH_ERROR",
42 3: "UNSPECIFIED_ERROR",
43 4: "RESPONSE_TOO_LARGE",
44 5: "DEADLINE_EXCEEDED",
45 6: "SSL_CERTIFICATE_ERROR",
46 7: "DNS_ERROR",
47 8: "CLOSED",
48 9: "INTERNAL_TRANSIENT_ERROR",
49 10: "TOO_MANY_REDIRECTS",
50 11: "MALFORMED_REPLY",
51 12: "CONNECTION_ERROR",
52 }
53 var URLFetchServiceError_ErrorCode_value = map[string]int32{
54 "OK": 0,
55 "INVALID_URL": 1,
56 "FETCH_ERROR": 2,
57 "UNSPECIFIED_ERROR": 3,
58 "RESPONSE_TOO_LARGE": 4,
59 "DEADLINE_EXCEEDED": 5,
60 "SSL_CERTIFICATE_ERROR": 6,
61 "DNS_ERROR": 7,
62 "CLOSED": 8,
63 "INTERNAL_TRANSIENT_ERROR": 9,
64 "TOO_MANY_REDIRECTS": 10,
65 "MALFORMED_REPLY": 11,
66 "CONNECTION_ERROR": 12,
67 }
68
69 func (x URLFetchServiceError_ErrorCode) Enum() *URLFetchServiceError_ErrorCode {
70 p := new(URLFetchServiceError_ErrorCode)
71 *p = x
72 return p
73 }
74 func (x URLFetchServiceError_ErrorCode) String() string {
75 return proto.EnumName(URLFetchServiceError_ErrorCode_name, int32(x))
76 }
77 func (x *URLFetchServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
78 value, err := proto.UnmarshalJSONEnum(URLFetchServiceError_ErrorCode_value, data, "URLFetchServiceError_ErrorCode")
79 if err != nil {
80 return err
81 }
82 *x = URLFetchServiceError_ErrorCode(value)
83 return nil
84 }
85 func (URLFetchServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
86 return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0, 0}
87 }
88
89 type URLFetchRequest_RequestMethod int32
90
91 const (
92 URLFetchRequest_GET URLFetchRequest_RequestMethod = 1
93 URLFetchRequest_POST URLFetchRequest_RequestMethod = 2
94 URLFetchRequest_HEAD URLFetchRequest_RequestMethod = 3
95 URLFetchRequest_PUT URLFetchRequest_RequestMethod = 4
96 URLFetchRequest_DELETE URLFetchRequest_RequestMethod = 5
97 URLFetchRequest_PATCH URLFetchRequest_RequestMethod = 6
98 )
99
100 var URLFetchRequest_RequestMethod_name = map[int32]string{
101 1: "GET",
102 2: "POST",
103 3: "HEAD",
104 4: "PUT",
105 5: "DELETE",
106 6: "PATCH",
107 }
108 var URLFetchRequest_RequestMethod_value = map[string]int32{
109 "GET": 1,
110 "POST": 2,
111 "HEAD": 3,
112 "PUT": 4,
113 "DELETE": 5,
114 "PATCH": 6,
115 }
116
117 func (x URLFetchRequest_RequestMethod) Enum() *URLFetchRequest_RequestMethod {
118 p := new(URLFetchRequest_RequestMethod)
119 *p = x
120 return p
121 }
122 func (x URLFetchRequest_RequestMethod) String() string {
123 return proto.EnumName(URLFetchRequest_RequestMethod_name, int32(x))
124 }
125 func (x *URLFetchRequest_RequestMethod) UnmarshalJSON(data []byte) error {
126 value, err := proto.UnmarshalJSONEnum(URLFetchRequest_RequestMethod_value, data, "URLFetchRequest_RequestMethod")
127 if err != nil {
128 return err
129 }
130 *x = URLFetchRequest_RequestMethod(value)
131 return nil
132 }
133 func (URLFetchRequest_RequestMethod) EnumDescriptor() ([]byte, []int) {
134 return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0}
135 }
136
137 type URLFetchServiceError struct {
138 XXX_NoUnkeyedLiteral struct{} `json:"-"`
139 XXX_unrecognized []byte `json:"-"`
140 XXX_sizecache int32 `json:"-"`
141 }
142
143 func (m *URLFetchServiceError) Reset() { *m = URLFetchServiceError{} }
144 func (m *URLFetchServiceError) String() string { return proto.CompactTextString(m) }
145 func (*URLFetchServiceError) ProtoMessage() {}
146 func (*URLFetchServiceError) Descriptor() ([]byte, []int) {
147 return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{0}
148 }
149 func (m *URLFetchServiceError) XXX_Unmarshal(b []byte) error {
150 return xxx_messageInfo_URLFetchServiceError.Unmarshal(m, b)
151 }
152 func (m *URLFetchServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
153 return xxx_messageInfo_URLFetchServiceError.Marshal(b, m, deterministic)
154 }
155 func (dst *URLFetchServiceError) XXX_Merge(src proto.Message) {
156 xxx_messageInfo_URLFetchServiceError.Merge(dst, src)
157 }
158 func (m *URLFetchServiceError) XXX_Size() int {
159 return xxx_messageInfo_URLFetchServiceError.Size(m)
160 }
161 func (m *URLFetchServiceError) XXX_DiscardUnknown() {
162 xxx_messageInfo_URLFetchServiceError.DiscardUnknown(m)
163 }
164
165 var xxx_messageInfo_URLFetchServiceError proto.InternalMessageInfo
166
167 type URLFetchRequest struct {
168 Method *URLFetchRequest_RequestMethod `protobuf:"varint,1,req,name=Method,enum=appengine.URLFetchRequest_RequestMethod" json:"Method,omitempty"`
169 Url *string `protobuf:"bytes,2,req,name=Url" json:"Url,omitempty"`
170 Header []*URLFetchRequest_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"`
171 Payload []byte `protobuf:"bytes,6,opt,name=Payload" json:"Payload,omitempty"`
172 FollowRedirects *bool `protobuf:"varint,7,opt,name=FollowRedirects,def=1" json:"FollowRedirects,omitempty"`
173 Deadline *float64 `protobuf:"fixed64,8,opt,name=Deadline" json:"Deadline,omitempty"`
174 MustValidateServerCertificate *bool `protobuf:"varint,9,opt,name=MustValidateServerCertificate,def=1" json:"MustValidateServerCertificate,omitempty"`
175 XXX_NoUnkeyedLiteral struct{} `json:"-"`
176 XXX_unrecognized []byte `json:"-"`
177 XXX_sizecache int32 `json:"-"`
178 }
179
180 func (m *URLFetchRequest) Reset() { *m = URLFetchRequest{} }
181 func (m *URLFetchRequest) String() string { return proto.CompactTextString(m) }
182 func (*URLFetchRequest) ProtoMessage() {}
183 func (*URLFetchRequest) Descriptor() ([]byte, []int) {
184 return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1}
185 }
186 func (m *URLFetchRequest) XXX_Unmarshal(b []byte) error {
187 return xxx_messageInfo_URLFetchRequest.Unmarshal(m, b)
188 }
189 func (m *URLFetchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
190 return xxx_messageInfo_URLFetchRequest.Marshal(b, m, deterministic)
191 }
192 func (dst *URLFetchRequest) XXX_Merge(src proto.Message) {
193 xxx_messageInfo_URLFetchRequest.Merge(dst, src)
194 }
195 func (m *URLFetchRequest) XXX_Size() int {
196 return xxx_messageInfo_URLFetchRequest.Size(m)
197 }
198 func (m *URLFetchRequest) XXX_DiscardUnknown() {
199 xxx_messageInfo_URLFetchRequest.DiscardUnknown(m)
200 }
201
202 var xxx_messageInfo_URLFetchRequest proto.InternalMessageInfo
203
204 const Default_URLFetchRequest_FollowRedirects bool = true
205 const Default_URLFetchRequest_MustValidateServerCertificate bool = true
206
207 func (m *URLFetchRequest) GetMethod() URLFetchRequest_RequestMethod {
208 if m != nil && m.Method != nil {
209 return *m.Method
210 }
211 return URLFetchRequest_GET
212 }
213
214 func (m *URLFetchRequest) GetUrl() string {
215 if m != nil && m.Url != nil {
216 return *m.Url
217 }
218 return ""
219 }
220
221 func (m *URLFetchRequest) GetHeader() []*URLFetchRequest_Header {
222 if m != nil {
223 return m.Header
224 }
225 return nil
226 }
227
228 func (m *URLFetchRequest) GetPayload() []byte {
229 if m != nil {
230 return m.Payload
231 }
232 return nil
233 }
234
235 func (m *URLFetchRequest) GetFollowRedirects() bool {
236 if m != nil && m.FollowRedirects != nil {
237 return *m.FollowRedirects
238 }
239 return Default_URLFetchRequest_FollowRedirects
240 }
241
242 func (m *URLFetchRequest) GetDeadline() float64 {
243 if m != nil && m.Deadline != nil {
244 return *m.Deadline
245 }
246 return 0
247 }
248
249 func (m *URLFetchRequest) GetMustValidateServerCertificate() bool {
250 if m != nil && m.MustValidateServerCertificate != nil {
251 return *m.MustValidateServerCertificate
252 }
253 return Default_URLFetchRequest_MustValidateServerCertificate
254 }
255
256 type URLFetchRequest_Header struct {
257 Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"`
258 Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"`
259 XXX_NoUnkeyedLiteral struct{} `json:"-"`
260 XXX_unrecognized []byte `json:"-"`
261 XXX_sizecache int32 `json:"-"`
262 }
263
264 func (m *URLFetchRequest_Header) Reset() { *m = URLFetchRequest_Header{} }
265 func (m *URLFetchRequest_Header) String() string { return proto.CompactTextString(m) }
266 func (*URLFetchRequest_Header) ProtoMessage() {}
267 func (*URLFetchRequest_Header) Descriptor() ([]byte, []int) {
268 return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{1, 0}
269 }
270 func (m *URLFetchRequest_Header) XXX_Unmarshal(b []byte) error {
271 return xxx_messageInfo_URLFetchRequest_Header.Unmarshal(m, b)
272 }
273 func (m *URLFetchRequest_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
274 return xxx_messageInfo_URLFetchRequest_Header.Marshal(b, m, deterministic)
275 }
276 func (dst *URLFetchRequest_Header) XXX_Merge(src proto.Message) {
277 xxx_messageInfo_URLFetchRequest_Header.Merge(dst, src)
278 }
279 func (m *URLFetchRequest_Header) XXX_Size() int {
280 return xxx_messageInfo_URLFetchRequest_Header.Size(m)
281 }
282 func (m *URLFetchRequest_Header) XXX_DiscardUnknown() {
283 xxx_messageInfo_URLFetchRequest_Header.DiscardUnknown(m)
284 }
285
286 var xxx_messageInfo_URLFetchRequest_Header proto.InternalMessageInfo
287
288 func (m *URLFetchRequest_Header) GetKey() string {
289 if m != nil && m.Key != nil {
290 return *m.Key
291 }
292 return ""
293 }
294
295 func (m *URLFetchRequest_Header) GetValue() string {
296 if m != nil && m.Value != nil {
297 return *m.Value
298 }
299 return ""
300 }
301
302 type URLFetchResponse struct {
303 Content []byte `protobuf:"bytes,1,opt,name=Content" json:"Content,omitempty"`
304 StatusCode *int32 `protobuf:"varint,2,req,name=StatusCode" json:"StatusCode,omitempty"`
305 Header []*URLFetchResponse_Header `protobuf:"group,3,rep,name=Header,json=header" json:"header,omitempty"`
306 ContentWasTruncated *bool `protobuf:"varint,6,opt,name=ContentWasTruncated,def=0" json:"ContentWasTruncated,omitempty"`
307 ExternalBytesSent *int64 `protobuf:"varint,7,opt,name=ExternalBytesSent" json:"ExternalBytesSent,omitempty"`
308 ExternalBytesReceived *int64 `protobuf:"varint,8,opt,name=ExternalBytesReceived" json:"ExternalBytesReceived,omitempty"`
309 FinalUrl *string `protobuf:"bytes,9,opt,name=FinalUrl" json:"FinalUrl,omitempty"`
310 ApiCpuMilliseconds *int64 `protobuf:"varint,10,opt,name=ApiCpuMilliseconds,def=0" json:"ApiCpuMilliseconds,omitempty"`
311 ApiBytesSent *int64 `protobuf:"varint,11,opt,name=ApiBytesSent,def=0" json:"ApiBytesSent,omitempty"`
312 ApiBytesReceived *int64 `protobuf:"varint,12,opt,name=ApiBytesReceived,def=0" json:"ApiBytesReceived,omitempty"`
313 XXX_NoUnkeyedLiteral struct{} `json:"-"`
314 XXX_unrecognized []byte `json:"-"`
315 XXX_sizecache int32 `json:"-"`
316 }
317
318 func (m *URLFetchResponse) Reset() { *m = URLFetchResponse{} }
319 func (m *URLFetchResponse) String() string { return proto.CompactTextString(m) }
320 func (*URLFetchResponse) ProtoMessage() {}
321 func (*URLFetchResponse) Descriptor() ([]byte, []int) {
322 return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2}
323 }
324 func (m *URLFetchResponse) XXX_Unmarshal(b []byte) error {
325 return xxx_messageInfo_URLFetchResponse.Unmarshal(m, b)
326 }
327 func (m *URLFetchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
328 return xxx_messageInfo_URLFetchResponse.Marshal(b, m, deterministic)
329 }
330 func (dst *URLFetchResponse) XXX_Merge(src proto.Message) {
331 xxx_messageInfo_URLFetchResponse.Merge(dst, src)
332 }
333 func (m *URLFetchResponse) XXX_Size() int {
334 return xxx_messageInfo_URLFetchResponse.Size(m)
335 }
336 func (m *URLFetchResponse) XXX_DiscardUnknown() {
337 xxx_messageInfo_URLFetchResponse.DiscardUnknown(m)
338 }
339
340 var xxx_messageInfo_URLFetchResponse proto.InternalMessageInfo
341
342 const Default_URLFetchResponse_ContentWasTruncated bool = false
343 const Default_URLFetchResponse_ApiCpuMilliseconds int64 = 0
344 const Default_URLFetchResponse_ApiBytesSent int64 = 0
345 const Default_URLFetchResponse_ApiBytesReceived int64 = 0
346
347 func (m *URLFetchResponse) GetContent() []byte {
348 if m != nil {
349 return m.Content
350 }
351 return nil
352 }
353
354 func (m *URLFetchResponse) GetStatusCode() int32 {
355 if m != nil && m.StatusCode != nil {
356 return *m.StatusCode
357 }
358 return 0
359 }
360
361 func (m *URLFetchResponse) GetHeader() []*URLFetchResponse_Header {
362 if m != nil {
363 return m.Header
364 }
365 return nil
366 }
367
368 func (m *URLFetchResponse) GetContentWasTruncated() bool {
369 if m != nil && m.ContentWasTruncated != nil {
370 return *m.ContentWasTruncated
371 }
372 return Default_URLFetchResponse_ContentWasTruncated
373 }
374
375 func (m *URLFetchResponse) GetExternalBytesSent() int64 {
376 if m != nil && m.ExternalBytesSent != nil {
377 return *m.ExternalBytesSent
378 }
379 return 0
380 }
381
382 func (m *URLFetchResponse) GetExternalBytesReceived() int64 {
383 if m != nil && m.ExternalBytesReceived != nil {
384 return *m.ExternalBytesReceived
385 }
386 return 0
387 }
388
389 func (m *URLFetchResponse) GetFinalUrl() string {
390 if m != nil && m.FinalUrl != nil {
391 return *m.FinalUrl
392 }
393 return ""
394 }
395
396 func (m *URLFetchResponse) GetApiCpuMilliseconds() int64 {
397 if m != nil && m.ApiCpuMilliseconds != nil {
398 return *m.ApiCpuMilliseconds
399 }
400 return Default_URLFetchResponse_ApiCpuMilliseconds
401 }
402
403 func (m *URLFetchResponse) GetApiBytesSent() int64 {
404 if m != nil && m.ApiBytesSent != nil {
405 return *m.ApiBytesSent
406 }
407 return Default_URLFetchResponse_ApiBytesSent
408 }
409
410 func (m *URLFetchResponse) GetApiBytesReceived() int64 {
411 if m != nil && m.ApiBytesReceived != nil {
412 return *m.ApiBytesReceived
413 }
414 return Default_URLFetchResponse_ApiBytesReceived
415 }
416
417 type URLFetchResponse_Header struct {
418 Key *string `protobuf:"bytes,4,req,name=Key" json:"Key,omitempty"`
419 Value *string `protobuf:"bytes,5,req,name=Value" json:"Value,omitempty"`
420 XXX_NoUnkeyedLiteral struct{} `json:"-"`
421 XXX_unrecognized []byte `json:"-"`
422 XXX_sizecache int32 `json:"-"`
423 }
424
425 func (m *URLFetchResponse_Header) Reset() { *m = URLFetchResponse_Header{} }
426 func (m *URLFetchResponse_Header) String() string { return proto.CompactTextString(m) }
427 func (*URLFetchResponse_Header) ProtoMessage() {}
428 func (*URLFetchResponse_Header) Descriptor() ([]byte, []int) {
429 return fileDescriptor_urlfetch_service_b245a7065f33bced, []int{2, 0}
430 }
431 func (m *URLFetchResponse_Header) XXX_Unmarshal(b []byte) error {
432 return xxx_messageInfo_URLFetchResponse_Header.Unmarshal(m, b)
433 }
434 func (m *URLFetchResponse_Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
435 return xxx_messageInfo_URLFetchResponse_Header.Marshal(b, m, deterministic)
436 }
437 func (dst *URLFetchResponse_Header) XXX_Merge(src proto.Message) {
438 xxx_messageInfo_URLFetchResponse_Header.Merge(dst, src)
439 }
440 func (m *URLFetchResponse_Header) XXX_Size() int {
441 return xxx_messageInfo_URLFetchResponse_Header.Size(m)
442 }
443 func (m *URLFetchResponse_Header) XXX_DiscardUnknown() {
444 xxx_messageInfo_URLFetchResponse_Header.DiscardUnknown(m)
445 }
446
447 var xxx_messageInfo_URLFetchResponse_Header proto.InternalMessageInfo
448
449 func (m *URLFetchResponse_Header) GetKey() string {
450 if m != nil && m.Key != nil {
451 return *m.Key
452 }
453 return ""
454 }
455
456 func (m *URLFetchResponse_Header) GetValue() string {
457 if m != nil && m.Value != nil {
458 return *m.Value
459 }
460 return ""
461 }
462
463 func init() {
464 proto.RegisterType((*URLFetchServiceError)(nil), "appengine.URLFetchServiceError")
465 proto.RegisterType((*URLFetchRequest)(nil), "appengine.URLFetchRequest")
466 proto.RegisterType((*URLFetchRequest_Header)(nil), "appengine.URLFetchRequest.Header")
467 proto.RegisterType((*URLFetchResponse)(nil), "appengine.URLFetchResponse")
468 proto.RegisterType((*URLFetchResponse_Header)(nil), "appengine.URLFetchResponse.Header")
469 }
470
471 func init() {
472 proto.RegisterFile("google.golang.org/appengine/v2/internal/urlfetch/urlfetch_service.proto", fileDescriptor_urlfetch_service_b245a7065f33bced)
473 }
474
475 var fileDescriptor_urlfetch_service_b245a7065f33bced = []byte{
476 // 770 bytes of a gzipped FileDescriptorProto
477 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0xe3, 0x54,
478 0x10, 0xc6, 0x76, 0x7e, 0xa7, 0x5d, 0x7a, 0x76, 0xb6, 0x45, 0x66, 0xb5, 0xa0, 0x10, 0x09, 0x29,
479 0x17, 0x90, 0x2e, 0x2b, 0x24, 0x44, 0xaf, 0x70, 0xed, 0x93, 0xad, 0xa9, 0x63, 0x47, 0xc7, 0x4e,
480 0x61, 0xb9, 0xb1, 0xac, 0x78, 0x9a, 0x5a, 0xb2, 0xec, 0x60, 0x9f, 0x2c, 0xf4, 0x35, 0x78, 0x0d,
481 0xde, 0x87, 0xa7, 0xe1, 0x02, 0x9d, 0xc4, 0xc9, 0x6e, 0xbb, 0xd1, 0x4a, 0x5c, 0x65, 0xe6, 0x9b,
482 0xef, 0xcc, 0x99, 0x7c, 0xdf, 0xf8, 0x80, 0xb3, 0x2c, 0xcb, 0x65, 0x4e, 0xe3, 0x65, 0x99, 0x27,
483 0xc5, 0x72, 0x5c, 0x56, 0xcb, 0xf3, 0x64, 0xb5, 0xa2, 0x62, 0x99, 0x15, 0x74, 0x9e, 0x15, 0x92,
484 0xaa, 0x22, 0xc9, 0xcf, 0xd7, 0x55, 0x7e, 0x4b, 0x72, 0x71, 0xb7, 0x0f, 0xe2, 0x9a, 0xaa, 0xb7,
485 0xd9, 0x82, 0xc6, 0xab, 0xaa, 0x94, 0x25, 0xf6, 0xf7, 0x67, 0x86, 0x7f, 0xeb, 0x70, 0x3a, 0x17,
486 0xde, 0x44, 0xb1, 0xc2, 0x2d, 0x89, 0x57, 0x55, 0x59, 0x0d, 0xff, 0xd2, 0xa1, 0xbf, 0x89, 0xec,
487 0x32, 0x25, 0xec, 0x80, 0x1e, 0x5c, 0xb3, 0x4f, 0xf0, 0x04, 0x8e, 0x5c, 0xff, 0xc6, 0xf2, 0x5c,
488 0x27, 0x9e, 0x0b, 0x8f, 0x69, 0x0a, 0x98, 0xf0, 0xc8, 0xbe, 0x8a, 0xb9, 0x10, 0x81, 0x60, 0x3a,
489 0x9e, 0xc1, 0xd3, 0xb9, 0x1f, 0xce, 0xb8, 0xed, 0x4e, 0x5c, 0xee, 0x34, 0xb0, 0x81, 0x9f, 0x01,
490 0x0a, 0x1e, 0xce, 0x02, 0x3f, 0xe4, 0x71, 0x14, 0x04, 0xb1, 0x67, 0x89, 0xd7, 0x9c, 0xb5, 0x14,
491 0xdd, 0xe1, 0x96, 0xe3, 0xb9, 0x3e, 0x8f, 0xf9, 0xaf, 0x36, 0xe7, 0x0e, 0x77, 0x58, 0x1b, 0x3f,
492 0x87, 0xb3, 0x30, 0xf4, 0x62, 0x9b, 0x8b, 0xc8, 0x9d, 0xb8, 0xb6, 0x15, 0xf1, 0xa6, 0x53, 0x07,
493 0x9f, 0x40, 0xdf, 0xf1, 0xc3, 0x26, 0xed, 0x22, 0x40, 0xc7, 0xf6, 0x82, 0x90, 0x3b, 0xac, 0x87,
494 0x2f, 0xc0, 0x74, 0xfd, 0x88, 0x0b, 0xdf, 0xf2, 0xe2, 0x48, 0x58, 0x7e, 0xe8, 0x72, 0x3f, 0x6a,
495 0x98, 0x7d, 0x35, 0x82, 0xba, 0x79, 0x6a, 0xf9, 0x6f, 0x62, 0xc1, 0x1d, 0x57, 0x70, 0x3b, 0x0a,
496 0x19, 0xe0, 0x33, 0x38, 0x99, 0x5a, 0xde, 0x24, 0x10, 0x53, 0xee, 0xc4, 0x82, 0xcf, 0xbc, 0x37,
497 0xec, 0x08, 0x4f, 0x81, 0xd9, 0x81, 0xef, 0x73, 0x3b, 0x72, 0x03, 0xbf, 0x69, 0x71, 0x3c, 0xfc,
498 0xc7, 0x80, 0x93, 0x9d, 0x5a, 0x82, 0x7e, 0x5f, 0x53, 0x2d, 0xf1, 0x27, 0xe8, 0x4c, 0x49, 0xde,
499 0x95, 0xa9, 0xa9, 0x0d, 0xf4, 0xd1, 0xa7, 0xaf, 0x46, 0xe3, 0xbd, 0xba, 0xe3, 0x47, 0xdc, 0x71,
500 0xf3, 0xbb, 0xe5, 0x8b, 0xe6, 0x1c, 0x32, 0x30, 0xe6, 0x55, 0x6e, 0xea, 0x03, 0x7d, 0xd4, 0x17,
501 0x2a, 0xc4, 0x1f, 0xa1, 0x73, 0x47, 0x49, 0x4a, 0x95, 0x69, 0x0c, 0x8c, 0x11, 0xbc, 0xfa, 0xea,
502 0x23, 0x3d, 0xaf, 0x36, 0x44, 0xd1, 0x1c, 0xc0, 0x17, 0xd0, 0x9d, 0x25, 0xf7, 0x79, 0x99, 0xa4,
503 0x66, 0x67, 0xa0, 0x8d, 0x8e, 0x2f, 0xf5, 0x9e, 0x26, 0x76, 0x10, 0x8e, 0xe1, 0x64, 0x52, 0xe6,
504 0x79, 0xf9, 0x87, 0xa0, 0x34, 0xab, 0x68, 0x21, 0x6b, 0xb3, 0x3b, 0xd0, 0x46, 0xbd, 0x8b, 0x96,
505 0xac, 0xd6, 0x24, 0x1e, 0x17, 0xf1, 0x39, 0xf4, 0x1c, 0x4a, 0xd2, 0x3c, 0x2b, 0xc8, 0xec, 0x0d,
506 0xb4, 0x91, 0x26, 0xf6, 0x39, 0xfe, 0x0c, 0x5f, 0x4c, 0xd7, 0xb5, 0xbc, 0x49, 0xf2, 0x2c, 0x4d,
507 0x24, 0xa9, 0xed, 0xa1, 0xca, 0xa6, 0x4a, 0x66, 0xb7, 0xd9, 0x22, 0x91, 0x64, 0xf6, 0xdf, 0xeb,
508 0xfc, 0x71, 0xea, 0xf3, 0x97, 0xd0, 0xd9, 0xfe, 0x0f, 0x25, 0xc6, 0x35, 0xdd, 0x9b, 0xad, 0xad,
509 0x18, 0xd7, 0x74, 0x8f, 0xa7, 0xd0, 0xbe, 0x49, 0xf2, 0x35, 0x99, 0xed, 0x0d, 0xb6, 0x4d, 0x86,
510 0x1e, 0x3c, 0x79, 0xa0, 0x26, 0x76, 0xc1, 0x78, 0xcd, 0x23, 0xa6, 0x61, 0x0f, 0x5a, 0xb3, 0x20,
511 0x8c, 0x98, 0xae, 0xa2, 0x2b, 0x6e, 0x39, 0xcc, 0x50, 0xc5, 0xd9, 0x3c, 0x62, 0x2d, 0xb5, 0x2e,
512 0x0e, 0xf7, 0x78, 0xc4, 0x59, 0x1b, 0xfb, 0xd0, 0x9e, 0x59, 0x91, 0x7d, 0xc5, 0x3a, 0xc3, 0x7f,
513 0x0d, 0x60, 0xef, 0x84, 0xad, 0x57, 0x65, 0x51, 0x13, 0x9a, 0xd0, 0xb5, 0xcb, 0x42, 0x52, 0x21,
514 0x4d, 0x4d, 0x49, 0x29, 0x76, 0x29, 0x7e, 0x09, 0x10, 0xca, 0x44, 0xae, 0x6b, 0xf5, 0x71, 0x6c,
515 0x8c, 0x6b, 0x8b, 0xf7, 0x10, 0xbc, 0x78, 0xe4, 0xdf, 0xf0, 0xa0, 0x7f, 0xdb, 0x6b, 0x1e, 0x1b,
516 0xf8, 0x03, 0x3c, 0x6b, 0xae, 0xf9, 0x25, 0xa9, 0xa3, 0x6a, 0x5d, 0x28, 0x81, 0xb6, 0x66, 0xf6,
517 0x2e, 0xda, 0xb7, 0x49, 0x5e, 0x93, 0x38, 0xc4, 0xc0, 0x6f, 0xe0, 0x29, 0xff, 0x73, 0xfb, 0x02,
518 0x5c, 0xde, 0x4b, 0xaa, 0x43, 0x35, 0xb8, 0x72, 0xd7, 0x10, 0x1f, 0x16, 0xf0, 0x7b, 0x38, 0x7b,
519 0x00, 0x0a, 0x5a, 0x50, 0xf6, 0x96, 0xd2, 0x8d, 0xcd, 0x86, 0x38, 0x5c, 0x54, 0xfb, 0x30, 0xc9,
520 0x8a, 0x24, 0x57, 0xfb, 0xaa, 0xec, 0xed, 0x8b, 0x7d, 0x8e, 0xdf, 0x01, 0x5a, 0xab, 0xcc, 0x5e,
521 0xad, 0xa7, 0x59, 0x9e, 0x67, 0x35, 0x2d, 0xca, 0x22, 0xad, 0x4d, 0x50, 0xed, 0x2e, 0xb4, 0x97,
522 0xe2, 0x40, 0x11, 0xbf, 0x86, 0x63, 0x6b, 0x95, 0xbd, 0x9b, 0xf6, 0x68, 0x47, 0x7e, 0x00, 0xe3,
523 0xb7, 0xc0, 0x76, 0xf9, 0x7e, 0xcc, 0xe3, 0x1d, 0xf5, 0x83, 0xd2, 0xff, 0x5f, 0xa6, 0x4b, 0xf8,
524 0xad, 0xb7, 0x7b, 0x2a, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x9f, 0x6d, 0x24, 0x63, 0x05,
525 0x00, 0x00,
526 }
0 syntax = "proto2";
1 option go_package = "urlfetch";
2
3 package appengine;
4
5 message URLFetchServiceError {
6 enum ErrorCode {
7 OK = 0;
8 INVALID_URL = 1;
9 FETCH_ERROR = 2;
10 UNSPECIFIED_ERROR = 3;
11 RESPONSE_TOO_LARGE = 4;
12 DEADLINE_EXCEEDED = 5;
13 SSL_CERTIFICATE_ERROR = 6;
14 DNS_ERROR = 7;
15 CLOSED = 8;
16 INTERNAL_TRANSIENT_ERROR = 9;
17 TOO_MANY_REDIRECTS = 10;
18 MALFORMED_REPLY = 11;
19 CONNECTION_ERROR = 12;
20 }
21 }
22
23 message URLFetchRequest {
24 enum RequestMethod {
25 GET = 1;
26 POST = 2;
27 HEAD = 3;
28 PUT = 4;
29 DELETE = 5;
30 PATCH = 6;
31 }
32 required RequestMethod Method = 1;
33 required string Url = 2;
34 repeated group Header = 3 {
35 required string Key = 4;
36 required string Value = 5;
37 }
38 optional bytes Payload = 6 [ctype=CORD];
39
40 optional bool FollowRedirects = 7 [default=true];
41
42 optional double Deadline = 8;
43
44 optional bool MustValidateServerCertificate = 9 [default=true];
45 }
46
47 message URLFetchResponse {
48 optional bytes Content = 1;
49 required int32 StatusCode = 2;
50 repeated group Header = 3 {
51 required string Key = 4;
52 required string Value = 5;
53 }
54 optional bool ContentWasTruncated = 6 [default=false];
55 optional int64 ExternalBytesSent = 7;
56 optional int64 ExternalBytesReceived = 8;
57
58 optional string FinalUrl = 9;
59
60 optional int64 ApiCpuMilliseconds = 10 [default=0];
61 optional int64 ApiBytesSent = 11 [default=0];
62 optional int64 ApiBytesReceived = 12 [default=0];
63 }
0 // Code generated by protoc-gen-go. DO NOT EDIT.
1 // source: google.golang.org/appengine/internal/user/user_service.proto
2
3 package user
4
5 import proto "github.com/golang/protobuf/proto"
6 import fmt "fmt"
7 import math "math"
8
9 // Reference imports to suppress errors if they are not otherwise used.
10 var _ = proto.Marshal
11 var _ = fmt.Errorf
12 var _ = math.Inf
13
14 // This is a compile-time assertion to ensure that this generated file
15 // is compatible with the proto package it is being compiled against.
16 // A compilation error at this line likely means your copy of the
17 // proto package needs to be updated.
18 const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
19
20 type UserServiceError_ErrorCode int32
21
22 const (
23 UserServiceError_OK UserServiceError_ErrorCode = 0
24 UserServiceError_REDIRECT_URL_TOO_LONG UserServiceError_ErrorCode = 1
25 UserServiceError_NOT_ALLOWED UserServiceError_ErrorCode = 2
26 UserServiceError_OAUTH_INVALID_TOKEN UserServiceError_ErrorCode = 3
27 UserServiceError_OAUTH_INVALID_REQUEST UserServiceError_ErrorCode = 4
28 UserServiceError_OAUTH_ERROR UserServiceError_ErrorCode = 5
29 )
30
31 var UserServiceError_ErrorCode_name = map[int32]string{
32 0: "OK",
33 1: "REDIRECT_URL_TOO_LONG",
34 2: "NOT_ALLOWED",
35 3: "OAUTH_INVALID_TOKEN",
36 4: "OAUTH_INVALID_REQUEST",
37 5: "OAUTH_ERROR",
38 }
39 var UserServiceError_ErrorCode_value = map[string]int32{
40 "OK": 0,
41 "REDIRECT_URL_TOO_LONG": 1,
42 "NOT_ALLOWED": 2,
43 "OAUTH_INVALID_TOKEN": 3,
44 "OAUTH_INVALID_REQUEST": 4,
45 "OAUTH_ERROR": 5,
46 }
47
48 func (x UserServiceError_ErrorCode) Enum() *UserServiceError_ErrorCode {
49 p := new(UserServiceError_ErrorCode)
50 *p = x
51 return p
52 }
53 func (x UserServiceError_ErrorCode) String() string {
54 return proto.EnumName(UserServiceError_ErrorCode_name, int32(x))
55 }
56 func (x *UserServiceError_ErrorCode) UnmarshalJSON(data []byte) error {
57 value, err := proto.UnmarshalJSONEnum(UserServiceError_ErrorCode_value, data, "UserServiceError_ErrorCode")
58 if err != nil {
59 return err
60 }
61 *x = UserServiceError_ErrorCode(value)
62 return nil
63 }
64 func (UserServiceError_ErrorCode) EnumDescriptor() ([]byte, []int) {
65 return fileDescriptor_user_service_faa685423dd20b0a, []int{0, 0}
66 }
67
68 type UserServiceError struct {
69 XXX_NoUnkeyedLiteral struct{} `json:"-"`
70 XXX_unrecognized []byte `json:"-"`
71 XXX_sizecache int32 `json:"-"`
72 }
73
74 func (m *UserServiceError) Reset() { *m = UserServiceError{} }
75 func (m *UserServiceError) String() string { return proto.CompactTextString(m) }
76 func (*UserServiceError) ProtoMessage() {}
77 func (*UserServiceError) Descriptor() ([]byte, []int) {
78 return fileDescriptor_user_service_faa685423dd20b0a, []int{0}
79 }
80 func (m *UserServiceError) XXX_Unmarshal(b []byte) error {
81 return xxx_messageInfo_UserServiceError.Unmarshal(m, b)
82 }
83 func (m *UserServiceError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
84 return xxx_messageInfo_UserServiceError.Marshal(b, m, deterministic)
85 }
86 func (dst *UserServiceError) XXX_Merge(src proto.Message) {
87 xxx_messageInfo_UserServiceError.Merge(dst, src)
88 }
89 func (m *UserServiceError) XXX_Size() int {
90 return xxx_messageInfo_UserServiceError.Size(m)
91 }
92 func (m *UserServiceError) XXX_DiscardUnknown() {
93 xxx_messageInfo_UserServiceError.DiscardUnknown(m)
94 }
95
96 var xxx_messageInfo_UserServiceError proto.InternalMessageInfo
97
98 type CreateLoginURLRequest struct {
99 DestinationUrl *string `protobuf:"bytes,1,req,name=destination_url,json=destinationUrl" json:"destination_url,omitempty"`
100 AuthDomain *string `protobuf:"bytes,2,opt,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"`
101 FederatedIdentity *string `protobuf:"bytes,3,opt,name=federated_identity,json=federatedIdentity,def=" json:"federated_identity,omitempty"`
102 XXX_NoUnkeyedLiteral struct{} `json:"-"`
103 XXX_unrecognized []byte `json:"-"`
104 XXX_sizecache int32 `json:"-"`
105 }
106
107 func (m *CreateLoginURLRequest) Reset() { *m = CreateLoginURLRequest{} }
108 func (m *CreateLoginURLRequest) String() string { return proto.CompactTextString(m) }
109 func (*CreateLoginURLRequest) ProtoMessage() {}
110 func (*CreateLoginURLRequest) Descriptor() ([]byte, []int) {
111 return fileDescriptor_user_service_faa685423dd20b0a, []int{1}
112 }
113 func (m *CreateLoginURLRequest) XXX_Unmarshal(b []byte) error {
114 return xxx_messageInfo_CreateLoginURLRequest.Unmarshal(m, b)
115 }
116 func (m *CreateLoginURLRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
117 return xxx_messageInfo_CreateLoginURLRequest.Marshal(b, m, deterministic)
118 }
119 func (dst *CreateLoginURLRequest) XXX_Merge(src proto.Message) {
120 xxx_messageInfo_CreateLoginURLRequest.Merge(dst, src)
121 }
122 func (m *CreateLoginURLRequest) XXX_Size() int {
123 return xxx_messageInfo_CreateLoginURLRequest.Size(m)
124 }
125 func (m *CreateLoginURLRequest) XXX_DiscardUnknown() {
126 xxx_messageInfo_CreateLoginURLRequest.DiscardUnknown(m)
127 }
128
129 var xxx_messageInfo_CreateLoginURLRequest proto.InternalMessageInfo
130
131 func (m *CreateLoginURLRequest) GetDestinationUrl() string {
132 if m != nil && m.DestinationUrl != nil {
133 return *m.DestinationUrl
134 }
135 return ""
136 }
137
138 func (m *CreateLoginURLRequest) GetAuthDomain() string {
139 if m != nil && m.AuthDomain != nil {
140 return *m.AuthDomain
141 }
142 return ""
143 }
144
145 func (m *CreateLoginURLRequest) GetFederatedIdentity() string {
146 if m != nil && m.FederatedIdentity != nil {
147 return *m.FederatedIdentity
148 }
149 return ""
150 }
151
152 type CreateLoginURLResponse struct {
153 LoginUrl *string `protobuf:"bytes,1,req,name=login_url,json=loginUrl" json:"login_url,omitempty"`
154 XXX_NoUnkeyedLiteral struct{} `json:"-"`
155 XXX_unrecognized []byte `json:"-"`
156 XXX_sizecache int32 `json:"-"`
157 }
158
159 func (m *CreateLoginURLResponse) Reset() { *m = CreateLoginURLResponse{} }
160 func (m *CreateLoginURLResponse) String() string { return proto.CompactTextString(m) }
161 func (*CreateLoginURLResponse) ProtoMessage() {}
162 func (*CreateLoginURLResponse) Descriptor() ([]byte, []int) {
163 return fileDescriptor_user_service_faa685423dd20b0a, []int{2}
164 }
165 func (m *CreateLoginURLResponse) XXX_Unmarshal(b []byte) error {
166 return xxx_messageInfo_CreateLoginURLResponse.Unmarshal(m, b)
167 }
168 func (m *CreateLoginURLResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
169 return xxx_messageInfo_CreateLoginURLResponse.Marshal(b, m, deterministic)
170 }
171 func (dst *CreateLoginURLResponse) XXX_Merge(src proto.Message) {
172 xxx_messageInfo_CreateLoginURLResponse.Merge(dst, src)
173 }
174 func (m *CreateLoginURLResponse) XXX_Size() int {
175 return xxx_messageInfo_CreateLoginURLResponse.Size(m)
176 }
177 func (m *CreateLoginURLResponse) XXX_DiscardUnknown() {
178 xxx_messageInfo_CreateLoginURLResponse.DiscardUnknown(m)
179 }
180
181 var xxx_messageInfo_CreateLoginURLResponse proto.InternalMessageInfo
182
183 func (m *CreateLoginURLResponse) GetLoginUrl() string {
184 if m != nil && m.LoginUrl != nil {
185 return *m.LoginUrl
186 }
187 return ""
188 }
189
190 type CreateLogoutURLRequest struct {
191 DestinationUrl *string `protobuf:"bytes,1,req,name=destination_url,json=destinationUrl" json:"destination_url,omitempty"`
192 AuthDomain *string `protobuf:"bytes,2,opt,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"`
193 XXX_NoUnkeyedLiteral struct{} `json:"-"`
194 XXX_unrecognized []byte `json:"-"`
195 XXX_sizecache int32 `json:"-"`
196 }
197
198 func (m *CreateLogoutURLRequest) Reset() { *m = CreateLogoutURLRequest{} }
199 func (m *CreateLogoutURLRequest) String() string { return proto.CompactTextString(m) }
200 func (*CreateLogoutURLRequest) ProtoMessage() {}
201 func (*CreateLogoutURLRequest) Descriptor() ([]byte, []int) {
202 return fileDescriptor_user_service_faa685423dd20b0a, []int{3}
203 }
204 func (m *CreateLogoutURLRequest) XXX_Unmarshal(b []byte) error {
205 return xxx_messageInfo_CreateLogoutURLRequest.Unmarshal(m, b)
206 }
207 func (m *CreateLogoutURLRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
208 return xxx_messageInfo_CreateLogoutURLRequest.Marshal(b, m, deterministic)
209 }
210 func (dst *CreateLogoutURLRequest) XXX_Merge(src proto.Message) {
211 xxx_messageInfo_CreateLogoutURLRequest.Merge(dst, src)
212 }
213 func (m *CreateLogoutURLRequest) XXX_Size() int {
214 return xxx_messageInfo_CreateLogoutURLRequest.Size(m)
215 }
216 func (m *CreateLogoutURLRequest) XXX_DiscardUnknown() {
217 xxx_messageInfo_CreateLogoutURLRequest.DiscardUnknown(m)
218 }
219
220 var xxx_messageInfo_CreateLogoutURLRequest proto.InternalMessageInfo
221
222 func (m *CreateLogoutURLRequest) GetDestinationUrl() string {
223 if m != nil && m.DestinationUrl != nil {
224 return *m.DestinationUrl
225 }
226 return ""
227 }
228
229 func (m *CreateLogoutURLRequest) GetAuthDomain() string {
230 if m != nil && m.AuthDomain != nil {
231 return *m.AuthDomain
232 }
233 return ""
234 }
235
236 type CreateLogoutURLResponse struct {
237 LogoutUrl *string `protobuf:"bytes,1,req,name=logout_url,json=logoutUrl" json:"logout_url,omitempty"`
238 XXX_NoUnkeyedLiteral struct{} `json:"-"`
239 XXX_unrecognized []byte `json:"-"`
240 XXX_sizecache int32 `json:"-"`
241 }
242
243 func (m *CreateLogoutURLResponse) Reset() { *m = CreateLogoutURLResponse{} }
244 func (m *CreateLogoutURLResponse) String() string { return proto.CompactTextString(m) }
245 func (*CreateLogoutURLResponse) ProtoMessage() {}
246 func (*CreateLogoutURLResponse) Descriptor() ([]byte, []int) {
247 return fileDescriptor_user_service_faa685423dd20b0a, []int{4}
248 }
249 func (m *CreateLogoutURLResponse) XXX_Unmarshal(b []byte) error {
250 return xxx_messageInfo_CreateLogoutURLResponse.Unmarshal(m, b)
251 }
252 func (m *CreateLogoutURLResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
253 return xxx_messageInfo_CreateLogoutURLResponse.Marshal(b, m, deterministic)
254 }
255 func (dst *CreateLogoutURLResponse) XXX_Merge(src proto.Message) {
256 xxx_messageInfo_CreateLogoutURLResponse.Merge(dst, src)
257 }
258 func (m *CreateLogoutURLResponse) XXX_Size() int {
259 return xxx_messageInfo_CreateLogoutURLResponse.Size(m)
260 }
261 func (m *CreateLogoutURLResponse) XXX_DiscardUnknown() {
262 xxx_messageInfo_CreateLogoutURLResponse.DiscardUnknown(m)
263 }
264
265 var xxx_messageInfo_CreateLogoutURLResponse proto.InternalMessageInfo
266
267 func (m *CreateLogoutURLResponse) GetLogoutUrl() string {
268 if m != nil && m.LogoutUrl != nil {
269 return *m.LogoutUrl
270 }
271 return ""
272 }
273
274 type GetOAuthUserRequest struct {
275 Scope *string `protobuf:"bytes,1,opt,name=scope" json:"scope,omitempty"`
276 Scopes []string `protobuf:"bytes,2,rep,name=scopes" json:"scopes,omitempty"`
277 XXX_NoUnkeyedLiteral struct{} `json:"-"`
278 XXX_unrecognized []byte `json:"-"`
279 XXX_sizecache int32 `json:"-"`
280 }
281
282 func (m *GetOAuthUserRequest) Reset() { *m = GetOAuthUserRequest{} }
283 func (m *GetOAuthUserRequest) String() string { return proto.CompactTextString(m) }
284 func (*GetOAuthUserRequest) ProtoMessage() {}
285 func (*GetOAuthUserRequest) Descriptor() ([]byte, []int) {
286 return fileDescriptor_user_service_faa685423dd20b0a, []int{5}
287 }
288 func (m *GetOAuthUserRequest) XXX_Unmarshal(b []byte) error {
289 return xxx_messageInfo_GetOAuthUserRequest.Unmarshal(m, b)
290 }
291 func (m *GetOAuthUserRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
292 return xxx_messageInfo_GetOAuthUserRequest.Marshal(b, m, deterministic)
293 }
294 func (dst *GetOAuthUserRequest) XXX_Merge(src proto.Message) {
295 xxx_messageInfo_GetOAuthUserRequest.Merge(dst, src)
296 }
297 func (m *GetOAuthUserRequest) XXX_Size() int {
298 return xxx_messageInfo_GetOAuthUserRequest.Size(m)
299 }
300 func (m *GetOAuthUserRequest) XXX_DiscardUnknown() {
301 xxx_messageInfo_GetOAuthUserRequest.DiscardUnknown(m)
302 }
303
304 var xxx_messageInfo_GetOAuthUserRequest proto.InternalMessageInfo
305
306 func (m *GetOAuthUserRequest) GetScope() string {
307 if m != nil && m.Scope != nil {
308 return *m.Scope
309 }
310 return ""
311 }
312
313 func (m *GetOAuthUserRequest) GetScopes() []string {
314 if m != nil {
315 return m.Scopes
316 }
317 return nil
318 }
319
320 type GetOAuthUserResponse struct {
321 Email *string `protobuf:"bytes,1,req,name=email" json:"email,omitempty"`
322 UserId *string `protobuf:"bytes,2,req,name=user_id,json=userId" json:"user_id,omitempty"`
323 AuthDomain *string `protobuf:"bytes,3,req,name=auth_domain,json=authDomain" json:"auth_domain,omitempty"`
324 UserOrganization *string `protobuf:"bytes,4,opt,name=user_organization,json=userOrganization,def=" json:"user_organization,omitempty"`
325 IsAdmin *bool `protobuf:"varint,5,opt,name=is_admin,json=isAdmin,def=0" json:"is_admin,omitempty"`
326 ClientId *string `protobuf:"bytes,6,opt,name=client_id,json=clientId,def=" json:"client_id,omitempty"`
327 Scopes []string `protobuf:"bytes,7,rep,name=scopes" json:"scopes,omitempty"`
328 XXX_NoUnkeyedLiteral struct{} `json:"-"`
329 XXX_unrecognized []byte `json:"-"`
330 XXX_sizecache int32 `json:"-"`
331 }
332
333 func (m *GetOAuthUserResponse) Reset() { *m = GetOAuthUserResponse{} }
334 func (m *GetOAuthUserResponse) String() string { return proto.CompactTextString(m) }
335 func (*GetOAuthUserResponse) ProtoMessage() {}
336 func (*GetOAuthUserResponse) Descriptor() ([]byte, []int) {
337 return fileDescriptor_user_service_faa685423dd20b0a, []int{6}
338 }
339 func (m *GetOAuthUserResponse) XXX_Unmarshal(b []byte) error {
340 return xxx_messageInfo_GetOAuthUserResponse.Unmarshal(m, b)
341 }
342 func (m *GetOAuthUserResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
343 return xxx_messageInfo_GetOAuthUserResponse.Marshal(b, m, deterministic)
344 }
345 func (dst *GetOAuthUserResponse) XXX_Merge(src proto.Message) {
346 xxx_messageInfo_GetOAuthUserResponse.Merge(dst, src)
347 }
348 func (m *GetOAuthUserResponse) XXX_Size() int {
349 return xxx_messageInfo_GetOAuthUserResponse.Size(m)
350 }
351 func (m *GetOAuthUserResponse) XXX_DiscardUnknown() {
352 xxx_messageInfo_GetOAuthUserResponse.DiscardUnknown(m)
353 }
354
355 var xxx_messageInfo_GetOAuthUserResponse proto.InternalMessageInfo
356
357 const Default_GetOAuthUserResponse_IsAdmin bool = false
358
359 func (m *GetOAuthUserResponse) GetEmail() string {
360 if m != nil && m.Email != nil {
361 return *m.Email
362 }
363 return ""
364 }
365
366 func (m *GetOAuthUserResponse) GetUserId() string {
367 if m != nil && m.UserId != nil {
368 return *m.UserId
369 }
370 return ""
371 }
372
373 func (m *GetOAuthUserResponse) GetAuthDomain() string {
374 if m != nil && m.AuthDomain != nil {
375 return *m.AuthDomain
376 }
377 return ""
378 }
379
380 func (m *GetOAuthUserResponse) GetUserOrganization() string {
381 if m != nil && m.UserOrganization != nil {
382 return *m.UserOrganization
383 }
384 return ""
385 }
386
387 func (m *GetOAuthUserResponse) GetIsAdmin() bool {
388 if m != nil && m.IsAdmin != nil {
389 return *m.IsAdmin
390 }
391 return Default_GetOAuthUserResponse_IsAdmin
392 }
393
394 func (m *GetOAuthUserResponse) GetClientId() string {
395 if m != nil && m.ClientId != nil {
396 return *m.ClientId
397 }
398 return ""
399 }
400
401 func (m *GetOAuthUserResponse) GetScopes() []string {
402 if m != nil {
403 return m.Scopes
404 }
405 return nil
406 }
407
408 type CheckOAuthSignatureRequest struct {
409 XXX_NoUnkeyedLiteral struct{} `json:"-"`
410 XXX_unrecognized []byte `json:"-"`
411 XXX_sizecache int32 `json:"-"`
412 }
413
414 func (m *CheckOAuthSignatureRequest) Reset() { *m = CheckOAuthSignatureRequest{} }
415 func (m *CheckOAuthSignatureRequest) String() string { return proto.CompactTextString(m) }
416 func (*CheckOAuthSignatureRequest) ProtoMessage() {}
417 func (*CheckOAuthSignatureRequest) Descriptor() ([]byte, []int) {
418 return fileDescriptor_user_service_faa685423dd20b0a, []int{7}
419 }
420 func (m *CheckOAuthSignatureRequest) XXX_Unmarshal(b []byte) error {
421 return xxx_messageInfo_CheckOAuthSignatureRequest.Unmarshal(m, b)
422 }
423 func (m *CheckOAuthSignatureRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
424 return xxx_messageInfo_CheckOAuthSignatureRequest.Marshal(b, m, deterministic)
425 }
426 func (dst *CheckOAuthSignatureRequest) XXX_Merge(src proto.Message) {
427 xxx_messageInfo_CheckOAuthSignatureRequest.Merge(dst, src)
428 }
429 func (m *CheckOAuthSignatureRequest) XXX_Size() int {
430 return xxx_messageInfo_CheckOAuthSignatureRequest.Size(m)
431 }
432 func (m *CheckOAuthSignatureRequest) XXX_DiscardUnknown() {
433 xxx_messageInfo_CheckOAuthSignatureRequest.DiscardUnknown(m)
434 }
435
436 var xxx_messageInfo_CheckOAuthSignatureRequest proto.InternalMessageInfo
437
438 type CheckOAuthSignatureResponse struct {
439 OauthConsumerKey *string `protobuf:"bytes,1,req,name=oauth_consumer_key,json=oauthConsumerKey" json:"oauth_consumer_key,omitempty"`
440 XXX_NoUnkeyedLiteral struct{} `json:"-"`
441 XXX_unrecognized []byte `json:"-"`
442 XXX_sizecache int32 `json:"-"`
443 }
444
445 func (m *CheckOAuthSignatureResponse) Reset() { *m = CheckOAuthSignatureResponse{} }
446 func (m *CheckOAuthSignatureResponse) String() string { return proto.CompactTextString(m) }
447 func (*CheckOAuthSignatureResponse) ProtoMessage() {}
448 func (*CheckOAuthSignatureResponse) Descriptor() ([]byte, []int) {
449 return fileDescriptor_user_service_faa685423dd20b0a, []int{8}
450 }
451 func (m *CheckOAuthSignatureResponse) XXX_Unmarshal(b []byte) error {
452 return xxx_messageInfo_CheckOAuthSignatureResponse.Unmarshal(m, b)
453 }
454 func (m *CheckOAuthSignatureResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
455 return xxx_messageInfo_CheckOAuthSignatureResponse.Marshal(b, m, deterministic)
456 }
457 func (dst *CheckOAuthSignatureResponse) XXX_Merge(src proto.Message) {
458 xxx_messageInfo_CheckOAuthSignatureResponse.Merge(dst, src)
459 }
460 func (m *CheckOAuthSignatureResponse) XXX_Size() int {
461 return xxx_messageInfo_CheckOAuthSignatureResponse.Size(m)
462 }
463 func (m *CheckOAuthSignatureResponse) XXX_DiscardUnknown() {
464 xxx_messageInfo_CheckOAuthSignatureResponse.DiscardUnknown(m)
465 }
466
467 var xxx_messageInfo_CheckOAuthSignatureResponse proto.InternalMessageInfo
468
469 func (m *CheckOAuthSignatureResponse) GetOauthConsumerKey() string {
470 if m != nil && m.OauthConsumerKey != nil {
471 return *m.OauthConsumerKey
472 }
473 return ""
474 }
475
476 func init() {
477 proto.RegisterType((*UserServiceError)(nil), "appengine.UserServiceError")
478 proto.RegisterType((*CreateLoginURLRequest)(nil), "appengine.CreateLoginURLRequest")
479 proto.RegisterType((*CreateLoginURLResponse)(nil), "appengine.CreateLoginURLResponse")
480 proto.RegisterType((*CreateLogoutURLRequest)(nil), "appengine.CreateLogoutURLRequest")
481 proto.RegisterType((*CreateLogoutURLResponse)(nil), "appengine.CreateLogoutURLResponse")
482 proto.RegisterType((*GetOAuthUserRequest)(nil), "appengine.GetOAuthUserRequest")
483 proto.RegisterType((*GetOAuthUserResponse)(nil), "appengine.GetOAuthUserResponse")
484 proto.RegisterType((*CheckOAuthSignatureRequest)(nil), "appengine.CheckOAuthSignatureRequest")
485 proto.RegisterType((*CheckOAuthSignatureResponse)(nil), "appengine.CheckOAuthSignatureResponse")
486 }
487
488 func init() {
489 proto.RegisterFile("google.golang.org/appengine/v2/internal/user/user_service.proto", fileDescriptor_user_service_faa685423dd20b0a)
490 }
491
492 var fileDescriptor_user_service_faa685423dd20b0a = []byte{
493 // 573 bytes of a gzipped FileDescriptorProto
494 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x52, 0x4d, 0x6f, 0xdb, 0x38,
495 0x10, 0x8d, 0xec, 0xd8, 0xb1, 0x26, 0xc0, 0x46, 0x61, 0xbe, 0xb4, 0x9b, 0x0d, 0xd6, 0xd0, 0x65,
496 0x7d, 0x68, 0xe3, 0x53, 0x81, 0x22, 0xe8, 0xc5, 0xb5, 0x85, 0xd4, 0xb0, 0x60, 0xa1, 0x8c, 0xd5,
497 0x02, 0xbd, 0x08, 0xac, 0x35, 0x51, 0x88, 0xc8, 0xa4, 0x4b, 0x52, 0x05, 0xd2, 0x73, 0x7f, 0x41,
498 0x6f, 0xfd, 0x93, 0xfd, 0x0d, 0x85, 0x68, 0x25, 0x50, 0xd2, 0x5e, 0x7b, 0x11, 0x34, 0xef, 0x0d,
499 0xdf, 0xbc, 0x37, 0x24, 0xbc, 0xca, 0xa5, 0xcc, 0x0b, 0x3c, 0xcf, 0x65, 0xc1, 0x44, 0x7e, 0x2e,
500 0x55, 0x3e, 0x64, 0xeb, 0x35, 0x8a, 0x9c, 0x0b, 0x1c, 0x72, 0x61, 0x50, 0x09, 0x56, 0x0c, 0x4b,
501 0x8d, 0xca, 0x7e, 0x52, 0x8d, 0xea, 0x33, 0x5f, 0xe2, 0xf9, 0x5a, 0x49, 0x23, 0x89, 0xfb, 0xd0,
502 0x1b, 0x7c, 0x77, 0xc0, 0x4b, 0x34, 0xaa, 0xab, 0x4d, 0x43, 0xa8, 0x94, 0x54, 0xc1, 0x57, 0x07,
503 0x5c, 0xfb, 0x37, 0x96, 0x19, 0x92, 0x2e, 0xb4, 0xe2, 0x99, 0xb7, 0x45, 0xfe, 0x86, 0x23, 0x1a,
504 0x4e, 0xa6, 0x34, 0x1c, 0x2f, 0xd2, 0x84, 0x46, 0xe9, 0x22, 0x8e, 0xd3, 0x28, 0x9e, 0x5f, 0x7a,
505 0x0e, 0xd9, 0x83, 0xdd, 0x79, 0xbc, 0x48, 0x47, 0x51, 0x14, 0xbf, 0x0f, 0x27, 0x5e, 0x8b, 0x9c,
506 0xc0, 0x41, 0x3c, 0x4a, 0x16, 0x6f, 0xd2, 0xe9, 0xfc, 0xdd, 0x28, 0x9a, 0x4e, 0xd2, 0x45, 0x3c,
507 0x0b, 0xe7, 0x5e, 0xbb, 0x12, 0x79, 0x4c, 0xd0, 0xf0, 0x6d, 0x12, 0x5e, 0x2d, 0xbc, 0xed, 0x4a,
508 0x64, 0x43, 0x85, 0x94, 0xc6, 0xd4, 0xeb, 0x04, 0xdf, 0x1c, 0x38, 0x1a, 0x2b, 0x64, 0x06, 0x23,
509 0x99, 0x73, 0x91, 0xd0, 0x88, 0xe2, 0xa7, 0x12, 0xb5, 0x21, 0xff, 0xc3, 0x5e, 0x86, 0xda, 0x70,
510 0xc1, 0x0c, 0x97, 0x22, 0x2d, 0x55, 0xe1, 0x3b, 0xfd, 0xd6, 0xc0, 0xa5, 0x7f, 0x35, 0xe0, 0x44,
511 0x15, 0xe4, 0x3f, 0xd8, 0x65, 0xa5, 0xb9, 0x49, 0x33, 0xb9, 0x62, 0x5c, 0xf8, 0xad, 0xbe, 0x33,
512 0x70, 0x29, 0x54, 0xd0, 0xc4, 0x22, 0x64, 0x08, 0xe4, 0x1a, 0x33, 0x54, 0xcc, 0x60, 0x96, 0xf2,
513 0x0c, 0x85, 0xe1, 0xe6, 0xce, 0x6f, 0x57, 0x7d, 0x17, 0x5b, 0x74, 0xff, 0x81, 0x9b, 0xd6, 0x54,
514 0xf0, 0x02, 0x8e, 0x9f, 0x7a, 0xd2, 0x6b, 0x29, 0x34, 0x92, 0x53, 0x70, 0x8b, 0x0a, 0x6b, 0xd8,
515 0xe9, 0x59, 0x20, 0x51, 0x45, 0xf0, 0xb1, 0x71, 0x4c, 0x96, 0xe6, 0x4f, 0x64, 0x09, 0x5e, 0xc2,
516 0xc9, 0x2f, 0x33, 0x6a, 0x6f, 0x67, 0x00, 0x85, 0x05, 0x1b, 0xfa, 0xee, 0x06, 0xa9, 0xdc, 0x8d,
517 0xe1, 0xe0, 0x12, 0x4d, 0x3c, 0x2a, 0xcd, 0x4d, 0xf5, 0x18, 0xee, 0xad, 0x1d, 0x42, 0x47, 0x2f,
518 0xe5, 0x1a, 0x7d, 0xc7, 0xce, 0xda, 0x14, 0xe4, 0x18, 0xba, 0xf6, 0x47, 0xfb, 0xad, 0x7e, 0x7b,
519 0xe0, 0xd2, 0xba, 0x0a, 0x7e, 0x38, 0x70, 0xf8, 0x58, 0xa5, 0x1e, 0x7e, 0x08, 0x1d, 0x5c, 0x31,
520 0x7e, 0x3f, 0x77, 0x53, 0x90, 0x13, 0xd8, 0xb1, 0x4f, 0x93, 0x67, 0x7e, 0xcb, 0xe2, 0xdd, 0xaa,
521 0x9c, 0x66, 0x4f, 0x73, 0xb6, 0x2d, 0xd9, 0xbc, 0xb3, 0xe7, 0xb0, 0x6f, 0x4f, 0x4a, 0x95, 0x33,
522 0xc1, 0xbf, 0xd8, 0x05, 0xf9, 0xdb, 0xf5, 0x95, 0x79, 0x15, 0x15, 0x37, 0x18, 0xd2, 0x87, 0x1e,
523 0xd7, 0x29, 0xcb, 0x56, 0x5c, 0xf8, 0x9d, 0xbe, 0x33, 0xe8, 0x5d, 0x74, 0xae, 0x59, 0xa1, 0x91,
524 0xee, 0x70, 0x3d, 0xaa, 0x50, 0x72, 0x06, 0xee, 0xb2, 0xe0, 0x28, 0x4c, 0x65, 0xa6, 0x5b, 0x0b,
525 0xf5, 0x36, 0xd0, 0x34, 0x6b, 0x04, 0xde, 0x79, 0x14, 0xf8, 0x5f, 0xf8, 0x67, 0x7c, 0x83, 0xcb,
526 0x5b, 0x9b, 0xf8, 0x8a, 0xe7, 0x82, 0x99, 0x52, 0x61, 0xbd, 0xbc, 0x60, 0x06, 0xa7, 0xbf, 0x65,
527 0xeb, 0xa5, 0x3c, 0x03, 0x22, 0x6d, 0xcc, 0xa5, 0x14, 0xba, 0x5c, 0xa1, 0x4a, 0x6f, 0xf1, 0xae,
528 0xde, 0x90, 0x67, 0x99, 0x71, 0x4d, 0xcc, 0xf0, 0xee, 0x75, 0xf7, 0xc3, 0x76, 0x95, 0xeb, 0x67,
529 0x00, 0x00, 0x00, 0xff, 0xff, 0x58, 0x04, 0x53, 0xcc, 0xf8, 0x03, 0x00, 0x00,
530 }
0 syntax = "proto2";
1 option go_package = "user";
2
3 package appengine;
4
5 message UserServiceError {
6 enum ErrorCode {
7 OK = 0;
8 REDIRECT_URL_TOO_LONG = 1;
9 NOT_ALLOWED = 2;
10 OAUTH_INVALID_TOKEN = 3;
11 OAUTH_INVALID_REQUEST = 4;
12 OAUTH_ERROR = 5;
13 }
14 }
15
16 message CreateLoginURLRequest {
17 required string destination_url = 1;
18 optional string auth_domain = 2;
19 optional string federated_identity = 3 [default = ""];
20 }
21
22 message CreateLoginURLResponse {
23 required string login_url = 1;
24 }
25
26 message CreateLogoutURLRequest {
27 required string destination_url = 1;
28 optional string auth_domain = 2;
29 }
30
31 message CreateLogoutURLResponse {
32 required string logout_url = 1;
33 }
34
35 message GetOAuthUserRequest {
36 optional string scope = 1;
37
38 repeated string scopes = 2;
39 }
40
41 message GetOAuthUserResponse {
42 required string email = 1;
43 required string user_id = 2;
44 required string auth_domain = 3;
45 optional string user_organization = 4 [default = ""];
46 optional bool is_admin = 5 [default = false];
47 optional string client_id = 6 [default = ""];
48
49 repeated string scopes = 7;
50 }
51
52 message CheckOAuthSignatureRequest {
53 }
54
55 message CheckOAuthSignatureResponse {
56 required string oauth_consumer_key = 1;
57 }
0 // Copyright 2015 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package log
5
6 // This file implements the logging API.
7
8 import (
9 "context"
10
11 "google.golang.org/appengine/v2/internal"
12 )
13
14 // Debugf formats its arguments according to the format, analogous to fmt.Printf,
15 // and records the text as a log message at Debug level. The message will be associated
16 // with the request linked with the provided context.
17 func Debugf(ctx context.Context, format string, args ...interface{}) {
18 internal.Logf(ctx, 0, format, args...)
19 }
20
21 // Infof is like Debugf, but at Info level.
22 func Infof(ctx context.Context, format string, args ...interface{}) {
23 internal.Logf(ctx, 1, format, args...)
24 }
25
26 // Warningf is like Debugf, but at Warning level.
27 func Warningf(ctx context.Context, format string, args ...interface{}) {
28 internal.Logf(ctx, 2, format, args...)
29 }
30
31 // Errorf is like Debugf, but at Error level.
32 func Errorf(ctx context.Context, format string, args ...interface{}) {
33 internal.Logf(ctx, 3, format, args...)
34 }
35
36 // Criticalf is like Debugf, but at Critical level.
37 func Criticalf(ctx context.Context, format string, args ...interface{}) {
38 internal.Logf(ctx, 4, format, args...)
39 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 /*
5 Package mail provides the means of sending email from an
6 App Engine application.
7
8 Example:
9
10 msg := &mail.Message{
11 Sender: "romeo@montague.com",
12 To: []string{"Juliet <juliet@capulet.org>"},
13 Subject: "See you tonight",
14 Body: "Don't forget our plans. Hark, 'til later.",
15 }
16 if err := mail.Send(c, msg); err != nil {
17 log.Errorf(c, "Alas, my user, the email failed to sendeth: %v", err)
18 }
19 */
20 package mail // import "google.golang.org/appengine/v2/mail"
21
22 import (
23 "context"
24 "net/mail"
25
26 "github.com/golang/protobuf/proto"
27
28 "google.golang.org/appengine/v2/internal"
29 bpb "google.golang.org/appengine/v2/internal/base"
30 pb "google.golang.org/appengine/v2/internal/mail"
31 )
32
33 // A Message represents an email message.
34 // Addresses may be of any form permitted by RFC 822.
35 type Message struct {
36 // Sender must be set, and must be either an application admin
37 // or the currently signed-in user.
38 Sender string
39 ReplyTo string // may be empty
40
41 // At least one of these slices must have a non-zero length,
42 // except when calling SendToAdmins.
43 To, Cc, Bcc []string
44
45 Subject string
46
47 // At least one of Body or HTMLBody must be non-empty.
48 Body string
49 HTMLBody string
50
51 Attachments []Attachment
52
53 // Extra mail headers.
54 // See https://cloud.google.com/appengine/docs/standard/go/mail/
55 // for permissible headers.
56 Headers mail.Header
57 }
58
59 // An Attachment represents an email attachment.
60 type Attachment struct {
61 // Name must be set to a valid file name.
62 Name string
63 Data []byte
64 ContentID string
65 }
66
67 // Send sends an email message.
68 func Send(c context.Context, msg *Message) error {
69 return send(c, "Send", msg)
70 }
71
72 // SendToAdmins sends an email message to the application's administrators.
73 func SendToAdmins(c context.Context, msg *Message) error {
74 return send(c, "SendToAdmins", msg)
75 }
76
77 func send(c context.Context, method string, msg *Message) error {
78 req := &pb.MailMessage{
79 Sender: &msg.Sender,
80 To: msg.To,
81 Cc: msg.Cc,
82 Bcc: msg.Bcc,
83 Subject: &msg.Subject,
84 }
85 if msg.ReplyTo != "" {
86 req.ReplyTo = &msg.ReplyTo
87 }
88 if msg.Body != "" {
89 req.TextBody = &msg.Body
90 }
91 if msg.HTMLBody != "" {
92 req.HtmlBody = &msg.HTMLBody
93 }
94 if len(msg.Attachments) > 0 {
95 req.Attachment = make([]*pb.MailAttachment, len(msg.Attachments))
96 for i, att := range msg.Attachments {
97 req.Attachment[i] = &pb.MailAttachment{
98 FileName: proto.String(att.Name),
99 Data: att.Data,
100 }
101 if att.ContentID != "" {
102 req.Attachment[i].ContentID = proto.String(att.ContentID)
103 }
104 }
105 }
106 for key, vs := range msg.Headers {
107 for _, v := range vs {
108 req.Header = append(req.Header, &pb.MailHeader{
109 Name: proto.String(key),
110 Value: proto.String(v),
111 })
112 }
113 }
114 res := &bpb.VoidProto{}
115 if err := internal.Call(c, "mail", method, req, res); err != nil {
116 return err
117 }
118 return nil
119 }
120
121 func init() {
122 internal.RegisterErrorCodeMap("mail", pb.MailServiceError_ErrorCode_name)
123 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package mail
5
6 import (
7 "testing"
8
9 "github.com/golang/protobuf/proto"
10
11 "google.golang.org/appengine/v2/internal/aetesting"
12 basepb "google.golang.org/appengine/v2/internal/base"
13 pb "google.golang.org/appengine/v2/internal/mail"
14 )
15
16 func TestMessageConstruction(t *testing.T) {
17 var got *pb.MailMessage
18 c := aetesting.FakeSingleContext(t, "mail", "Send", func(in *pb.MailMessage, out *basepb.VoidProto) error {
19 got = in
20 return nil
21 })
22
23 msg := &Message{
24 Sender: "dsymonds@example.com",
25 To: []string{"nigeltao@example.com"},
26 Body: "Hey, lunch time?",
27 Attachments: []Attachment{
28 // Regression test for a prod bug. The address of a range variable was used when
29 // constructing the outgoing proto, so multiple attachments used the same name.
30 {
31 Name: "att1.txt",
32 Data: []byte("data1"),
33 ContentID: "<att1>",
34 },
35 {
36 Name: "att2.txt",
37 Data: []byte("data2"),
38 },
39 },
40 }
41 if err := Send(c, msg); err != nil {
42 t.Fatalf("Send: %v", err)
43 }
44 want := &pb.MailMessage{
45 Sender: proto.String("dsymonds@example.com"),
46 To: []string{"nigeltao@example.com"},
47 Subject: proto.String(""),
48 TextBody: proto.String("Hey, lunch time?"),
49 Attachment: []*pb.MailAttachment{
50 {
51 FileName: proto.String("att1.txt"),
52 Data: []byte("data1"),
53 ContentID: proto.String("<att1>"),
54 },
55 {
56 FileName: proto.String("att2.txt"),
57 Data: []byte("data2"),
58 },
59 },
60 }
61 if !proto.Equal(got, want) {
62 t.Errorf("Bad proto for %+v\n got %v\nwant %v", msg, got, want)
63 }
64 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package memcache provides a client for App Engine's distributed in-memory
5 // key-value store for small chunks of arbitrary data.
6 //
7 // The fundamental operations get and set items, keyed by a string.
8 //
9 // item0, err := memcache.Get(c, "key")
10 // if err != nil && err != memcache.ErrCacheMiss {
11 // return err
12 // }
13 // if err == nil {
14 // fmt.Fprintf(w, "memcache hit: Key=%q Val=[% x]\n", item0.Key, item0.Value)
15 // } else {
16 // fmt.Fprintf(w, "memcache miss\n")
17 // }
18 //
19 // and
20 //
21 // item1 := &memcache.Item{
22 // Key: "foo",
23 // Value: []byte("bar"),
24 // }
25 // if err := memcache.Set(c, item1); err != nil {
26 // return err
27 // }
28 package memcache // import "google.golang.org/appengine/v2/memcache"
29
30 import (
31 "bytes"
32 "context"
33 "encoding/gob"
34 "encoding/json"
35 "errors"
36 "time"
37
38 "github.com/golang/protobuf/proto"
39
40 "google.golang.org/appengine/v2"
41 "google.golang.org/appengine/v2/internal"
42 pb "google.golang.org/appengine/v2/internal/memcache"
43 )
44
45 var (
46 // ErrCacheMiss means that an operation failed
47 // because the item wasn't present.
48 ErrCacheMiss = errors.New("memcache: cache miss")
49 // ErrCASConflict means that a CompareAndSwap call failed due to the
50 // cached value being modified between the Get and the CompareAndSwap.
51 // If the cached value was simply evicted rather than replaced,
52 // ErrNotStored will be returned instead.
53 ErrCASConflict = errors.New("memcache: compare-and-swap conflict")
54 // ErrNoStats means that no statistics were available.
55 ErrNoStats = errors.New("memcache: no statistics available")
56 // ErrNotStored means that a conditional write operation (i.e. Add or
57 // CompareAndSwap) failed because the condition was not satisfied.
58 ErrNotStored = errors.New("memcache: item not stored")
59 // ErrServerError means that a server error occurred.
60 ErrServerError = errors.New("memcache: server error")
61 )
62
63 // Item is the unit of memcache gets and sets.
64 type Item struct {
65 // Key is the Item's key (250 bytes maximum).
66 Key string
67 // Value is the Item's value.
68 Value []byte
69 // Object is the Item's value for use with a Codec.
70 Object interface{}
71 // Flags are server-opaque flags whose semantics are entirely up to the
72 // App Engine app.
73 Flags uint32
74 // Expiration is the maximum duration that the item will stay
75 // in the cache.
76 // The zero value means the Item has no expiration time.
77 // Subsecond precision is ignored.
78 // This is not set when getting items.
79 Expiration time.Duration
80 // casID is a client-opaque value used for compare-and-swap operations.
81 // Zero means that compare-and-swap is not used.
82 casID uint64
83 }
84
85 const (
86 secondsIn30Years = 60 * 60 * 24 * 365 * 30 // from memcache server code
87 thirtyYears = time.Duration(secondsIn30Years) * time.Second
88 )
89
90 // protoToItem converts a protocol buffer item to a Go struct.
91 func protoToItem(p *pb.MemcacheGetResponse_Item) *Item {
92 return &Item{
93 Key: string(p.Key),
94 Value: p.Value,
95 Flags: p.GetFlags(),
96 casID: p.GetCasId(),
97 }
98 }
99
100 // If err is an appengine.MultiError, return its first element. Otherwise, return err.
101 func singleError(err error) error {
102 if me, ok := err.(appengine.MultiError); ok {
103 return me[0]
104 }
105 return err
106 }
107
108 // Get gets the item for the given key. ErrCacheMiss is returned for a memcache
109 // cache miss. The key must be at most 250 bytes in length.
110 func Get(c context.Context, key string) (*Item, error) {
111 m, err := GetMulti(c, []string{key})
112 if err != nil {
113 return nil, err
114 }
115 if _, ok := m[key]; !ok {
116 return nil, ErrCacheMiss
117 }
118 return m[key], nil
119 }
120
121 // GetMulti is a batch version of Get. The returned map from keys to items may
122 // have fewer elements than the input slice, due to memcache cache misses.
123 // Each key must be at most 250 bytes in length.
124 func GetMulti(c context.Context, key []string) (map[string]*Item, error) {
125 if len(key) == 0 {
126 return nil, nil
127 }
128 keyAsBytes := make([][]byte, len(key))
129 for i, k := range key {
130 keyAsBytes[i] = []byte(k)
131 }
132 req := &pb.MemcacheGetRequest{
133 Key: keyAsBytes,
134 ForCas: proto.Bool(true),
135 }
136 res := &pb.MemcacheGetResponse{}
137 if err := internal.Call(c, "memcache", "Get", req, res); err != nil {
138 return nil, err
139 }
140 m := make(map[string]*Item, len(res.Item))
141 for _, p := range res.Item {
142 t := protoToItem(p)
143 m[t.Key] = t
144 }
145 return m, nil
146 }
147
148 // Delete deletes the item for the given key.
149 // ErrCacheMiss is returned if the specified item can not be found.
150 // The key must be at most 250 bytes in length.
151 func Delete(c context.Context, key string) error {
152 return singleError(DeleteMulti(c, []string{key}))
153 }
154
155 // DeleteMulti is a batch version of Delete.
156 // If any keys cannot be found, an appengine.MultiError is returned.
157 // Each key must be at most 250 bytes in length.
158 func DeleteMulti(c context.Context, key []string) error {
159 if len(key) == 0 {
160 return nil
161 }
162 req := &pb.MemcacheDeleteRequest{
163 Item: make([]*pb.MemcacheDeleteRequest_Item, len(key)),
164 }
165 for i, k := range key {
166 req.Item[i] = &pb.MemcacheDeleteRequest_Item{Key: []byte(k)}
167 }
168 res := &pb.MemcacheDeleteResponse{}
169 if err := internal.Call(c, "memcache", "Delete", req, res); err != nil {
170 return err
171 }
172 if len(res.DeleteStatus) != len(key) {
173 return ErrServerError
174 }
175 me, any := make(appengine.MultiError, len(key)), false
176 for i, s := range res.DeleteStatus {
177 switch s {
178 case pb.MemcacheDeleteResponse_DELETED:
179 // OK
180 case pb.MemcacheDeleteResponse_NOT_FOUND:
181 me[i] = ErrCacheMiss
182 any = true
183 default:
184 me[i] = ErrServerError
185 any = true
186 }
187 }
188 if any {
189 return me
190 }
191 return nil
192 }
193
194 // Increment atomically increments the decimal value in the given key
195 // by delta and returns the new value. The value must fit in a uint64.
196 // Overflow wraps around, and underflow is capped to zero. The
197 // provided delta may be negative. If the key doesn't exist in
198 // memcache, the provided initial value is used to atomically
199 // populate it before the delta is applied.
200 // The key must be at most 250 bytes in length.
201 func Increment(c context.Context, key string, delta int64, initialValue uint64) (newValue uint64, err error) {
202 return incr(c, key, delta, &initialValue)
203 }
204
205 // IncrementExisting works like Increment but assumes that the key
206 // already exists in memcache and doesn't take an initial value.
207 // IncrementExisting can save work if calculating the initial value is
208 // expensive.
209 // An error is returned if the specified item can not be found.
210 func IncrementExisting(c context.Context, key string, delta int64) (newValue uint64, err error) {
211 return incr(c, key, delta, nil)
212 }
213
214 func incr(c context.Context, key string, delta int64, initialValue *uint64) (newValue uint64, err error) {
215 req := &pb.MemcacheIncrementRequest{
216 Key: []byte(key),
217 InitialValue: initialValue,
218 }
219 if delta >= 0 {
220 req.Delta = proto.Uint64(uint64(delta))
221 } else {
222 req.Delta = proto.Uint64(uint64(-delta))
223 req.Direction = pb.MemcacheIncrementRequest_DECREMENT.Enum()
224 }
225 res := &pb.MemcacheIncrementResponse{}
226 err = internal.Call(c, "memcache", "Increment", req, res)
227 if err != nil {
228 return
229 }
230 if res.NewValue == nil {
231 return 0, ErrCacheMiss
232 }
233 return *res.NewValue, nil
234 }
235
236 // set sets the given items using the given conflict resolution policy.
237 // appengine.MultiError may be returned.
238 func set(c context.Context, item []*Item, value [][]byte, policy pb.MemcacheSetRequest_SetPolicy) error {
239 if len(item) == 0 {
240 return nil
241 }
242 req := &pb.MemcacheSetRequest{
243 Item: make([]*pb.MemcacheSetRequest_Item, len(item)),
244 }
245 for i, t := range item {
246 p := &pb.MemcacheSetRequest_Item{
247 Key: []byte(t.Key),
248 }
249 if value == nil {
250 p.Value = t.Value
251 } else {
252 p.Value = value[i]
253 }
254 if t.Flags != 0 {
255 p.Flags = proto.Uint32(t.Flags)
256 }
257 if t.Expiration != 0 {
258 // In the .proto file, MemcacheSetRequest_Item uses a fixed32 (i.e. unsigned)
259 // for expiration time, while MemcacheGetRequest_Item uses int32 (i.e. signed).
260 // Throughout this .go file, we use int32.
261 // Also, in the proto, the expiration value is either a duration (in seconds)
262 // or an absolute Unix timestamp (in seconds), depending on whether the
263 // value is less than or greater than or equal to 30 years, respectively.
264 if t.Expiration < time.Second {
265 // Because an Expiration of 0 means no expiration, we take
266 // care here to translate an item with an expiration
267 // Duration between 0-1 seconds as immediately expiring
268 // (saying it expired a few seconds ago), rather than
269 // rounding it down to 0 and making it live forever.
270 p.ExpirationTime = proto.Uint32(uint32(time.Now().Unix()) - 5)
271 } else if t.Expiration >= thirtyYears {
272 p.ExpirationTime = proto.Uint32(uint32(time.Now().Unix()) + uint32(t.Expiration/time.Second))
273 } else {
274 p.ExpirationTime = proto.Uint32(uint32(t.Expiration / time.Second))
275 }
276 }
277 if t.casID != 0 {
278 p.CasId = proto.Uint64(t.casID)
279 p.ForCas = proto.Bool(true)
280 }
281 p.SetPolicy = policy.Enum()
282 req.Item[i] = p
283 }
284 res := &pb.MemcacheSetResponse{}
285 if err := internal.Call(c, "memcache", "Set", req, res); err != nil {
286 return err
287 }
288 if len(res.SetStatus) != len(item) {
289 return ErrServerError
290 }
291 me, any := make(appengine.MultiError, len(item)), false
292 for i, st := range res.SetStatus {
293 var err error
294 switch st {
295 case pb.MemcacheSetResponse_STORED:
296 // OK
297 case pb.MemcacheSetResponse_NOT_STORED:
298 err = ErrNotStored
299 case pb.MemcacheSetResponse_EXISTS:
300 err = ErrCASConflict
301 default:
302 err = ErrServerError
303 }
304 if err != nil {
305 me[i] = err
306 any = true
307 }
308 }
309 if any {
310 return me
311 }
312 return nil
313 }
314
315 // Set writes the given item, unconditionally.
316 func Set(c context.Context, item *Item) error {
317 return singleError(set(c, []*Item{item}, nil, pb.MemcacheSetRequest_SET))
318 }
319
320 // SetMulti is a batch version of Set.
321 // appengine.MultiError may be returned.
322 func SetMulti(c context.Context, item []*Item) error {
323 return set(c, item, nil, pb.MemcacheSetRequest_SET)
324 }
325
326 // Add writes the given item, if no value already exists for its key.
327 // ErrNotStored is returned if that condition is not met.
328 func Add(c context.Context, item *Item) error {
329 return singleError(set(c, []*Item{item}, nil, pb.MemcacheSetRequest_ADD))
330 }
331
332 // AddMulti is a batch version of Add.
333 // appengine.MultiError may be returned.
334 func AddMulti(c context.Context, item []*Item) error {
335 return set(c, item, nil, pb.MemcacheSetRequest_ADD)
336 }
337
338 // CompareAndSwap writes the given item that was previously returned by Get,
339 // if the value was neither modified or evicted between the Get and the
340 // CompareAndSwap calls. The item's Key should not change between calls but
341 // all other item fields may differ.
342 // ErrCASConflict is returned if the value was modified in between the calls.
343 // ErrNotStored is returned if the value was evicted in between the calls.
344 func CompareAndSwap(c context.Context, item *Item) error {
345 return singleError(set(c, []*Item{item}, nil, pb.MemcacheSetRequest_CAS))
346 }
347
348 // CompareAndSwapMulti is a batch version of CompareAndSwap.
349 // appengine.MultiError may be returned.
350 func CompareAndSwapMulti(c context.Context, item []*Item) error {
351 return set(c, item, nil, pb.MemcacheSetRequest_CAS)
352 }
353
354 // Codec represents a symmetric pair of functions that implement a codec.
355 // Items stored into or retrieved from memcache using a Codec have their
356 // values marshaled or unmarshaled.
357 //
358 // All the methods provided for Codec behave analogously to the package level
359 // function with same name.
360 type Codec struct {
361 Marshal func(interface{}) ([]byte, error)
362 Unmarshal func([]byte, interface{}) error
363 }
364
365 // Get gets the item for the given key and decodes the obtained value into v.
366 // ErrCacheMiss is returned for a memcache cache miss.
367 // The key must be at most 250 bytes in length.
368 func (cd Codec) Get(c context.Context, key string, v interface{}) (*Item, error) {
369 i, err := Get(c, key)
370 if err != nil {
371 return nil, err
372 }
373 if err := cd.Unmarshal(i.Value, v); err != nil {
374 return nil, err
375 }
376 return i, nil
377 }
378
379 func (cd Codec) set(c context.Context, items []*Item, policy pb.MemcacheSetRequest_SetPolicy) error {
380 var vs [][]byte
381 var me appengine.MultiError
382 for i, item := range items {
383 v, err := cd.Marshal(item.Object)
384 if err != nil {
385 if me == nil {
386 me = make(appengine.MultiError, len(items))
387 }
388 me[i] = err
389 continue
390 }
391 if me == nil {
392 vs = append(vs, v)
393 }
394 }
395 if me != nil {
396 return me
397 }
398
399 return set(c, items, vs, policy)
400 }
401
402 // Set writes the given item, unconditionally.
403 func (cd Codec) Set(c context.Context, item *Item) error {
404 return singleError(cd.set(c, []*Item{item}, pb.MemcacheSetRequest_SET))
405 }
406
407 // SetMulti is a batch version of Set.
408 // appengine.MultiError may be returned.
409 func (cd Codec) SetMulti(c context.Context, items []*Item) error {
410 return cd.set(c, items, pb.MemcacheSetRequest_SET)
411 }
412
413 // Add writes the given item, if no value already exists for its key.
414 // ErrNotStored is returned if that condition is not met.
415 func (cd Codec) Add(c context.Context, item *Item) error {
416 return singleError(cd.set(c, []*Item{item}, pb.MemcacheSetRequest_ADD))
417 }
418
419 // AddMulti is a batch version of Add.
420 // appengine.MultiError may be returned.
421 func (cd Codec) AddMulti(c context.Context, items []*Item) error {
422 return cd.set(c, items, pb.MemcacheSetRequest_ADD)
423 }
424
425 // CompareAndSwap writes the given item that was previously returned by Get,
426 // if the value was neither modified or evicted between the Get and the
427 // CompareAndSwap calls. The item's Key should not change between calls but
428 // all other item fields may differ.
429 // ErrCASConflict is returned if the value was modified in between the calls.
430 // ErrNotStored is returned if the value was evicted in between the calls.
431 func (cd Codec) CompareAndSwap(c context.Context, item *Item) error {
432 return singleError(cd.set(c, []*Item{item}, pb.MemcacheSetRequest_CAS))
433 }
434
435 // CompareAndSwapMulti is a batch version of CompareAndSwap.
436 // appengine.MultiError may be returned.
437 func (cd Codec) CompareAndSwapMulti(c context.Context, items []*Item) error {
438 return cd.set(c, items, pb.MemcacheSetRequest_CAS)
439 }
440
441 var (
442 // Gob is a Codec that uses the gob package.
443 Gob = Codec{gobMarshal, gobUnmarshal}
444 // JSON is a Codec that uses the json package.
445 JSON = Codec{json.Marshal, json.Unmarshal}
446 )
447
448 func gobMarshal(v interface{}) ([]byte, error) {
449 var buf bytes.Buffer
450 if err := gob.NewEncoder(&buf).Encode(v); err != nil {
451 return nil, err
452 }
453 return buf.Bytes(), nil
454 }
455
456 func gobUnmarshal(data []byte, v interface{}) error {
457 return gob.NewDecoder(bytes.NewBuffer(data)).Decode(v)
458 }
459
460 // Statistics represents a set of statistics about the memcache cache.
461 // This may include items that have expired but have not yet been removed from the cache.
462 type Statistics struct {
463 Hits uint64 // Counter of cache hits
464 Misses uint64 // Counter of cache misses
465 ByteHits uint64 // Counter of bytes transferred for gets
466
467 Items uint64 // Items currently in the cache
468 Bytes uint64 // Size of all items currently in the cache
469
470 Oldest int64 // Age of access of the oldest item, in seconds
471 }
472
473 // Stats retrieves the current memcache statistics.
474 func Stats(c context.Context) (*Statistics, error) {
475 req := &pb.MemcacheStatsRequest{}
476 res := &pb.MemcacheStatsResponse{}
477 if err := internal.Call(c, "memcache", "Stats", req, res); err != nil {
478 return nil, err
479 }
480 if res.Stats == nil {
481 return nil, ErrNoStats
482 }
483 return &Statistics{
484 Hits: *res.Stats.Hits,
485 Misses: *res.Stats.Misses,
486 ByteHits: *res.Stats.ByteHits,
487 Items: *res.Stats.Items,
488 Bytes: *res.Stats.Bytes,
489 Oldest: int64(*res.Stats.OldestItemAge),
490 }, nil
491 }
492
493 // Flush flushes all items from memcache.
494 func Flush(c context.Context) error {
495 req := &pb.MemcacheFlushRequest{}
496 res := &pb.MemcacheFlushResponse{}
497 return internal.Call(c, "memcache", "FlushAll", req, res)
498 }
499
500 func namespaceMod(m proto.Message, namespace string) {
501 switch m := m.(type) {
502 case *pb.MemcacheDeleteRequest:
503 if m.NameSpace == nil {
504 m.NameSpace = &namespace
505 }
506 case *pb.MemcacheGetRequest:
507 if m.NameSpace == nil {
508 m.NameSpace = &namespace
509 }
510 case *pb.MemcacheIncrementRequest:
511 if m.NameSpace == nil {
512 m.NameSpace = &namespace
513 }
514 case *pb.MemcacheSetRequest:
515 if m.NameSpace == nil {
516 m.NameSpace = &namespace
517 }
518 // MemcacheFlushRequest, MemcacheStatsRequest do not apply namespace.
519 }
520 }
521
522 func init() {
523 internal.RegisterErrorCodeMap("memcache", pb.MemcacheServiceError_ErrorCode_name)
524 internal.NamespaceMods["memcache"] = namespaceMod
525 }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package memcache
5
6 import (
7 "fmt"
8 "testing"
9
10 "google.golang.org/appengine/v2"
11 "google.golang.org/appengine/v2/internal/aetesting"
12 pb "google.golang.org/appengine/v2/internal/memcache"
13 )
14
15 var errRPC = fmt.Errorf("RPC error")
16
17 func TestGetRequest(t *testing.T) {
18 serviceCalled := false
19 apiKey := "lyric"
20
21 c := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, _ *pb.MemcacheGetResponse) error {
22 // Test request.
23 if n := len(req.Key); n != 1 {
24 t.Errorf("got %d want 1", n)
25 return nil
26 }
27 if k := string(req.Key[0]); k != apiKey {
28 t.Errorf("got %q want %q", k, apiKey)
29 }
30
31 serviceCalled = true
32 return nil
33 })
34
35 // Test the "forward" path from the API call parameters to the
36 // protobuf request object. (The "backward" path from the
37 // protobuf response object to the API call response,
38 // including the error response, are handled in the next few
39 // tests).
40 Get(c, apiKey)
41 if !serviceCalled {
42 t.Error("Service was not called as expected")
43 }
44 }
45
46 func TestGetResponseHit(t *testing.T) {
47 key := "lyric"
48 value := "Where the buffalo roam"
49
50 c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
51 res.Item = []*pb.MemcacheGetResponse_Item{
52 {Key: []byte(key), Value: []byte(value)},
53 }
54 return nil
55 })
56 apiItem, err := Get(c, key)
57 if apiItem == nil || apiItem.Key != key || string(apiItem.Value) != value {
58 t.Errorf("got %q, %q want {%q,%q}, nil", apiItem, err, key, value)
59 }
60 }
61
62 func TestGetResponseMiss(t *testing.T) {
63 c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
64 // don't fill in any of the response
65 return nil
66 })
67 _, err := Get(c, "something")
68 if err != ErrCacheMiss {
69 t.Errorf("got %v want ErrCacheMiss", err)
70 }
71 }
72
73 func TestGetResponseRPCError(t *testing.T) {
74 c := aetesting.FakeSingleContext(t, "memcache", "Get", func(_ *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
75 return errRPC
76 })
77
78 if _, err := Get(c, "something"); err != errRPC {
79 t.Errorf("got %v want errRPC", err)
80 }
81 }
82
83 func TestAddRequest(t *testing.T) {
84 var apiItem = &Item{
85 Key: "lyric",
86 Value: []byte("Oh, give me a home"),
87 }
88
89 serviceCalled := false
90
91 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(req *pb.MemcacheSetRequest, _ *pb.MemcacheSetResponse) error {
92 // Test request.
93 pbItem := req.Item[0]
94 if k := string(pbItem.Key); k != apiItem.Key {
95 t.Errorf("got %q want %q", k, apiItem.Key)
96 }
97 if v := string(apiItem.Value); v != string(pbItem.Value) {
98 t.Errorf("got %q want %q", v, string(pbItem.Value))
99 }
100 if p := *pbItem.SetPolicy; p != pb.MemcacheSetRequest_ADD {
101 t.Errorf("got %v want %v", p, pb.MemcacheSetRequest_ADD)
102 }
103
104 serviceCalled = true
105 return nil
106 })
107
108 Add(c, apiItem)
109 if !serviceCalled {
110 t.Error("Service was not called as expected")
111 }
112 }
113
114 func TestAddResponseStored(t *testing.T) {
115 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
116 res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_STORED}
117 return nil
118 })
119
120 if err := Add(c, &Item{}); err != nil {
121 t.Errorf("got %v want nil", err)
122 }
123 }
124
125 func TestAddResponseNotStored(t *testing.T) {
126 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
127 res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_NOT_STORED}
128 return nil
129 })
130
131 if err := Add(c, &Item{}); err != ErrNotStored {
132 t.Errorf("got %v want ErrNotStored", err)
133 }
134 }
135
136 func TestAddResponseError(t *testing.T) {
137 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
138 res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_ERROR}
139 return nil
140 })
141
142 if err := Add(c, &Item{}); err != ErrServerError {
143 t.Errorf("got %v want ErrServerError", err)
144 }
145 }
146
147 func TestAddResponseRPCError(t *testing.T) {
148 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
149 return errRPC
150 })
151
152 if err := Add(c, &Item{}); err != errRPC {
153 t.Errorf("got %v want errRPC", err)
154 }
155 }
156
157 func TestSetRequest(t *testing.T) {
158 var apiItem = &Item{
159 Key: "lyric",
160 Value: []byte("Where the buffalo roam"),
161 }
162
163 serviceCalled := false
164
165 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(req *pb.MemcacheSetRequest, _ *pb.MemcacheSetResponse) error {
166 // Test request.
167 if n := len(req.Item); n != 1 {
168 t.Errorf("got %d want 1", n)
169 return nil
170 }
171 pbItem := req.Item[0]
172 if k := string(pbItem.Key); k != apiItem.Key {
173 t.Errorf("got %q want %q", k, apiItem.Key)
174 }
175 if v := string(pbItem.Value); v != string(apiItem.Value) {
176 t.Errorf("got %q want %q", v, string(apiItem.Value))
177 }
178 if p := *pbItem.SetPolicy; p != pb.MemcacheSetRequest_SET {
179 t.Errorf("got %v want %v", p, pb.MemcacheSetRequest_SET)
180 }
181
182 serviceCalled = true
183 return nil
184 })
185
186 Set(c, apiItem)
187 if !serviceCalled {
188 t.Error("Service was not called as expected")
189 }
190 }
191
192 func TestSetResponse(t *testing.T) {
193 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
194 res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_STORED}
195 return nil
196 })
197
198 if err := Set(c, &Item{}); err != nil {
199 t.Errorf("got %v want nil", err)
200 }
201 }
202
203 func TestSetResponseError(t *testing.T) {
204 c := aetesting.FakeSingleContext(t, "memcache", "Set", func(_ *pb.MemcacheSetRequest, res *pb.MemcacheSetResponse) error {
205 res.SetStatus = []pb.MemcacheSetResponse_SetStatusCode{pb.MemcacheSetResponse_ERROR}
206 return nil
207 })
208
209 if err := Set(c, &Item{}); err != ErrServerError {
210 t.Errorf("got %v want ErrServerError", err)
211 }
212 }
213
214 func TestNamespaceResetting(t *testing.T) {
215 namec := make(chan *string, 1)
216 c0 := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, res *pb.MemcacheGetResponse) error {
217 namec <- req.NameSpace
218 return errRPC
219 })
220
221 // Check that wrapping c0 in a namespace twice works correctly.
222 c1, err := appengine.Namespace(c0, "A")
223 if err != nil {
224 t.Fatalf("appengine.Namespace: %v", err)
225 }
226 c2, err := appengine.Namespace(c1, "") // should act as the original context
227 if err != nil {
228 t.Fatalf("appengine.Namespace: %v", err)
229 }
230
231 Get(c0, "key")
232 if ns := <-namec; ns != nil {
233 t.Errorf(`Get with c0: ns = %q, want nil`, *ns)
234 }
235
236 Get(c1, "key")
237 if ns := <-namec; ns == nil {
238 t.Error(`Get with c1: ns = nil, want "A"`)
239 } else if *ns != "A" {
240 t.Errorf(`Get with c1: ns = %q, want "A"`, *ns)
241 }
242
243 Get(c2, "key")
244 if ns := <-namec; ns != nil {
245 t.Errorf(`Get with c2: ns = %q, want nil`, *ns)
246 }
247 }
248
249 func TestGetMultiEmpty(t *testing.T) {
250 serviceCalled := false
251 c := aetesting.FakeSingleContext(t, "memcache", "Get", func(req *pb.MemcacheGetRequest, _ *pb.MemcacheGetResponse) error {
252 serviceCalled = true
253 return nil
254 })
255
256 // Test that the Memcache service is not called when
257 // GetMulti is passed an empty slice of keys.
258 GetMulti(c, []string{})
259 if serviceCalled {
260 t.Error("Service was called but should not have been")
261 }
262 }
0 // Copyright 2013 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 /*
5 Package module provides functions for interacting with modules.
6
7 The appengine package contains functions that report the identity of the app,
8 including the module name.
9 */
10 package module // import "google.golang.org/appengine/v2/module"
11
12 import (
13 "context"
14
15 "github.com/golang/protobuf/proto"
16
17 "google.golang.org/appengine/v2/internal"
18 pb "google.golang.org/appengine/v2/internal/modules"
19 )
20
21 // List returns the names of modules belonging to this application.
22 func List(c context.Context) ([]string, error) {
23 req := &pb.GetModulesRequest{}
24 res := &pb.GetModulesResponse{}
25 err := internal.Call(c, "modules", "GetModules", req, res)
26 return res.Module, err
27 }
28
29 // NumInstances returns the number of instances of the given module/version.
30 // If either argument is the empty string it means the default. This only works
31 // if you are using manual_scaling in your app's config file.
32 func NumInstances(c context.Context, module, version string) (int, error) {
33 req := &pb.GetNumInstancesRequest{}
34 if module != "" {
35 req.Module = &module
36 }
37 if version != "" {
38 req.Version = &version
39 }
40 res := &pb.GetNumInstancesResponse{}
41
42 if err := internal.Call(c, "modules", "GetNumInstances", req, res); err != nil {
43 return 0, err
44 }
45 return int(*res.Instances), nil
46 }
47
48 // SetNumInstances sets the number of instances of the given module.version to the
49 // specified value. If either module or version are the empty string it means the
50 // default.
51 func SetNumInstances(c context.Context, module, version string, instances int) error {
52 req := &pb.SetNumInstancesRequest{}
53 if module != "" {
54 req.Module = &module
55 }
56 if version != "" {
57 req.Version = &version
58 }
59 req.Instances = proto.Int64(int64(instances))
60 res := &pb.SetNumInstancesResponse{}
61 return internal.Call(c, "modules", "SetNumInstances", req, res)
62 }
63
64 // Versions returns the names of the versions that belong to the specified module.
65 // If module is the empty string, it means the default module.
66 func Versions(c context.Context, module string) ([]string, error) {
67 req := &pb.GetVersionsRequest{}
68 if module != "" {
69 req.Module = &module
70 }
71 res := &pb.GetVersionsResponse{}
72 err := internal.Call(c, "modules", "GetVersions", req, res)
73 return res.GetVersion(), err
74 }
75
76 // DefaultVersion returns the default version of the specified module.
77 // If module is the empty string, it means the default module.
78 func DefaultVersion(c context.Context, module string) (string, error) {
79 req := &pb.GetDefaultVersionRequest{}
80 if module != "" {
81 req.Module = &module
82 }
83 res := &pb.GetDefaultVersionResponse{}
84 err := internal.Call(c, "modules", "GetDefaultVersion", req, res)
85 return res.GetVersion(), err
86 }
87
88 // Start starts the specified version of the specified module.
89 // If either module or version are the empty string, it means the default.
90 func Start(c context.Context, module, version string) error {
91 req := &pb.StartModuleRequest{}
92 if module != "" {
93 req.Module = &module
94 }
95 if version != "" {
96 req.Version = &version
97 }
98 res := &pb.StartModuleResponse{}
99 return internal.Call(c, "modules", "StartModule", req, res)
100 }
101
102 // Stop stops the specified version of the specified module.
103 // If either module or version are the empty string, it means the default.
104 func Stop(c context.Context, module, version string) error {
105 req := &pb.StopModuleRequest{}
106 if module != "" {
107 req.Module = &module
108 }
109 if version != "" {
110 req.Version = &version
111 }
112 res := &pb.StopModuleResponse{}
113 return internal.Call(c, "modules", "StopModule", req, res)
114 }
0 // Copyright 2013 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package module
5
6 import (
7 "reflect"
8 "testing"
9
10 "github.com/golang/protobuf/proto"
11
12 "google.golang.org/appengine/v2/internal/aetesting"
13 pb "google.golang.org/appengine/v2/internal/modules"
14 )
15
16 const version = "test-version"
17 const module = "test-module"
18 const instances = 3
19
20 func TestList(t *testing.T) {
21 c := aetesting.FakeSingleContext(t, "modules", "GetModules", func(req *pb.GetModulesRequest, res *pb.GetModulesResponse) error {
22 res.Module = []string{"default", "mod1"}
23 return nil
24 })
25 got, err := List(c)
26 if err != nil {
27 t.Fatalf("List: %v", err)
28 }
29 want := []string{"default", "mod1"}
30 if !reflect.DeepEqual(got, want) {
31 t.Errorf("List = %v, want %v", got, want)
32 }
33 }
34
35 func TestSetNumInstances(t *testing.T) {
36 c := aetesting.FakeSingleContext(t, "modules", "SetNumInstances", func(req *pb.SetNumInstancesRequest, res *pb.SetNumInstancesResponse) error {
37 if *req.Module != module {
38 t.Errorf("Module = %v, want %v", req.Module, module)
39 }
40 if *req.Version != version {
41 t.Errorf("Version = %v, want %v", req.Version, version)
42 }
43 if *req.Instances != instances {
44 t.Errorf("Instances = %v, want %d", req.Instances, instances)
45 }
46 return nil
47 })
48 err := SetNumInstances(c, module, version, instances)
49 if err != nil {
50 t.Fatalf("SetNumInstances: %v", err)
51 }
52 }
53
54 func TestVersions(t *testing.T) {
55 c := aetesting.FakeSingleContext(t, "modules", "GetVersions", func(req *pb.GetVersionsRequest, res *pb.GetVersionsResponse) error {
56 if *req.Module != module {
57 t.Errorf("Module = %v, want %v", req.Module, module)
58 }
59 res.Version = []string{"v1", "v2", "v3"}
60 return nil
61 })
62 got, err := Versions(c, module)
63 if err != nil {
64 t.Fatalf("Versions: %v", err)
65 }
66 want := []string{"v1", "v2", "v3"}
67 if !reflect.DeepEqual(got, want) {
68 t.Errorf("Versions = %v, want %v", got, want)
69 }
70 }
71
72 func TestDefaultVersion(t *testing.T) {
73 c := aetesting.FakeSingleContext(t, "modules", "GetDefaultVersion", func(req *pb.GetDefaultVersionRequest, res *pb.GetDefaultVersionResponse) error {
74 if *req.Module != module {
75 t.Errorf("Module = %v, want %v", req.Module, module)
76 }
77 res.Version = proto.String(version)
78 return nil
79 })
80 got, err := DefaultVersion(c, module)
81 if err != nil {
82 t.Fatalf("DefaultVersion: %v", err)
83 }
84 if got != version {
85 t.Errorf("Version = %v, want %v", got, version)
86 }
87 }
88
89 func TestStart(t *testing.T) {
90 c := aetesting.FakeSingleContext(t, "modules", "StartModule", func(req *pb.StartModuleRequest, res *pb.StartModuleResponse) error {
91 if *req.Module != module {
92 t.Errorf("Module = %v, want %v", req.Module, module)
93 }
94 if *req.Version != version {
95 t.Errorf("Version = %v, want %v", req.Version, version)
96 }
97 return nil
98 })
99
100 err := Start(c, module, version)
101 if err != nil {
102 t.Fatalf("Start: %v", err)
103 }
104 }
105
106 func TestStop(t *testing.T) {
107 c := aetesting.FakeSingleContext(t, "modules", "StopModule", func(req *pb.StopModuleRequest, res *pb.StopModuleResponse) error {
108 version := "test-version"
109 module := "test-module"
110 if *req.Module != module {
111 t.Errorf("Module = %v, want %v", req.Module, module)
112 }
113 if *req.Version != version {
114 t.Errorf("Version = %v, want %v", req.Version, version)
115 }
116 return nil
117 })
118
119 err := Stop(c, module, version)
120 if err != nil {
121 t.Fatalf("Stop: %v", err)
122 }
123 }
0 // Copyright 2012 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package appengine
5
6 import (
7 "context"
8 "fmt"
9 "regexp"
10
11 "google.golang.org/appengine/v2/internal"
12 )
13
14 // Namespace returns a replacement context that operates within the given namespace.
15 func Namespace(c context.Context, namespace string) (context.Context, error) {
16 if !validNamespace.MatchString(namespace) {
17 return nil, fmt.Errorf("appengine: namespace %q does not match /%s/", namespace, validNamespace)
18 }
19 return internal.NamespacedContext(c, namespace), nil
20 }
21
22 // validNamespace matches valid namespace names.
23 var validNamespace = regexp.MustCompile(`^[0-9A-Za-z._-]{0,100}$`)
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package appengine
5
6 import (
7 "context"
8 "testing"
9 )
10
11 func TestNamespaceValidity(t *testing.T) {
12 testCases := []struct {
13 namespace string
14 ok bool
15 }{
16 // data from Python's namespace_manager_test.py
17 {"", true},
18 {"__a.namespace.123__", true},
19 {"-_A....NAMESPACE-_", true},
20 {"-", true},
21 {".", true},
22 {".-", true},
23
24 {"?", false},
25 {"+", false},
26 {"!", false},
27 {" ", false},
28 }
29 for _, tc := range testCases {
30 _, err := Namespace(context.Background(), tc.namespace)
31 if err == nil && !tc.ok {
32 t.Errorf("Namespace %q should be rejected, but wasn't", tc.namespace)
33 } else if err != nil && tc.ok {
34 t.Errorf("Namespace %q should be accepted, but wasn't", tc.namespace)
35 }
36 }
37 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 /*
5 Package runtime exposes information about the resource usage of the application.
6 It also provides a way to run code in a new background context of a module.
7
8 This package does not work on App Engine "flexible environment".
9 */
10 package runtime // import "google.golang.org/appengine/v2/runtime"
11
12 import (
13 "context"
14 "net/http"
15
16 "google.golang.org/appengine/v2"
17 "google.golang.org/appengine/v2/internal"
18 pb "google.golang.org/appengine/v2/internal/system"
19 )
20
21 // Statistics represents the system's statistics.
22 type Statistics struct {
23 // CPU records the CPU consumed by this instance, in megacycles.
24 CPU struct {
25 Total float64
26 Rate1M float64 // consumption rate over one minute
27 Rate10M float64 // consumption rate over ten minutes
28 }
29 // RAM records the memory used by the instance, in megabytes.
30 RAM struct {
31 Current float64
32 Average1M float64 // average usage over one minute
33 Average10M float64 // average usage over ten minutes
34 }
35 }
36
37 func Stats(c context.Context) (*Statistics, error) {
38 req := &pb.GetSystemStatsRequest{}
39 res := &pb.GetSystemStatsResponse{}
40 if err := internal.Call(c, "system", "GetSystemStats", req, res); err != nil {
41 return nil, err
42 }
43 s := &Statistics{}
44 if res.Cpu != nil {
45 s.CPU.Total = res.Cpu.GetTotal()
46 s.CPU.Rate1M = res.Cpu.GetRate1M()
47 s.CPU.Rate10M = res.Cpu.GetRate10M()
48 }
49 if res.Memory != nil {
50 s.RAM.Current = res.Memory.GetCurrent()
51 s.RAM.Average1M = res.Memory.GetAverage1M()
52 s.RAM.Average10M = res.Memory.GetAverage10M()
53 }
54 return s, nil
55 }
56
57 /*
58 RunInBackground makes an API call that triggers an /_ah/background request.
59
60 There are two independent code paths that need to make contact:
61 the RunInBackground code, and the /_ah/background handler. The matchmaker
62 loop arranges for the two paths to meet. The RunInBackground code passes
63 a send to the matchmaker, the /_ah/background passes a recv to the matchmaker,
64 and the matchmaker hooks them up.
65 */
66
67 func init() {
68 http.HandleFunc("/_ah/background", handleBackground)
69
70 sc := make(chan send)
71 rc := make(chan recv)
72 sendc, recvc = sc, rc
73 go matchmaker(sc, rc)
74 }
75
76 var (
77 sendc chan<- send // RunInBackground sends to this
78 recvc chan<- recv // handleBackground sends to this
79 )
80
81 type send struct {
82 id string
83 f func(context.Context)
84 }
85
86 type recv struct {
87 id string
88 ch chan<- func(context.Context)
89 }
90
91 func matchmaker(sendc <-chan send, recvc <-chan recv) {
92 // When one side of the match arrives before the other
93 // it is inserted in the corresponding map.
94 waitSend := make(map[string]send)
95 waitRecv := make(map[string]recv)
96
97 for {
98 select {
99 case s := <-sendc:
100 if r, ok := waitRecv[s.id]; ok {
101 // meet!
102 delete(waitRecv, s.id)
103 r.ch <- s.f
104 } else {
105 // waiting for r
106 waitSend[s.id] = s
107 }
108 case r := <-recvc:
109 if s, ok := waitSend[r.id]; ok {
110 // meet!
111 delete(waitSend, r.id)
112 r.ch <- s.f
113 } else {
114 // waiting for s
115 waitRecv[r.id] = r
116 }
117 }
118 }
119 }
120
121 var newContext = appengine.NewContext // for testing
122
123 func handleBackground(w http.ResponseWriter, req *http.Request) {
124 id := req.Header.Get("X-AppEngine-BackgroundRequest")
125
126 ch := make(chan func(context.Context))
127 recvc <- recv{id, ch}
128 (<-ch)(newContext(req))
129 }
130
131 // RunInBackground runs f in a background goroutine in this process.
132 // f is provided a context that may outlast the context provided to RunInBackground.
133 // This is only valid to invoke from a service set to basic or manual scaling.
134 func RunInBackground(c context.Context, f func(c context.Context)) error {
135 req := &pb.StartBackgroundRequestRequest{}
136 res := &pb.StartBackgroundRequestResponse{}
137 if err := internal.Call(c, "system", "StartBackgroundRequest", req, res); err != nil {
138 return err
139 }
140 sendc <- send{res.GetRequestId(), f}
141 return nil
142 }
143
144 func init() {
145 internal.RegisterErrorCodeMap("system", pb.SystemServiceError_ErrorCode_name)
146 }
0 // Copyright 2012 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package runtime
5
6 import (
7 "context"
8 "fmt"
9 "net/http"
10 "net/http/httptest"
11 "testing"
12 "time"
13
14 "github.com/golang/protobuf/proto"
15
16 "google.golang.org/appengine/v2/internal/aetesting"
17 pb "google.golang.org/appengine/v2/internal/system"
18 )
19
20 func TestRunInBackgroundSendFirst(t *testing.T) { testRunInBackground(t, true) }
21 func TestRunInBackgroundRecvFirst(t *testing.T) { testRunInBackground(t, false) }
22
23 func testRunInBackground(t *testing.T, sendFirst bool) {
24 srv := httptest.NewServer(nil)
25 defer srv.Close()
26
27 const id = "f00bar"
28 sendWait, recvWait := make(chan bool), make(chan bool)
29 sbr := make(chan bool) // strobed when system.StartBackgroundRequest has started
30
31 calls := 0
32 c := aetesting.FakeSingleContext(t, "system", "StartBackgroundRequest", func(req *pb.StartBackgroundRequestRequest, res *pb.StartBackgroundRequestResponse) error {
33 calls++
34 if calls > 1 {
35 t.Errorf("Too many calls to system.StartBackgroundRequest")
36 }
37 sbr <- true
38 res.RequestId = proto.String(id)
39 <-sendWait
40 return nil
41 })
42
43 var c2 context.Context // a fake
44 newContext = func(*http.Request) context.Context {
45 return c2
46 }
47
48 var fRun int
49 f := func(c3 context.Context) {
50 fRun++
51 if c3 != c2 {
52 t.Errorf("f got a different context than expected")
53 }
54 }
55
56 ribErrc := make(chan error)
57 go func() {
58 ribErrc <- RunInBackground(c, f)
59 }()
60
61 brErrc := make(chan error)
62 go func() {
63 <-sbr
64 req, err := http.NewRequest("GET", srv.URL+"/_ah/background", nil)
65 if err != nil {
66 brErrc <- fmt.Errorf("http.NewRequest: %v", err)
67 return
68 }
69 req.Header.Set("X-AppEngine-BackgroundRequest", id)
70 client := &http.Client{
71 Transport: &http.Transport{
72 Proxy: http.ProxyFromEnvironment,
73 },
74 }
75
76 <-recvWait
77 _, err = client.Do(req)
78 brErrc <- err
79 }()
80
81 // Send and receive are both waiting at this point.
82 waits := [2]chan bool{sendWait, recvWait}
83 if !sendFirst {
84 waits[0], waits[1] = waits[1], waits[0]
85 }
86 waits[0] <- true
87 time.Sleep(100 * time.Millisecond)
88 waits[1] <- true
89
90 if err := <-ribErrc; err != nil {
91 t.Fatalf("RunInBackground: %v", err)
92 }
93 if err := <-brErrc; err != nil {
94 t.Fatalf("background request: %v", err)
95 }
96
97 if fRun != 1 {
98 t.Errorf("Got %d runs of f, want 1", fRun)
99 }
100 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 /*
5 Package taskqueue provides a client for App Engine's taskqueue service.
6 Using this service, applications may perform work outside a user's request.
7
8 A Task may be constructed manually; alternatively, since the most common
9 taskqueue operation is to add a single POST task, NewPOSTTask makes it easy.
10
11 t := taskqueue.NewPOSTTask("/worker", url.Values{
12 "key": {key},
13 })
14 taskqueue.Add(c, t, "") // add t to the default queue
15 */
16 package taskqueue // import "google.golang.org/appengine/v2/taskqueue"
17
18 import (
19 "context"
20 "errors"
21 "fmt"
22 "net/http"
23 "net/url"
24 "strconv"
25 "time"
26
27 "github.com/golang/protobuf/proto"
28
29 "google.golang.org/appengine/v2"
30 "google.golang.org/appengine/v2/internal"
31 dspb "google.golang.org/appengine/v2/internal/datastore"
32 pb "google.golang.org/appengine/v2/internal/taskqueue"
33 )
34
35 var (
36 // ErrTaskAlreadyAdded is the error returned by Add and AddMulti when a task has already been added with a particular name.
37 ErrTaskAlreadyAdded = errors.New("taskqueue: task has already been added")
38 )
39
40 // RetryOptions let you control whether to retry a task and the backoff intervals between tries.
41 type RetryOptions struct {
42 // Number of tries/leases after which the task fails permanently and is deleted.
43 // If AgeLimit is also set, both limits must be exceeded for the task to fail permanently.
44 RetryLimit int32
45
46 // Maximum time allowed since the task's first try before the task fails permanently and is deleted (only for push tasks).
47 // If RetryLimit is also set, both limits must be exceeded for the task to fail permanently.
48 AgeLimit time.Duration
49
50 // Minimum time between successive tries (only for push tasks).
51 MinBackoff time.Duration
52
53 // Maximum time between successive tries (only for push tasks).
54 MaxBackoff time.Duration
55
56 // Maximum number of times to double the interval between successive tries before the intervals increase linearly (only for push tasks).
57 MaxDoublings int32
58
59 // If MaxDoublings is zero, set ApplyZeroMaxDoublings to true to override the default non-zero value.
60 // Otherwise a zero MaxDoublings is ignored and the default is used.
61 ApplyZeroMaxDoublings bool
62 }
63
64 // toRetryParameter converts RetryOptions to pb.TaskQueueRetryParameters.
65 func (opt *RetryOptions) toRetryParameters() *pb.TaskQueueRetryParameters {
66 params := &pb.TaskQueueRetryParameters{}
67 if opt.RetryLimit > 0 {
68 params.RetryLimit = proto.Int32(opt.RetryLimit)
69 }
70 if opt.AgeLimit > 0 {
71 params.AgeLimitSec = proto.Int64(int64(opt.AgeLimit.Seconds()))
72 }
73 if opt.MinBackoff > 0 {
74 params.MinBackoffSec = proto.Float64(opt.MinBackoff.Seconds())
75 }
76 if opt.MaxBackoff > 0 {
77 params.MaxBackoffSec = proto.Float64(opt.MaxBackoff.Seconds())
78 }
79 if opt.MaxDoublings > 0 || (opt.MaxDoublings == 0 && opt.ApplyZeroMaxDoublings) {
80 params.MaxDoublings = proto.Int32(opt.MaxDoublings)
81 }
82 return params
83 }
84
85 // A Task represents a task to be executed.
86 type Task struct {
87 // Path is the worker URL for the task.
88 // If unset, it will default to /_ah/queue/<queue_name>.
89 Path string
90
91 // Payload is the data for the task.
92 // This will be delivered as the HTTP request body.
93 // It is only used when Method is POST, PUT or PULL.
94 // url.Values' Encode method may be used to generate this for POST requests.
95 Payload []byte
96
97 // Additional HTTP headers to pass at the task's execution time.
98 // To schedule the task to be run with an alternate app version
99 // or backend, set the "Host" header.
100 Header http.Header
101
102 // Method is the HTTP method for the task ("GET", "POST", etc.),
103 // or "PULL" if this is task is destined for a pull-based queue.
104 // If empty, this defaults to "POST".
105 Method string
106
107 // A name for the task.
108 // If empty, a name will be chosen.
109 Name string
110
111 // Delay specifies the duration the task queue service must wait
112 // before executing the task.
113 // Either Delay or ETA may be set, but not both.
114 Delay time.Duration
115
116 // ETA specifies the earliest time a task may be executed (push queues)
117 // or leased (pull queues).
118 // Either Delay or ETA may be set, but not both.
119 ETA time.Time
120
121 // The number of times the task has been dispatched or leased.
122 RetryCount int32
123
124 // Tag for the task. Only used when Method is PULL.
125 Tag string
126
127 // Retry options for this task. May be nil.
128 RetryOptions *RetryOptions
129 }
130
131 func (t *Task) method() string {
132 if t.Method == "" {
133 return "POST"
134 }
135 return t.Method
136 }
137
138 // NewPOSTTask creates a Task that will POST to a path with the given form data.
139 func NewPOSTTask(path string, params url.Values) *Task {
140 h := make(http.Header)
141 h.Set("Content-Type", "application/x-www-form-urlencoded")
142 return &Task{
143 Path: path,
144 Payload: []byte(params.Encode()),
145 Header: h,
146 Method: "POST",
147 }
148 }
149
150 // RequestHeaders are the special HTTP request headers available to push task
151 // HTTP request handlers. These headers are set internally by App Engine.
152 // See https://cloud.google.com/appengine/docs/standard/go/taskqueue/push/creating-handlers#reading_request_headers
153 // for a description of the fields.
154 type RequestHeaders struct {
155 QueueName string
156 TaskName string
157 TaskRetryCount int64
158 TaskExecutionCount int64
159 TaskETA time.Time
160
161 TaskPreviousResponse int
162 TaskRetryReason string
163 FailFast bool
164 }
165
166 // ParseRequestHeaders parses the special HTTP request headers available to push
167 // task request handlers. This function silently ignores values of the wrong
168 // format.
169 func ParseRequestHeaders(h http.Header) *RequestHeaders {
170 ret := &RequestHeaders{
171 QueueName: h.Get("X-AppEngine-QueueName"),
172 TaskName: h.Get("X-AppEngine-TaskName"),
173 }
174
175 ret.TaskRetryCount, _ = strconv.ParseInt(h.Get("X-AppEngine-TaskRetryCount"), 10, 64)
176 ret.TaskExecutionCount, _ = strconv.ParseInt(h.Get("X-AppEngine-TaskExecutionCount"), 10, 64)
177
178 etaSecs, _ := strconv.ParseInt(h.Get("X-AppEngine-TaskETA"), 10, 64)
179 if etaSecs != 0 {
180 ret.TaskETA = time.Unix(etaSecs, 0)
181 }
182
183 ret.TaskPreviousResponse, _ = strconv.Atoi(h.Get("X-AppEngine-TaskPreviousResponse"))
184 ret.TaskRetryReason = h.Get("X-AppEngine-TaskRetryReason")
185 if h.Get("X-AppEngine-FailFast") != "" {
186 ret.FailFast = true
187 }
188
189 return ret
190 }
191
192 var (
193 currentNamespace = http.CanonicalHeaderKey("X-AppEngine-Current-Namespace")
194 defaultNamespace = http.CanonicalHeaderKey("X-AppEngine-Default-Namespace")
195 )
196
197 func getDefaultNamespace(ctx context.Context) string {
198 return internal.IncomingHeaders(ctx).Get(defaultNamespace)
199 }
200
201 func newAddReq(c context.Context, task *Task, queueName string) (*pb.TaskQueueAddRequest, error) {
202 if queueName == "" {
203 queueName = "default"
204 }
205 path := task.Path
206 if path == "" {
207 path = "/_ah/queue/" + queueName
208 }
209 eta := task.ETA
210 if eta.IsZero() {
211 eta = time.Now().Add(task.Delay)
212 } else if task.Delay != 0 {
213 panic("taskqueue: both Delay and ETA are set")
214 }
215 req := &pb.TaskQueueAddRequest{
216 QueueName: []byte(queueName),
217 TaskName: []byte(task.Name),
218 EtaUsec: proto.Int64(eta.UnixNano() / 1e3),
219 }
220 method := task.method()
221 if method == "PULL" {
222 // Pull-based task
223 req.Body = task.Payload
224 req.Mode = pb.TaskQueueMode_PULL.Enum()
225 if task.Tag != "" {
226 req.Tag = []byte(task.Tag)
227 }
228 } else {
229 // HTTP-based task
230 if v, ok := pb.TaskQueueAddRequest_RequestMethod_value[method]; ok {
231 req.Method = pb.TaskQueueAddRequest_RequestMethod(v).Enum()
232 } else {
233 return nil, fmt.Errorf("taskqueue: bad method %q", method)
234 }
235 req.Url = []byte(path)
236 for k, vs := range task.Header {
237 for _, v := range vs {
238 req.Header = append(req.Header, &pb.TaskQueueAddRequest_Header{
239 Key: []byte(k),
240 Value: []byte(v),
241 })
242 }
243 }
244 if method == "POST" || method == "PUT" {
245 req.Body = task.Payload
246 }
247
248 // Namespace headers.
249 if _, ok := task.Header[currentNamespace]; !ok {
250 // Fetch the current namespace of this request.
251 ns := internal.NamespaceFromContext(c)
252 req.Header = append(req.Header, &pb.TaskQueueAddRequest_Header{
253 Key: []byte(currentNamespace),
254 Value: []byte(ns),
255 })
256 }
257 if _, ok := task.Header[defaultNamespace]; !ok {
258 // Fetch the X-AppEngine-Default-Namespace header of this request.
259 if ns := getDefaultNamespace(c); ns != "" {
260 req.Header = append(req.Header, &pb.TaskQueueAddRequest_Header{
261 Key: []byte(defaultNamespace),
262 Value: []byte(ns),
263 })
264 }
265 }
266 }
267
268 if task.RetryOptions != nil {
269 req.RetryParameters = task.RetryOptions.toRetryParameters()
270 }
271
272 return req, nil
273 }
274
275 var alreadyAddedErrors = map[pb.TaskQueueServiceError_ErrorCode]bool{
276 pb.TaskQueueServiceError_TASK_ALREADY_EXISTS: true,
277 pb.TaskQueueServiceError_TOMBSTONED_TASK: true,
278 }
279
280 // Add adds the task to a named queue.
281 // An empty queue name means that the default queue will be used.
282 // Add returns an equivalent Task with defaults filled in, including setting
283 // the task's Name field to the chosen name if the original was empty.
284 func Add(c context.Context, task *Task, queueName string) (*Task, error) {
285 req, err := newAddReq(c, task, queueName)
286 if err != nil {
287 return nil, err
288 }
289 res := &pb.TaskQueueAddResponse{}
290 if err := internal.Call(c, "taskqueue", "Add", req, res); err != nil {
291 apiErr, ok := err.(*internal.APIError)
292 if ok && alreadyAddedErrors[pb.TaskQueueServiceError_ErrorCode(apiErr.Code)] {
293 return nil, ErrTaskAlreadyAdded
294 }
295 return nil, err
296 }
297 resultTask := *task
298 resultTask.Method = task.method()
299 if task.Name == "" {
300 resultTask.Name = string(res.ChosenTaskName)
301 }
302 return &resultTask, nil
303 }
304
305 // AddMulti adds multiple tasks to a named queue.
306 // An empty queue name means that the default queue will be used.
307 // AddMulti returns a slice of equivalent tasks with defaults filled in, including setting
308 // each task's Name field to the chosen name if the original was empty.
309 // If a given task is badly formed or could not be added, an appengine.MultiError is returned.
310 func AddMulti(c context.Context, tasks []*Task, queueName string) ([]*Task, error) {
311 req := &pb.TaskQueueBulkAddRequest{
312 AddRequest: make([]*pb.TaskQueueAddRequest, len(tasks)),
313 }
314 me, any := make(appengine.MultiError, len(tasks)), false
315 for i, t := range tasks {
316 req.AddRequest[i], me[i] = newAddReq(c, t, queueName)
317 any = any || me[i] != nil
318 }
319 if any {
320 return nil, me
321 }
322 res := &pb.TaskQueueBulkAddResponse{}
323 if err := internal.Call(c, "taskqueue", "BulkAdd", req, res); err != nil {
324 return nil, err
325 }
326 if len(res.Taskresult) != len(tasks) {
327 return nil, errors.New("taskqueue: server error")
328 }
329 tasksOut := make([]*Task, len(tasks))
330 for i, tr := range res.Taskresult {
331 tasksOut[i] = new(Task)
332 *tasksOut[i] = *tasks[i]
333 tasksOut[i].Method = tasksOut[i].method()
334 if tasksOut[i].Name == "" {
335 tasksOut[i].Name = string(tr.ChosenTaskName)
336 }
337 if *tr.Result != pb.TaskQueueServiceError_OK {
338 if alreadyAddedErrors[*tr.Result] {
339 me[i] = ErrTaskAlreadyAdded
340 } else {
341 me[i] = &internal.APIError{
342 Service: "taskqueue",
343 Code: int32(*tr.Result),
344 }
345 }
346 any = true
347 }
348 }
349 if any {
350 return tasksOut, me
351 }
352 return tasksOut, nil
353 }
354
355 // Delete deletes a task from a named queue.
356 func Delete(c context.Context, task *Task, queueName string) error {
357 err := DeleteMulti(c, []*Task{task}, queueName)
358 if me, ok := err.(appengine.MultiError); ok {
359 return me[0]
360 }
361 return err
362 }
363
364 // DeleteMulti deletes multiple tasks from a named queue.
365 // If a given task could not be deleted, an appengine.MultiError is returned.
366 // Each task is deleted independently; one may fail to delete while the others
367 // are successfully deleted.
368 func DeleteMulti(c context.Context, tasks []*Task, queueName string) error {
369 taskNames := make([][]byte, len(tasks))
370 for i, t := range tasks {
371 taskNames[i] = []byte(t.Name)
372 }
373 if queueName == "" {
374 queueName = "default"
375 }
376 req := &pb.TaskQueueDeleteRequest{
377 QueueName: []byte(queueName),
378 TaskName: taskNames,
379 }
380 res := &pb.TaskQueueDeleteResponse{}
381 if err := internal.Call(c, "taskqueue", "Delete", req, res); err != nil {
382 return err
383 }
384 if a, b := len(req.TaskName), len(res.Result); a != b {
385 return fmt.Errorf("taskqueue: internal error: requested deletion of %d tasks, got %d results", a, b)
386 }
387 me, any := make(appengine.MultiError, len(res.Result)), false
388 for i, ec := range res.Result {
389 if ec != pb.TaskQueueServiceError_OK {
390 me[i] = &internal.APIError{
391 Service: "taskqueue",
392 Code: int32(ec),
393 }
394 any = true
395 }
396 }
397 if any {
398 return me
399 }
400 return nil
401 }
402
403 func lease(c context.Context, maxTasks int, queueName string, leaseTime int, groupByTag bool, tag []byte) ([]*Task, error) {
404 if queueName == "" {
405 queueName = "default"
406 }
407 req := &pb.TaskQueueQueryAndOwnTasksRequest{
408 QueueName: []byte(queueName),
409 LeaseSeconds: proto.Float64(float64(leaseTime)),
410 MaxTasks: proto.Int64(int64(maxTasks)),
411 GroupByTag: proto.Bool(groupByTag),
412 Tag: tag,
413 }
414 res := &pb.TaskQueueQueryAndOwnTasksResponse{}
415 if err := internal.Call(c, "taskqueue", "QueryAndOwnTasks", req, res); err != nil {
416 return nil, err
417 }
418 tasks := make([]*Task, len(res.Task))
419 for i, t := range res.Task {
420 tasks[i] = &Task{
421 Payload: t.Body,
422 Name: string(t.TaskName),
423 Method: "PULL",
424 ETA: time.Unix(0, *t.EtaUsec*1e3),
425 RetryCount: *t.RetryCount,
426 Tag: string(t.Tag),
427 }
428 }
429 return tasks, nil
430 }
431
432 // Lease leases tasks from a queue.
433 // leaseTime is in seconds.
434 // The number of tasks fetched will be at most maxTasks.
435 func Lease(c context.Context, maxTasks int, queueName string, leaseTime int) ([]*Task, error) {
436 return lease(c, maxTasks, queueName, leaseTime, false, nil)
437 }
438
439 // LeaseByTag leases tasks from a queue, grouped by tag.
440 // If tag is empty, then the returned tasks are grouped by the tag of the task with earliest ETA.
441 // leaseTime is in seconds.
442 // The number of tasks fetched will be at most maxTasks.
443 func LeaseByTag(c context.Context, maxTasks int, queueName string, leaseTime int, tag string) ([]*Task, error) {
444 return lease(c, maxTasks, queueName, leaseTime, true, []byte(tag))
445 }
446
447 // Purge removes all tasks from a queue.
448 func Purge(c context.Context, queueName string) error {
449 if queueName == "" {
450 queueName = "default"
451 }
452 req := &pb.TaskQueuePurgeQueueRequest{
453 QueueName: []byte(queueName),
454 }
455 res := &pb.TaskQueuePurgeQueueResponse{}
456 return internal.Call(c, "taskqueue", "PurgeQueue", req, res)
457 }
458
459 // ModifyLease modifies the lease of a task.
460 // Used to request more processing time, or to abandon processing.
461 // leaseTime is in seconds and must not be negative.
462 func ModifyLease(c context.Context, task *Task, queueName string, leaseTime int) error {
463 if queueName == "" {
464 queueName = "default"
465 }
466 req := &pb.TaskQueueModifyTaskLeaseRequest{
467 QueueName: []byte(queueName),
468 TaskName: []byte(task.Name),
469 EtaUsec: proto.Int64(task.ETA.UnixNano() / 1e3), // Used to verify ownership.
470 LeaseSeconds: proto.Float64(float64(leaseTime)),
471 }
472 res := &pb.TaskQueueModifyTaskLeaseResponse{}
473 if err := internal.Call(c, "taskqueue", "ModifyTaskLease", req, res); err != nil {
474 return err
475 }
476 task.ETA = time.Unix(0, *res.UpdatedEtaUsec*1e3)
477 return nil
478 }
479
480 // QueueStatistics represents statistics about a single task queue.
481 type QueueStatistics struct {
482 Tasks int // may be an approximation
483 OldestETA time.Time // zero if there are no pending tasks
484
485 Executed1Minute int // tasks executed in the last minute
486 InFlight int // tasks executing now
487 EnforcedRate float64 // requests per second
488 }
489
490 // QueueStats retrieves statistics about queues.
491 func QueueStats(c context.Context, queueNames []string) ([]QueueStatistics, error) {
492 req := &pb.TaskQueueFetchQueueStatsRequest{
493 QueueName: make([][]byte, len(queueNames)),
494 }
495 for i, q := range queueNames {
496 if q == "" {
497 q = "default"
498 }
499 req.QueueName[i] = []byte(q)
500 }
501 res := &pb.TaskQueueFetchQueueStatsResponse{}
502 if err := internal.Call(c, "taskqueue", "FetchQueueStats", req, res); err != nil {
503 return nil, err
504 }
505 qs := make([]QueueStatistics, len(res.Queuestats))
506 for i, qsg := range res.Queuestats {
507 qs[i] = QueueStatistics{
508 Tasks: int(*qsg.NumTasks),
509 }
510 if eta := *qsg.OldestEtaUsec; eta > -1 {
511 qs[i].OldestETA = time.Unix(0, eta*1e3)
512 }
513 if si := qsg.ScannerInfo; si != nil {
514 qs[i].Executed1Minute = int(*si.ExecutedLastMinute)
515 qs[i].InFlight = int(si.GetRequestsInFlight())
516 qs[i].EnforcedRate = si.GetEnforcedRate()
517 }
518 }
519 return qs, nil
520 }
521
522 func setTransaction(x *pb.TaskQueueAddRequest, t *dspb.Transaction) {
523 x.Transaction = t
524 }
525
526 func init() {
527 internal.RegisterErrorCodeMap("taskqueue", pb.TaskQueueServiceError_ErrorCode_name)
528
529 // Datastore error codes are shifted by DATASTORE_ERROR when presented through taskqueue.
530 dsCode := int32(pb.TaskQueueServiceError_DATASTORE_ERROR) + int32(dspb.Error_TIMEOUT)
531 internal.RegisterTimeoutErrorCode("taskqueue", dsCode)
532
533 // Transaction registration.
534 internal.RegisterTransactionSetter(setTransaction)
535 internal.RegisterTransactionSetter(func(x *pb.TaskQueueBulkAddRequest, t *dspb.Transaction) {
536 for _, req := range x.AddRequest {
537 setTransaction(req, t)
538 }
539 })
540 }
0 // Copyright 2014 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package taskqueue
5
6 import (
7 "errors"
8 "fmt"
9 "net/http"
10 "reflect"
11 "testing"
12 "time"
13
14 "google.golang.org/appengine/v2"
15 "google.golang.org/appengine/v2/internal"
16 "google.golang.org/appengine/v2/internal/aetesting"
17 pb "google.golang.org/appengine/v2/internal/taskqueue"
18 )
19
20 func TestAddErrors(t *testing.T) {
21 var tests = []struct {
22 err, want error
23 sameErr bool // if true, should return err exactly
24 }{
25 {
26 err: &internal.APIError{
27 Service: "taskqueue",
28 Code: int32(pb.TaskQueueServiceError_TASK_ALREADY_EXISTS),
29 },
30 want: ErrTaskAlreadyAdded,
31 },
32 {
33 err: &internal.APIError{
34 Service: "taskqueue",
35 Code: int32(pb.TaskQueueServiceError_TOMBSTONED_TASK),
36 },
37 want: ErrTaskAlreadyAdded,
38 },
39 {
40 err: &internal.APIError{
41 Service: "taskqueue",
42 Code: int32(pb.TaskQueueServiceError_UNKNOWN_QUEUE),
43 },
44 want: errors.New("not used"),
45 sameErr: true,
46 },
47 }
48 for _, tc := range tests {
49 c := aetesting.FakeSingleContext(t, "taskqueue", "Add", func(req *pb.TaskQueueAddRequest, res *pb.TaskQueueAddResponse) error {
50 // don't fill in any of the response
51 return tc.err
52 })
53 task := &Task{Path: "/worker", Method: "PULL"}
54 _, err := Add(c, task, "a-queue")
55 want := tc.want
56 if tc.sameErr {
57 want = tc.err
58 }
59 if err != want {
60 t.Errorf("Add with tc.err = %v, got %#v, want = %#v", tc.err, err, want)
61 }
62 }
63 }
64
65 func TestAddMulti(t *testing.T) {
66 c := aetesting.FakeSingleContext(t, "taskqueue", "BulkAdd", func(req *pb.TaskQueueBulkAddRequest, res *pb.TaskQueueBulkAddResponse) error {
67 res.Taskresult = []*pb.TaskQueueBulkAddResponse_TaskResult{
68 {
69 Result: pb.TaskQueueServiceError_OK.Enum(),
70 },
71 {
72 Result: pb.TaskQueueServiceError_TASK_ALREADY_EXISTS.Enum(),
73 },
74 {
75 Result: pb.TaskQueueServiceError_TOMBSTONED_TASK.Enum(),
76 },
77 {
78 Result: pb.TaskQueueServiceError_INTERNAL_ERROR.Enum(),
79 },
80 }
81 return nil
82 })
83 tasks := []*Task{
84 {Path: "/worker", Method: "PULL"},
85 {Path: "/worker", Method: "PULL"},
86 {Path: "/worker", Method: "PULL"},
87 {Path: "/worker", Method: "PULL"},
88 }
89 r, err := AddMulti(c, tasks, "a-queue")
90 if len(r) != len(tasks) {
91 t.Fatalf("AddMulti returned %d tasks, want %d", len(r), len(tasks))
92 }
93 want := appengine.MultiError{
94 nil,
95 ErrTaskAlreadyAdded,
96 ErrTaskAlreadyAdded,
97 &internal.APIError{
98 Service: "taskqueue",
99 Code: int32(pb.TaskQueueServiceError_INTERNAL_ERROR),
100 },
101 }
102 if !reflect.DeepEqual(err, want) {
103 t.Errorf("AddMulti got %v, wanted %v", err, want)
104 }
105 }
106
107 func TestAddWithEmptyPath(t *testing.T) {
108 c := aetesting.FakeSingleContext(t, "taskqueue", "Add", func(req *pb.TaskQueueAddRequest, res *pb.TaskQueueAddResponse) error {
109 if got, want := string(req.Url), "/_ah/queue/a-queue"; got != want {
110 return fmt.Errorf("req.Url = %q; want %q", got, want)
111 }
112 return nil
113 })
114 if _, err := Add(c, &Task{}, "a-queue"); err != nil {
115 t.Fatalf("Add: %v", err)
116 }
117 }
118
119 func TestParseRequestHeaders(t *testing.T) {
120 tests := []struct {
121 Header http.Header
122 Want RequestHeaders
123 }{
124 {
125 Header: map[string][]string{
126 "X-Appengine-Queuename": []string{"foo"},
127 "X-Appengine-Taskname": []string{"bar"},
128 "X-Appengine-Taskretrycount": []string{"4294967297"}, // 2^32 + 1
129 "X-Appengine-Taskexecutioncount": []string{"4294967298"}, // 2^32 + 2
130 "X-Appengine-Tasketa": []string{"1500000000"},
131 "X-Appengine-Taskpreviousresponse": []string{"404"},
132 "X-Appengine-Taskretryreason": []string{"baz"},
133 "X-Appengine-Failfast": []string{"yes"},
134 },
135 Want: RequestHeaders{
136 QueueName: "foo",
137 TaskName: "bar",
138 TaskRetryCount: 4294967297,
139 TaskExecutionCount: 4294967298,
140 TaskETA: time.Date(2017, time.July, 14, 2, 40, 0, 0, time.UTC),
141 TaskPreviousResponse: 404,
142 TaskRetryReason: "baz",
143 FailFast: true,
144 },
145 },
146 {
147 Header: map[string][]string{},
148 Want: RequestHeaders{
149 QueueName: "",
150 TaskName: "",
151 TaskRetryCount: 0,
152 TaskExecutionCount: 0,
153 TaskETA: time.Time{},
154 TaskPreviousResponse: 0,
155 TaskRetryReason: "",
156 FailFast: false,
157 },
158 },
159 }
160
161 for idx, test := range tests {
162 got := *ParseRequestHeaders(test.Header)
163 if got.TaskETA.UnixNano() != test.Want.TaskETA.UnixNano() {
164 t.Errorf("%d. ParseRequestHeaders got TaskETA %v, wanted %v", idx, got.TaskETA, test.Want.TaskETA)
165 }
166 got.TaskETA = time.Time{}
167 test.Want.TaskETA = time.Time{}
168 if !reflect.DeepEqual(got, test.Want) {
169 t.Errorf("%d. ParseRequestHeaders got %v, wanted %v", idx, got, test.Want)
170 }
171 }
172 }
0 // Copyright 2013 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package appengine
5
6 import "context"
7
8 // IsTimeoutError reports whether err is a timeout error.
9 func IsTimeoutError(err error) bool {
10 if err == context.DeadlineExceeded {
11 return true
12 }
13 if t, ok := err.(interface {
14 IsTimeout() bool
15 }); ok {
16 return t.IsTimeout()
17 }
18 return false
19 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package urlfetch provides an http.RoundTripper implementation
5 // for fetching URLs via App Engine's urlfetch service.
6 package urlfetch // import "google.golang.org/appengine/v2/urlfetch"
7
8 import (
9 "context"
10 "errors"
11 "fmt"
12 "io"
13 "io/ioutil"
14 "net/http"
15 "net/url"
16 "strconv"
17 "strings"
18 "time"
19
20 "github.com/golang/protobuf/proto"
21
22 "google.golang.org/appengine/v2/internal"
23 pb "google.golang.org/appengine/v2/internal/urlfetch"
24 )
25
26 // Transport is an implementation of http.RoundTripper for
27 // App Engine. Users should generally create an http.Client using
28 // this transport and use the Client rather than using this transport
29 // directly.
30 type Transport struct {
31 Context context.Context
32
33 // Controls whether the application checks the validity of SSL certificates
34 // over HTTPS connections. A value of false (the default) instructs the
35 // application to send a request to the server only if the certificate is
36 // valid and signed by a trusted certificate authority (CA), and also
37 // includes a hostname that matches the certificate. A value of true
38 // instructs the application to perform no certificate validation.
39 AllowInvalidServerCertificate bool
40 }
41
42 // Verify statically that *Transport implements http.RoundTripper.
43 var _ http.RoundTripper = (*Transport)(nil)
44
45 // Client returns an *http.Client using a default urlfetch Transport. This
46 // client will have the default deadline of 5 seconds, and will check the
47 // validity of SSL certificates.
48 //
49 // Any deadline of the provided context will be used for requests through this client;
50 // if the client does not have a deadline then a 5 second default is used.
51 func Client(ctx context.Context) *http.Client {
52 return &http.Client{
53 Transport: &Transport{
54 Context: ctx,
55 },
56 }
57 }
58
59 type bodyReader struct {
60 content []byte
61 truncated bool
62 closed bool
63 }
64
65 // ErrTruncatedBody is the error returned after the final Read() from a
66 // response's Body if the body has been truncated by App Engine's proxy.
67 var ErrTruncatedBody = errors.New("urlfetch: truncated body")
68
69 func statusCodeToText(code int) string {
70 if t := http.StatusText(code); t != "" {
71 return t
72 }
73 return strconv.Itoa(code)
74 }
75
76 func (br *bodyReader) Read(p []byte) (n int, err error) {
77 if br.closed {
78 if br.truncated {
79 return 0, ErrTruncatedBody
80 }
81 return 0, io.EOF
82 }
83 n = copy(p, br.content)
84 if n > 0 {
85 br.content = br.content[n:]
86 return
87 }
88 if br.truncated {
89 br.closed = true
90 return 0, ErrTruncatedBody
91 }
92 return 0, io.EOF
93 }
94
95 func (br *bodyReader) Close() error {
96 br.closed = true
97 br.content = nil
98 return nil
99 }
100
101 // A map of the URL Fetch-accepted methods that take a request body.
102 var methodAcceptsRequestBody = map[string]bool{
103 "POST": true,
104 "PUT": true,
105 "PATCH": true,
106 }
107
108 // urlString returns a valid string given a URL. This function is necessary because
109 // the String method of URL doesn't correctly handle URLs with non-empty Opaque values.
110 // See http://code.google.com/p/go/issues/detail?id=4860.
111 func urlString(u *url.URL) string {
112 if u.Opaque == "" || strings.HasPrefix(u.Opaque, "//") {
113 return u.String()
114 }
115 aux := *u
116 aux.Opaque = "//" + aux.Host + aux.Opaque
117 return aux.String()
118 }
119
120 // RoundTrip issues a single HTTP request and returns its response. Per the
121 // http.RoundTripper interface, RoundTrip only returns an error if there
122 // was an unsupported request or the URL Fetch proxy fails.
123 // Note that HTTP response codes such as 5xx, 403, 404, etc are not
124 // errors as far as the transport is concerned and will be returned
125 // with err set to nil.
126 func (t *Transport) RoundTrip(req *http.Request) (res *http.Response, err error) {
127 methNum, ok := pb.URLFetchRequest_RequestMethod_value[req.Method]
128 if !ok {
129 return nil, fmt.Errorf("urlfetch: unsupported HTTP method %q", req.Method)
130 }
131
132 method := pb.URLFetchRequest_RequestMethod(methNum)
133
134 freq := &pb.URLFetchRequest{
135 Method: &method,
136 Url: proto.String(urlString(req.URL)),
137 FollowRedirects: proto.Bool(false), // http.Client's responsibility
138 MustValidateServerCertificate: proto.Bool(!t.AllowInvalidServerCertificate),
139 }
140 if deadline, ok := t.Context.Deadline(); ok {
141 freq.Deadline = proto.Float64(deadline.Sub(time.Now()).Seconds())
142 }
143
144 for k, vals := range req.Header {
145 for _, val := range vals {
146 freq.Header = append(freq.Header, &pb.URLFetchRequest_Header{
147 Key: proto.String(k),
148 Value: proto.String(val),
149 })
150 }
151 }
152 if methodAcceptsRequestBody[req.Method] && req.Body != nil {
153 // Avoid a []byte copy if req.Body has a Bytes method.
154 switch b := req.Body.(type) {
155 case interface {
156 Bytes() []byte
157 }:
158 freq.Payload = b.Bytes()
159 default:
160 freq.Payload, err = ioutil.ReadAll(req.Body)
161 if err != nil {
162 return nil, err
163 }
164 }
165 }
166
167 fres := &pb.URLFetchResponse{}
168 if err := internal.Call(t.Context, "urlfetch", "Fetch", freq, fres); err != nil {
169 return nil, err
170 }
171
172 res = &http.Response{}
173 res.StatusCode = int(*fres.StatusCode)
174 res.Status = fmt.Sprintf("%d %s", res.StatusCode, statusCodeToText(res.StatusCode))
175 res.Header = make(http.Header)
176 res.Request = req
177
178 // Faked:
179 res.ProtoMajor = 1
180 res.ProtoMinor = 1
181 res.Proto = "HTTP/1.1"
182 res.Close = true
183
184 for _, h := range fres.Header {
185 hkey := http.CanonicalHeaderKey(*h.Key)
186 hval := *h.Value
187 if hkey == "Content-Length" {
188 // Will get filled in below for all but HEAD requests.
189 if req.Method == "HEAD" {
190 res.ContentLength, _ = strconv.ParseInt(hval, 10, 64)
191 }
192 continue
193 }
194 res.Header.Add(hkey, hval)
195 }
196
197 if req.Method != "HEAD" {
198 res.ContentLength = int64(len(fres.Content))
199 }
200
201 truncated := fres.GetContentWasTruncated()
202 res.Body = &bodyReader{content: fres.Content, truncated: truncated}
203 return
204 }
205
206 func init() {
207 internal.RegisterErrorCodeMap("urlfetch", pb.URLFetchServiceError_ErrorCode_name)
208 internal.RegisterTimeoutErrorCode("urlfetch", int32(pb.URLFetchServiceError_DEADLINE_EXCEEDED))
209 }
0 // Copyright 2012 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package user
5
6 import (
7 "context"
8
9 "google.golang.org/appengine/v2/internal"
10 pb "google.golang.org/appengine/v2/internal/user"
11 )
12
13 // CurrentOAuth returns the user associated with the OAuth consumer making this
14 // request. If the OAuth consumer did not make a valid OAuth request, or the
15 // scopes is non-empty and the current user does not have at least one of the
16 // scopes, this method will return an error.
17 func CurrentOAuth(c context.Context, scopes ...string) (*User, error) {
18 req := &pb.GetOAuthUserRequest{}
19 if len(scopes) != 1 || scopes[0] != "" {
20 // The signature for this function used to be CurrentOAuth(Context, string).
21 // Ignore the singular "" scope to preserve existing behavior.
22 req.Scopes = scopes
23 }
24
25 res := &pb.GetOAuthUserResponse{}
26
27 err := internal.Call(c, "user", "GetOAuthUser", req, res)
28 if err != nil {
29 return nil, err
30 }
31 return &User{
32 Email: *res.Email,
33 AuthDomain: *res.AuthDomain,
34 Admin: res.GetIsAdmin(),
35 ID: *res.UserId,
36 ClientID: res.GetClientId(),
37 }, nil
38 }
39
40 // OAuthConsumerKey returns the OAuth consumer key provided with the current
41 // request. This method will return an error if the OAuth request was invalid.
42 func OAuthConsumerKey(c context.Context) (string, error) {
43 req := &pb.CheckOAuthSignatureRequest{}
44 res := &pb.CheckOAuthSignatureResponse{}
45
46 err := internal.Call(c, "user", "CheckOAuthSignature", req, res)
47 if err != nil {
48 return "", err
49 }
50 return *res.OauthConsumerKey, err
51 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 // Package user provides a client for App Engine's user authentication service.
5 package user // import "google.golang.org/appengine/v2/user"
6
7 import (
8 "context"
9 "strings"
10
11 "github.com/golang/protobuf/proto"
12
13 "google.golang.org/appengine/v2/internal"
14 pb "google.golang.org/appengine/v2/internal/user"
15 )
16
17 // User represents a user of the application.
18 type User struct {
19 Email string
20 AuthDomain string
21 Admin bool
22
23 // ID is the unique permanent ID of the user.
24 // It is populated if the Email is associated
25 // with a Google account, or empty otherwise.
26 ID string
27
28 // ClientID is the ID of the pre-registered client so its identity can be verified.
29 // See https://developers.google.com/console/help/#generatingoauth2 for more information.
30 ClientID string
31
32 FederatedIdentity string
33 FederatedProvider string
34 }
35
36 // String returns a displayable name for the user.
37 func (u *User) String() string {
38 if u.AuthDomain != "" && strings.HasSuffix(u.Email, "@"+u.AuthDomain) {
39 return u.Email[:len(u.Email)-len("@"+u.AuthDomain)]
40 }
41 if u.FederatedIdentity != "" {
42 return u.FederatedIdentity
43 }
44 return u.Email
45 }
46
47 // LoginURL returns a URL that, when visited, prompts the user to sign in,
48 // then redirects the user to the URL specified by dest.
49 func LoginURL(c context.Context, dest string) (string, error) {
50 return LoginURLFederated(c, dest, "")
51 }
52
53 // LoginURLFederated is like LoginURL but accepts a user's OpenID identifier.
54 func LoginURLFederated(c context.Context, dest, identity string) (string, error) {
55 req := &pb.CreateLoginURLRequest{
56 DestinationUrl: proto.String(dest),
57 }
58 if identity != "" {
59 req.FederatedIdentity = proto.String(identity)
60 }
61 res := &pb.CreateLoginURLResponse{}
62 if err := internal.Call(c, "user", "CreateLoginURL", req, res); err != nil {
63 return "", err
64 }
65 return *res.LoginUrl, nil
66 }
67
68 // LogoutURL returns a URL that, when visited, signs the user out,
69 // then redirects the user to the URL specified by dest.
70 func LogoutURL(c context.Context, dest string) (string, error) {
71 req := &pb.CreateLogoutURLRequest{
72 DestinationUrl: proto.String(dest),
73 }
74 res := &pb.CreateLogoutURLResponse{}
75 if err := internal.Call(c, "user", "CreateLogoutURL", req, res); err != nil {
76 return "", err
77 }
78 return *res.LogoutUrl, nil
79 }
80
81 func init() {
82 internal.RegisterErrorCodeMap("user", pb.UserServiceError_ErrorCode_name)
83 }
84
85 // Current returns the currently logged-in user,
86 // or nil if the user is not signed in.
87 func Current(c context.Context) *User {
88 h := internal.IncomingHeaders(c)
89 u := &User{
90 Email: h.Get("X-AppEngine-User-Email"),
91 AuthDomain: h.Get("X-AppEngine-Auth-Domain"),
92 ID: h.Get("X-AppEngine-User-Id"),
93 Admin: h.Get("X-AppEngine-User-Is-Admin") == "1",
94 FederatedIdentity: h.Get("X-AppEngine-Federated-Identity"),
95 FederatedProvider: h.Get("X-AppEngine-Federated-Provider"),
96 }
97 if u.Email == "" && u.FederatedIdentity == "" {
98 return nil
99 }
100 return u
101 }
102
103 // IsAdmin returns true if the current user is signed in and
104 // is currently registered as an administrator of the application.
105 func IsAdmin(c context.Context) bool {
106 h := internal.IncomingHeaders(c)
107 return h.Get("X-AppEngine-User-Is-Admin") == "1"
108 }
0 // Copyright 2011 Google Inc. All rights reserved.
1 // Use of this source code is governed by the Apache 2.0
2 // license that can be found in the LICENSE file.
3
4 package user
5
6 import (
7 "fmt"
8 "net/http"
9 "testing"
10
11 "github.com/golang/protobuf/proto"
12
13 "google.golang.org/appengine/v2/internal"
14 "google.golang.org/appengine/v2/internal/aetesting"
15 pb "google.golang.org/appengine/v2/internal/user"
16 )
17
18 func baseReq() *http.Request {
19 return &http.Request{
20 Header: http.Header{},
21 }
22 }
23
24 type basicUserTest struct {
25 nickname, email, authDomain, admin string
26 // expectations
27 isNil, isAdmin bool
28 displayName string
29 }
30
31 var basicUserTests = []basicUserTest{
32 {"", "", "", "0", true, false, ""},
33 {"ken", "ken@example.com", "example.com", "0", false, false, "ken"},
34 {"ken", "ken@example.com", "auth_domain.com", "1", false, true, "ken@example.com"},
35 }
36
37 func TestBasicUserAPI(t *testing.T) {
38 for i, tc := range basicUserTests {
39 req := baseReq()
40 req.Header.Set("X-AppEngine-User-Nickname", tc.nickname)
41 req.Header.Set("X-AppEngine-User-Email", tc.email)
42 req.Header.Set("X-AppEngine-Auth-Domain", tc.authDomain)
43 req.Header.Set("X-AppEngine-User-Is-Admin", tc.admin)
44
45 c := internal.ContextForTesting(req)
46
47 if ga := IsAdmin(c); ga != tc.isAdmin {
48 t.Errorf("test %d: expected IsAdmin(c) = %v, got %v", i, tc.isAdmin, ga)
49 }
50
51 u := Current(c)
52 if tc.isNil {
53 if u != nil {
54 t.Errorf("test %d: expected u == nil, got %+v", i, u)
55 }
56 continue
57 }
58 if u == nil {
59 t.Errorf("test %d: expected u != nil, got nil", i)
60 continue
61 }
62 if u.Email != tc.email {
63 t.Errorf("test %d: expected u.Email = %q, got %q", i, tc.email, u.Email)
64 }
65 if gs := u.String(); gs != tc.displayName {
66 t.Errorf("test %d: expected u.String() = %q, got %q", i, tc.displayName, gs)
67 }
68 if u.Admin != tc.isAdmin {
69 t.Errorf("test %d: expected u.Admin = %v, got %v", i, tc.isAdmin, u.Admin)
70 }
71 }
72 }
73
74 func TestLoginURL(t *testing.T) {
75 expectedQuery := &pb.CreateLoginURLRequest{
76 DestinationUrl: proto.String("/destination"),
77 }
78 const expectedDest = "/redir/dest"
79 c := aetesting.FakeSingleContext(t, "user", "CreateLoginURL", func(req *pb.CreateLoginURLRequest, res *pb.CreateLoginURLResponse) error {
80 if !proto.Equal(req, expectedQuery) {
81 return fmt.Errorf("got %v, want %v", req, expectedQuery)
82 }
83 res.LoginUrl = proto.String(expectedDest)
84 return nil
85 })
86
87 url, err := LoginURL(c, "/destination")
88 if err != nil {
89 t.Fatalf("LoginURL failed: %v", err)
90 }
91 if url != expectedDest {
92 t.Errorf("got %v, want %v", url, expectedDest)
93 }
94 }
95
96 // TODO(dsymonds): Add test for LogoutURL.
66 to and from users of XMPP-compatible services.
77
88 To send a message,
9
910 m := &xmpp.Message{
1011 To: []string{"kaylee@example.com"},
1112 Body: `Hi! How's the carrot?`,
1314 err := m.Send(c)
1415
1516 To receive messages,
17
1618 func init() {
1719 xmpp.Handle(handleChat)
1820 }