1// Copyright 2020 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Code generated by protoc-gen-go_gapic. DO NOT EDIT.
16
17package vision
18
19import (
20	"context"
21	"fmt"
22	"math"
23	"net/url"
24	"time"
25
26	"cloud.google.com/go/longrunning"
27	lroauto "cloud.google.com/go/longrunning/autogen"
28	"github.com/golang/protobuf/proto"
29	gax "github.com/googleapis/gax-go/v2"
30	"google.golang.org/api/iterator"
31	"google.golang.org/api/option"
32	gtransport "google.golang.org/api/transport/grpc"
33	visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1"
34	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
35	"google.golang.org/grpc"
36	"google.golang.org/grpc/codes"
37	"google.golang.org/grpc/metadata"
38)
39
40var newProductSearchClientHook clientHook
41
42// ProductSearchCallOptions contains the retry settings for each method of ProductSearchClient.
43type ProductSearchCallOptions struct {
44	CreateProductSet            []gax.CallOption
45	ListProductSets             []gax.CallOption
46	GetProductSet               []gax.CallOption
47	UpdateProductSet            []gax.CallOption
48	DeleteProductSet            []gax.CallOption
49	CreateProduct               []gax.CallOption
50	ListProducts                []gax.CallOption
51	GetProduct                  []gax.CallOption
52	UpdateProduct               []gax.CallOption
53	DeleteProduct               []gax.CallOption
54	CreateReferenceImage        []gax.CallOption
55	DeleteReferenceImage        []gax.CallOption
56	ListReferenceImages         []gax.CallOption
57	GetReferenceImage           []gax.CallOption
58	AddProductToProductSet      []gax.CallOption
59	RemoveProductFromProductSet []gax.CallOption
60	ListProductsInProductSet    []gax.CallOption
61	ImportProductSets           []gax.CallOption
62	PurgeProducts               []gax.CallOption
63}
64
65func defaultProductSearchClientOptions() []option.ClientOption {
66	return []option.ClientOption{
67		option.WithEndpoint("vision.googleapis.com:443"),
68		option.WithGRPCDialOption(grpc.WithDisableServiceConfig()),
69		option.WithScopes(DefaultAuthScopes()...),
70		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
71			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
72	}
73}
74
75func defaultProductSearchCallOptions() *ProductSearchCallOptions {
76	return &ProductSearchCallOptions{
77		CreateProductSet: []gax.CallOption{
78			gax.WithRetry(func() gax.Retryer {
79				return gax.OnCodes([]codes.Code{}, gax.Backoff{
80					Initial:    100 * time.Millisecond,
81					Max:        60000 * time.Millisecond,
82					Multiplier: 1.30,
83				})
84			}),
85		},
86		ListProductSets: []gax.CallOption{
87			gax.WithRetry(func() gax.Retryer {
88				return gax.OnCodes([]codes.Code{
89					codes.DeadlineExceeded,
90					codes.Unavailable,
91				}, gax.Backoff{
92					Initial:    100 * time.Millisecond,
93					Max:        60000 * time.Millisecond,
94					Multiplier: 1.30,
95				})
96			}),
97		},
98		GetProductSet: []gax.CallOption{
99			gax.WithRetry(func() gax.Retryer {
100				return gax.OnCodes([]codes.Code{
101					codes.DeadlineExceeded,
102					codes.Unavailable,
103				}, gax.Backoff{
104					Initial:    100 * time.Millisecond,
105					Max:        60000 * time.Millisecond,
106					Multiplier: 1.30,
107				})
108			}),
109		},
110		UpdateProductSet: []gax.CallOption{
111			gax.WithRetry(func() gax.Retryer {
112				return gax.OnCodes([]codes.Code{
113					codes.DeadlineExceeded,
114					codes.Unavailable,
115				}, gax.Backoff{
116					Initial:    100 * time.Millisecond,
117					Max:        60000 * time.Millisecond,
118					Multiplier: 1.30,
119				})
120			}),
121		},
122		DeleteProductSet: []gax.CallOption{
123			gax.WithRetry(func() gax.Retryer {
124				return gax.OnCodes([]codes.Code{
125					codes.DeadlineExceeded,
126					codes.Unavailable,
127				}, gax.Backoff{
128					Initial:    100 * time.Millisecond,
129					Max:        60000 * time.Millisecond,
130					Multiplier: 1.30,
131				})
132			}),
133		},
134		CreateProduct: []gax.CallOption{
135			gax.WithRetry(func() gax.Retryer {
136				return gax.OnCodes([]codes.Code{}, gax.Backoff{
137					Initial:    100 * time.Millisecond,
138					Max:        60000 * time.Millisecond,
139					Multiplier: 1.30,
140				})
141			}),
142		},
143		ListProducts: []gax.CallOption{
144			gax.WithRetry(func() gax.Retryer {
145				return gax.OnCodes([]codes.Code{
146					codes.DeadlineExceeded,
147					codes.Unavailable,
148				}, gax.Backoff{
149					Initial:    100 * time.Millisecond,
150					Max:        60000 * time.Millisecond,
151					Multiplier: 1.30,
152				})
153			}),
154		},
155		GetProduct: []gax.CallOption{
156			gax.WithRetry(func() gax.Retryer {
157				return gax.OnCodes([]codes.Code{
158					codes.DeadlineExceeded,
159					codes.Unavailable,
160				}, gax.Backoff{
161					Initial:    100 * time.Millisecond,
162					Max:        60000 * time.Millisecond,
163					Multiplier: 1.30,
164				})
165			}),
166		},
167		UpdateProduct: []gax.CallOption{
168			gax.WithRetry(func() gax.Retryer {
169				return gax.OnCodes([]codes.Code{
170					codes.DeadlineExceeded,
171					codes.Unavailable,
172				}, gax.Backoff{
173					Initial:    100 * time.Millisecond,
174					Max:        60000 * time.Millisecond,
175					Multiplier: 1.30,
176				})
177			}),
178		},
179		DeleteProduct: []gax.CallOption{
180			gax.WithRetry(func() gax.Retryer {
181				return gax.OnCodes([]codes.Code{
182					codes.DeadlineExceeded,
183					codes.Unavailable,
184				}, gax.Backoff{
185					Initial:    100 * time.Millisecond,
186					Max:        60000 * time.Millisecond,
187					Multiplier: 1.30,
188				})
189			}),
190		},
191		CreateReferenceImage: []gax.CallOption{
192			gax.WithRetry(func() gax.Retryer {
193				return gax.OnCodes([]codes.Code{}, gax.Backoff{
194					Initial:    100 * time.Millisecond,
195					Max:        60000 * time.Millisecond,
196					Multiplier: 1.30,
197				})
198			}),
199		},
200		DeleteReferenceImage: []gax.CallOption{
201			gax.WithRetry(func() gax.Retryer {
202				return gax.OnCodes([]codes.Code{
203					codes.DeadlineExceeded,
204					codes.Unavailable,
205				}, gax.Backoff{
206					Initial:    100 * time.Millisecond,
207					Max:        60000 * time.Millisecond,
208					Multiplier: 1.30,
209				})
210			}),
211		},
212		ListReferenceImages: []gax.CallOption{
213			gax.WithRetry(func() gax.Retryer {
214				return gax.OnCodes([]codes.Code{
215					codes.DeadlineExceeded,
216					codes.Unavailable,
217				}, gax.Backoff{
218					Initial:    100 * time.Millisecond,
219					Max:        60000 * time.Millisecond,
220					Multiplier: 1.30,
221				})
222			}),
223		},
224		GetReferenceImage: []gax.CallOption{
225			gax.WithRetry(func() gax.Retryer {
226				return gax.OnCodes([]codes.Code{
227					codes.DeadlineExceeded,
228					codes.Unavailable,
229				}, gax.Backoff{
230					Initial:    100 * time.Millisecond,
231					Max:        60000 * time.Millisecond,
232					Multiplier: 1.30,
233				})
234			}),
235		},
236		AddProductToProductSet: []gax.CallOption{
237			gax.WithRetry(func() gax.Retryer {
238				return gax.OnCodes([]codes.Code{
239					codes.DeadlineExceeded,
240					codes.Unavailable,
241				}, gax.Backoff{
242					Initial:    100 * time.Millisecond,
243					Max:        60000 * time.Millisecond,
244					Multiplier: 1.30,
245				})
246			}),
247		},
248		RemoveProductFromProductSet: []gax.CallOption{
249			gax.WithRetry(func() gax.Retryer {
250				return gax.OnCodes([]codes.Code{
251					codes.DeadlineExceeded,
252					codes.Unavailable,
253				}, gax.Backoff{
254					Initial:    100 * time.Millisecond,
255					Max:        60000 * time.Millisecond,
256					Multiplier: 1.30,
257				})
258			}),
259		},
260		ListProductsInProductSet: []gax.CallOption{
261			gax.WithRetry(func() gax.Retryer {
262				return gax.OnCodes([]codes.Code{
263					codes.DeadlineExceeded,
264					codes.Unavailable,
265				}, gax.Backoff{
266					Initial:    100 * time.Millisecond,
267					Max:        60000 * time.Millisecond,
268					Multiplier: 1.30,
269				})
270			}),
271		},
272		ImportProductSets: []gax.CallOption{
273			gax.WithRetry(func() gax.Retryer {
274				return gax.OnCodes([]codes.Code{}, gax.Backoff{
275					Initial:    100 * time.Millisecond,
276					Max:        60000 * time.Millisecond,
277					Multiplier: 1.30,
278				})
279			}),
280		},
281		PurgeProducts: []gax.CallOption{
282			gax.WithRetry(func() gax.Retryer {
283				return gax.OnCodes([]codes.Code{}, gax.Backoff{
284					Initial:    100 * time.Millisecond,
285					Max:        60000 * time.Millisecond,
286					Multiplier: 1.30,
287				})
288			}),
289		},
290	}
291}
292
293// ProductSearchClient is a client for interacting with Cloud Vision API.
294//
295// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
296type ProductSearchClient struct {
297	// Connection pool of gRPC connections to the service.
298	connPool gtransport.ConnPool
299
300	// The gRPC API client.
301	productSearchClient visionpb.ProductSearchClient
302
303	// LROClient is used internally to handle longrunning operations.
304	// It is exposed so that its CallOptions can be modified if required.
305	// Users should not Close this client.
306	LROClient *lroauto.OperationsClient
307
308	// The call options for this service.
309	CallOptions *ProductSearchCallOptions
310
311	// The x-goog-* metadata to be sent with each request.
312	xGoogMetadata metadata.MD
313}
314
315// NewProductSearchClient creates a new product search client.
316//
317// Manages Products and ProductSets of reference images for use in product
318// search. It uses the following resource model:
319//
320//   The API has a collection of ProductSet resources, named
321//   projects/*/locations/*/productSets/*, which acts as a way to put different
322//   products into groups to limit identification.
323//
324// In parallel,
325//
326//   The API has a collection of Product resources, named
327//   projects/*/locations/*/products/*
328//
329//   Each Product has a collection of ReferenceImage resources, named
330//   projects/*/locations/*/products/*/referenceImages/*
331func NewProductSearchClient(ctx context.Context, opts ...option.ClientOption) (*ProductSearchClient, error) {
332	clientOpts := defaultProductSearchClientOptions()
333
334	if newProductSearchClientHook != nil {
335		hookOpts, err := newProductSearchClientHook(ctx, clientHookParams{})
336		if err != nil {
337			return nil, err
338		}
339		clientOpts = append(clientOpts, hookOpts...)
340	}
341
342	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
343	if err != nil {
344		return nil, err
345	}
346	c := &ProductSearchClient{
347		connPool:    connPool,
348		CallOptions: defaultProductSearchCallOptions(),
349
350		productSearchClient: visionpb.NewProductSearchClient(connPool),
351	}
352	c.setGoogleClientInfo()
353
354	c.LROClient, err = lroauto.NewOperationsClient(ctx, gtransport.WithConnPool(connPool))
355	if err != nil {
356		// This error "should not happen", since we are just reusing old connection pool
357		// and never actually need to dial.
358		// If this does happen, we could leak connp. However, we cannot close conn:
359		// If the user invoked the constructor with option.WithGRPCConn,
360		// we would close a connection that's still in use.
361		// TODO: investigate error conditions.
362		return nil, err
363	}
364	return c, nil
365}
366
367// Connection returns a connection to the API service.
368//
369// Deprecated.
370func (c *ProductSearchClient) Connection() *grpc.ClientConn {
371	return c.connPool.Conn()
372}
373
374// Close closes the connection to the API service. The user should invoke this when
375// the client is no longer required.
376func (c *ProductSearchClient) Close() error {
377	return c.connPool.Close()
378}
379
380// setGoogleClientInfo sets the name and version of the application in
381// the `x-goog-api-client` header passed on each request. Intended for
382// use by Google-written clients.
383func (c *ProductSearchClient) setGoogleClientInfo(keyval ...string) {
384	kv := append([]string{"gl-go", versionGo()}, keyval...)
385	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version)
386	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
387}
388
389// CreateProductSet creates and returns a new ProductSet resource.
390//
391// Possible errors:
392//
393//   Returns INVALID_ARGUMENT if display_name is missing, or is longer than
394//   4096 characters.
395func (c *ProductSearchClient) CreateProductSet(ctx context.Context, req *visionpb.CreateProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) {
396	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
397	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
398	opts = append(c.CallOptions.CreateProductSet[0:len(c.CallOptions.CreateProductSet):len(c.CallOptions.CreateProductSet)], opts...)
399	var resp *visionpb.ProductSet
400	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
401		var err error
402		resp, err = c.productSearchClient.CreateProductSet(ctx, req, settings.GRPC...)
403		return err
404	}, opts...)
405	if err != nil {
406		return nil, err
407	}
408	return resp, nil
409}
410
411// ListProductSets lists ProductSets in an unspecified order.
412//
413// Possible errors:
414//
415//   Returns INVALID_ARGUMENT if page_size is greater than 100, or less
416//   than 1.
417func (c *ProductSearchClient) ListProductSets(ctx context.Context, req *visionpb.ListProductSetsRequest, opts ...gax.CallOption) *ProductSetIterator {
418	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
419	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
420	opts = append(c.CallOptions.ListProductSets[0:len(c.CallOptions.ListProductSets):len(c.CallOptions.ListProductSets)], opts...)
421	it := &ProductSetIterator{}
422	req = proto.Clone(req).(*visionpb.ListProductSetsRequest)
423	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.ProductSet, string, error) {
424		var resp *visionpb.ListProductSetsResponse
425		req.PageToken = pageToken
426		if pageSize > math.MaxInt32 {
427			req.PageSize = math.MaxInt32
428		} else {
429			req.PageSize = int32(pageSize)
430		}
431		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
432			var err error
433			resp, err = c.productSearchClient.ListProductSets(ctx, req, settings.GRPC...)
434			return err
435		}, opts...)
436		if err != nil {
437			return nil, "", err
438		}
439
440		it.Response = resp
441		return resp.ProductSets, resp.NextPageToken, nil
442	}
443	fetch := func(pageSize int, pageToken string) (string, error) {
444		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
445		if err != nil {
446			return "", err
447		}
448		it.items = append(it.items, items...)
449		return nextPageToken, nil
450	}
451	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
452	it.pageInfo.MaxSize = int(req.PageSize)
453	it.pageInfo.Token = req.PageToken
454	return it
455}
456
457// GetProductSet gets information associated with a ProductSet.
458//
459// Possible errors:
460//
461//   Returns NOT_FOUND if the ProductSet does not exist.
462func (c *ProductSearchClient) GetProductSet(ctx context.Context, req *visionpb.GetProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) {
463	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
464	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
465	opts = append(c.CallOptions.GetProductSet[0:len(c.CallOptions.GetProductSet):len(c.CallOptions.GetProductSet)], opts...)
466	var resp *visionpb.ProductSet
467	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
468		var err error
469		resp, err = c.productSearchClient.GetProductSet(ctx, req, settings.GRPC...)
470		return err
471	}, opts...)
472	if err != nil {
473		return nil, err
474	}
475	return resp, nil
476}
477
478// UpdateProductSet makes changes to a ProductSet resource.
479// Only display_name can be updated currently.
480//
481// Possible errors:
482//
483//   Returns NOT_FOUND if the ProductSet does not exist.
484//
485//   Returns INVALID_ARGUMENT if display_name is present in update_mask but
486//   missing from the request or longer than 4096 characters.
487func (c *ProductSearchClient) UpdateProductSet(ctx context.Context, req *visionpb.UpdateProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) {
488	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "product_set.name", url.QueryEscape(req.GetProductSet().GetName())))
489	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
490	opts = append(c.CallOptions.UpdateProductSet[0:len(c.CallOptions.UpdateProductSet):len(c.CallOptions.UpdateProductSet)], opts...)
491	var resp *visionpb.ProductSet
492	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
493		var err error
494		resp, err = c.productSearchClient.UpdateProductSet(ctx, req, settings.GRPC...)
495		return err
496	}, opts...)
497	if err != nil {
498		return nil, err
499	}
500	return resp, nil
501}
502
503// DeleteProductSet permanently deletes a ProductSet. Products and ReferenceImages in the
504// ProductSet are not deleted.
505//
506// The actual image files are not deleted from Google Cloud Storage.
507func (c *ProductSearchClient) DeleteProductSet(ctx context.Context, req *visionpb.DeleteProductSetRequest, opts ...gax.CallOption) error {
508	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
509	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
510	opts = append(c.CallOptions.DeleteProductSet[0:len(c.CallOptions.DeleteProductSet):len(c.CallOptions.DeleteProductSet)], opts...)
511	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
512		var err error
513		_, err = c.productSearchClient.DeleteProductSet(ctx, req, settings.GRPC...)
514		return err
515	}, opts...)
516	return err
517}
518
519// CreateProduct creates and returns a new product resource.
520//
521// Possible errors:
522//
523//   Returns INVALID_ARGUMENT if display_name is missing or longer than 4096
524//   characters.
525//
526//   Returns INVALID_ARGUMENT if description is longer than 4096 characters.
527//
528//   Returns INVALID_ARGUMENT if product_category is missing or invalid.
529func (c *ProductSearchClient) CreateProduct(ctx context.Context, req *visionpb.CreateProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) {
530	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
531	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
532	opts = append(c.CallOptions.CreateProduct[0:len(c.CallOptions.CreateProduct):len(c.CallOptions.CreateProduct)], opts...)
533	var resp *visionpb.Product
534	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
535		var err error
536		resp, err = c.productSearchClient.CreateProduct(ctx, req, settings.GRPC...)
537		return err
538	}, opts...)
539	if err != nil {
540		return nil, err
541	}
542	return resp, nil
543}
544
545// ListProducts lists products in an unspecified order.
546//
547// Possible errors:
548//
549//   Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
550func (c *ProductSearchClient) ListProducts(ctx context.Context, req *visionpb.ListProductsRequest, opts ...gax.CallOption) *ProductIterator {
551	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
552	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
553	opts = append(c.CallOptions.ListProducts[0:len(c.CallOptions.ListProducts):len(c.CallOptions.ListProducts)], opts...)
554	it := &ProductIterator{}
555	req = proto.Clone(req).(*visionpb.ListProductsRequest)
556	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.Product, string, error) {
557		var resp *visionpb.ListProductsResponse
558		req.PageToken = pageToken
559		if pageSize > math.MaxInt32 {
560			req.PageSize = math.MaxInt32
561		} else {
562			req.PageSize = int32(pageSize)
563		}
564		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
565			var err error
566			resp, err = c.productSearchClient.ListProducts(ctx, req, settings.GRPC...)
567			return err
568		}, opts...)
569		if err != nil {
570			return nil, "", err
571		}
572
573		it.Response = resp
574		return resp.Products, resp.NextPageToken, nil
575	}
576	fetch := func(pageSize int, pageToken string) (string, error) {
577		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
578		if err != nil {
579			return "", err
580		}
581		it.items = append(it.items, items...)
582		return nextPageToken, nil
583	}
584	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
585	it.pageInfo.MaxSize = int(req.PageSize)
586	it.pageInfo.Token = req.PageToken
587	return it
588}
589
590// GetProduct gets information associated with a Product.
591//
592// Possible errors:
593//
594//   Returns NOT_FOUND if the Product does not exist.
595func (c *ProductSearchClient) GetProduct(ctx context.Context, req *visionpb.GetProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) {
596	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
597	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
598	opts = append(c.CallOptions.GetProduct[0:len(c.CallOptions.GetProduct):len(c.CallOptions.GetProduct)], opts...)
599	var resp *visionpb.Product
600	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
601		var err error
602		resp, err = c.productSearchClient.GetProduct(ctx, req, settings.GRPC...)
603		return err
604	}, opts...)
605	if err != nil {
606		return nil, err
607	}
608	return resp, nil
609}
610
611// UpdateProduct makes changes to a Product resource.
612// Only the display_name, description, and labels fields can be updated
613// right now.
614//
615// If labels are updated, the change will not be reflected in queries until
616// the next index time.
617//
618// Possible errors:
619//
620//   Returns NOT_FOUND if the Product does not exist.
621//
622//   Returns INVALID_ARGUMENT if display_name is present in update_mask but is
623//   missing from the request or longer than 4096 characters.
624//
625//   Returns INVALID_ARGUMENT if description is present in update_mask but is
626//   longer than 4096 characters.
627//
628//   Returns INVALID_ARGUMENT if product_category is present in update_mask.
629func (c *ProductSearchClient) UpdateProduct(ctx context.Context, req *visionpb.UpdateProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) {
630	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "product.name", url.QueryEscape(req.GetProduct().GetName())))
631	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
632	opts = append(c.CallOptions.UpdateProduct[0:len(c.CallOptions.UpdateProduct):len(c.CallOptions.UpdateProduct)], opts...)
633	var resp *visionpb.Product
634	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
635		var err error
636		resp, err = c.productSearchClient.UpdateProduct(ctx, req, settings.GRPC...)
637		return err
638	}, opts...)
639	if err != nil {
640		return nil, err
641	}
642	return resp, nil
643}
644
645// DeleteProduct permanently deletes a product and its reference images.
646//
647// Metadata of the product and all its images will be deleted right away, but
648// search queries against ProductSets containing the product may still work
649// until all related caches are refreshed.
650func (c *ProductSearchClient) DeleteProduct(ctx context.Context, req *visionpb.DeleteProductRequest, opts ...gax.CallOption) error {
651	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
652	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
653	opts = append(c.CallOptions.DeleteProduct[0:len(c.CallOptions.DeleteProduct):len(c.CallOptions.DeleteProduct)], opts...)
654	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
655		var err error
656		_, err = c.productSearchClient.DeleteProduct(ctx, req, settings.GRPC...)
657		return err
658	}, opts...)
659	return err
660}
661
662// CreateReferenceImage creates and returns a new ReferenceImage resource.
663//
664// The bounding_poly field is optional. If bounding_poly is not specified,
665// the system will try to detect regions of interest in the image that are
666// compatible with the product_category on the parent product. If it is
667// specified, detection is ALWAYS skipped. The system converts polygons into
668// non-rotated rectangles.
669//
670// Note that the pipeline will resize the image if the image resolution is too
671// large to process (above 50MP).
672//
673// Possible errors:
674//
675//   Returns INVALID_ARGUMENT if the image_uri is missing or longer than 4096
676//   characters.
677//
678//   Returns INVALID_ARGUMENT if the product does not exist.
679//
680//   Returns INVALID_ARGUMENT if bounding_poly is not provided, and nothing
681//   compatible with the parent product’s product_category is detected.
682//
683//   Returns INVALID_ARGUMENT if bounding_poly contains more than 10 polygons.
684func (c *ProductSearchClient) CreateReferenceImage(ctx context.Context, req *visionpb.CreateReferenceImageRequest, opts ...gax.CallOption) (*visionpb.ReferenceImage, error) {
685	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
686	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
687	opts = append(c.CallOptions.CreateReferenceImage[0:len(c.CallOptions.CreateReferenceImage):len(c.CallOptions.CreateReferenceImage)], opts...)
688	var resp *visionpb.ReferenceImage
689	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
690		var err error
691		resp, err = c.productSearchClient.CreateReferenceImage(ctx, req, settings.GRPC...)
692		return err
693	}, opts...)
694	if err != nil {
695		return nil, err
696	}
697	return resp, nil
698}
699
700// DeleteReferenceImage permanently deletes a reference image.
701//
702// The image metadata will be deleted right away, but search queries
703// against ProductSets containing the image may still work until all related
704// caches are refreshed.
705//
706// The actual image files are not deleted from Google Cloud Storage.
707func (c *ProductSearchClient) DeleteReferenceImage(ctx context.Context, req *visionpb.DeleteReferenceImageRequest, opts ...gax.CallOption) error {
708	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
709	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
710	opts = append(c.CallOptions.DeleteReferenceImage[0:len(c.CallOptions.DeleteReferenceImage):len(c.CallOptions.DeleteReferenceImage)], opts...)
711	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
712		var err error
713		_, err = c.productSearchClient.DeleteReferenceImage(ctx, req, settings.GRPC...)
714		return err
715	}, opts...)
716	return err
717}
718
719// ListReferenceImages lists reference images.
720//
721// Possible errors:
722//
723//   Returns NOT_FOUND if the parent product does not exist.
724//
725//   Returns INVALID_ARGUMENT if the page_size is greater than 100, or less
726//   than 1.
727func (c *ProductSearchClient) ListReferenceImages(ctx context.Context, req *visionpb.ListReferenceImagesRequest, opts ...gax.CallOption) *ReferenceImageIterator {
728	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
729	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
730	opts = append(c.CallOptions.ListReferenceImages[0:len(c.CallOptions.ListReferenceImages):len(c.CallOptions.ListReferenceImages)], opts...)
731	it := &ReferenceImageIterator{}
732	req = proto.Clone(req).(*visionpb.ListReferenceImagesRequest)
733	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.ReferenceImage, string, error) {
734		var resp *visionpb.ListReferenceImagesResponse
735		req.PageToken = pageToken
736		if pageSize > math.MaxInt32 {
737			req.PageSize = math.MaxInt32
738		} else {
739			req.PageSize = int32(pageSize)
740		}
741		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
742			var err error
743			resp, err = c.productSearchClient.ListReferenceImages(ctx, req, settings.GRPC...)
744			return err
745		}, opts...)
746		if err != nil {
747			return nil, "", err
748		}
749
750		it.Response = resp
751		return resp.ReferenceImages, resp.NextPageToken, nil
752	}
753	fetch := func(pageSize int, pageToken string) (string, error) {
754		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
755		if err != nil {
756			return "", err
757		}
758		it.items = append(it.items, items...)
759		return nextPageToken, nil
760	}
761	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
762	it.pageInfo.MaxSize = int(req.PageSize)
763	it.pageInfo.Token = req.PageToken
764	return it
765}
766
767// GetReferenceImage gets information associated with a ReferenceImage.
768//
769// Possible errors:
770//
771//   Returns NOT_FOUND if the specified image does not exist.
772func (c *ProductSearchClient) GetReferenceImage(ctx context.Context, req *visionpb.GetReferenceImageRequest, opts ...gax.CallOption) (*visionpb.ReferenceImage, error) {
773	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
774	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
775	opts = append(c.CallOptions.GetReferenceImage[0:len(c.CallOptions.GetReferenceImage):len(c.CallOptions.GetReferenceImage)], opts...)
776	var resp *visionpb.ReferenceImage
777	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
778		var err error
779		resp, err = c.productSearchClient.GetReferenceImage(ctx, req, settings.GRPC...)
780		return err
781	}, opts...)
782	if err != nil {
783		return nil, err
784	}
785	return resp, nil
786}
787
788// AddProductToProductSet adds a Product to the specified ProductSet. If the Product is already
789// present, no change is made.
790//
791// One Product can be added to at most 100 ProductSets.
792//
793// Possible errors:
794//
795//   Returns NOT_FOUND if the Product or the ProductSet doesn’t exist.
796func (c *ProductSearchClient) AddProductToProductSet(ctx context.Context, req *visionpb.AddProductToProductSetRequest, opts ...gax.CallOption) error {
797	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
798	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
799	opts = append(c.CallOptions.AddProductToProductSet[0:len(c.CallOptions.AddProductToProductSet):len(c.CallOptions.AddProductToProductSet)], opts...)
800	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
801		var err error
802		_, err = c.productSearchClient.AddProductToProductSet(ctx, req, settings.GRPC...)
803		return err
804	}, opts...)
805	return err
806}
807
808// RemoveProductFromProductSet removes a Product from the specified ProductSet.
809func (c *ProductSearchClient) RemoveProductFromProductSet(ctx context.Context, req *visionpb.RemoveProductFromProductSetRequest, opts ...gax.CallOption) error {
810	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
811	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
812	opts = append(c.CallOptions.RemoveProductFromProductSet[0:len(c.CallOptions.RemoveProductFromProductSet):len(c.CallOptions.RemoveProductFromProductSet)], opts...)
813	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
814		var err error
815		_, err = c.productSearchClient.RemoveProductFromProductSet(ctx, req, settings.GRPC...)
816		return err
817	}, opts...)
818	return err
819}
820
821// ListProductsInProductSet lists the Products in a ProductSet, in an unspecified order. If the
822// ProductSet does not exist, the products field of the response will be
823// empty.
824//
825// Possible errors:
826//
827//   Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
828func (c *ProductSearchClient) ListProductsInProductSet(ctx context.Context, req *visionpb.ListProductsInProductSetRequest, opts ...gax.CallOption) *ProductIterator {
829	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
830	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
831	opts = append(c.CallOptions.ListProductsInProductSet[0:len(c.CallOptions.ListProductsInProductSet):len(c.CallOptions.ListProductsInProductSet)], opts...)
832	it := &ProductIterator{}
833	req = proto.Clone(req).(*visionpb.ListProductsInProductSetRequest)
834	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.Product, string, error) {
835		var resp *visionpb.ListProductsInProductSetResponse
836		req.PageToken = pageToken
837		if pageSize > math.MaxInt32 {
838			req.PageSize = math.MaxInt32
839		} else {
840			req.PageSize = int32(pageSize)
841		}
842		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
843			var err error
844			resp, err = c.productSearchClient.ListProductsInProductSet(ctx, req, settings.GRPC...)
845			return err
846		}, opts...)
847		if err != nil {
848			return nil, "", err
849		}
850
851		it.Response = resp
852		return resp.Products, resp.NextPageToken, nil
853	}
854	fetch := func(pageSize int, pageToken string) (string, error) {
855		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
856		if err != nil {
857			return "", err
858		}
859		it.items = append(it.items, items...)
860		return nextPageToken, nil
861	}
862	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
863	it.pageInfo.MaxSize = int(req.PageSize)
864	it.pageInfo.Token = req.PageToken
865	return it
866}
867
868// ImportProductSets asynchronous API that imports a list of reference images to specified
869// product sets based on a list of image information.
870//
871// The google.longrunning.Operation API can be used to keep track of the
872// progress and results of the request.
873// Operation.metadata contains BatchOperationMetadata. (progress)
874// Operation.response contains ImportProductSetsResponse. (results)
875//
876// The input source of this method is a csv file on Google Cloud Storage.
877// For the format of the csv file please see
878// ImportProductSetsGcsSource.csv_file_uri.
879func (c *ProductSearchClient) ImportProductSets(ctx context.Context, req *visionpb.ImportProductSetsRequest, opts ...gax.CallOption) (*ImportProductSetsOperation, error) {
880	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
881	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
882	opts = append(c.CallOptions.ImportProductSets[0:len(c.CallOptions.ImportProductSets):len(c.CallOptions.ImportProductSets)], opts...)
883	var resp *longrunningpb.Operation
884	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
885		var err error
886		resp, err = c.productSearchClient.ImportProductSets(ctx, req, settings.GRPC...)
887		return err
888	}, opts...)
889	if err != nil {
890		return nil, err
891	}
892	return &ImportProductSetsOperation{
893		lro: longrunning.InternalNewOperation(c.LROClient, resp),
894	}, nil
895}
896
897// PurgeProducts asynchronous API to delete all Products in a ProductSet or all Products
898// that are in no ProductSet.
899//
900// If a Product is a member of the specified ProductSet in addition to other
901// ProductSets, the Product will still be deleted.
902//
903// It is recommended to not delete the specified ProductSet until after this
904// operation has completed. It is also recommended to not add any of the
905// Products involved in the batch delete to a new ProductSet while this
906// operation is running because those Products may still end up deleted.
907//
908// It’s not possible to undo the PurgeProducts operation. Therefore, it is
909// recommended to keep the csv files used in ImportProductSets (if that was
910// how you originally built the Product Set) before starting PurgeProducts, in
911// case you need to re-import the data after deletion.
912//
913// If the plan is to purge all of the Products from a ProductSet and then
914// re-use the empty ProductSet to re-import new Products into the empty
915// ProductSet, you must wait until the PurgeProducts operation has finished
916// for that ProductSet.
917//
918// The google.longrunning.Operation API can be used to keep track of the
919// progress and results of the request.
920// Operation.metadata contains BatchOperationMetadata. (progress)
921func (c *ProductSearchClient) PurgeProducts(ctx context.Context, req *visionpb.PurgeProductsRequest, opts ...gax.CallOption) (*PurgeProductsOperation, error) {
922	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
923	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
924	opts = append(c.CallOptions.PurgeProducts[0:len(c.CallOptions.PurgeProducts):len(c.CallOptions.PurgeProducts)], opts...)
925	var resp *longrunningpb.Operation
926	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
927		var err error
928		resp, err = c.productSearchClient.PurgeProducts(ctx, req, settings.GRPC...)
929		return err
930	}, opts...)
931	if err != nil {
932		return nil, err
933	}
934	return &PurgeProductsOperation{
935		lro: longrunning.InternalNewOperation(c.LROClient, resp),
936	}, nil
937}
938
939// ImportProductSetsOperation manages a long-running operation from ImportProductSets.
940type ImportProductSetsOperation struct {
941	lro *longrunning.Operation
942}
943
944// ImportProductSetsOperation returns a new ImportProductSetsOperation from a given name.
945// The name must be that of a previously created ImportProductSetsOperation, possibly from a different process.
946func (c *ProductSearchClient) ImportProductSetsOperation(name string) *ImportProductSetsOperation {
947	return &ImportProductSetsOperation{
948		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
949	}
950}
951
952// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
953//
954// See documentation of Poll for error-handling information.
955func (op *ImportProductSetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*visionpb.ImportProductSetsResponse, error) {
956	var resp visionpb.ImportProductSetsResponse
957	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
958		return nil, err
959	}
960	return &resp, nil
961}
962
963// Poll fetches the latest state of the long-running operation.
964//
965// Poll also fetches the latest metadata, which can be retrieved by Metadata.
966//
967// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
968// the operation has completed with failure, the error is returned and op.Done will return true.
969// If Poll succeeds and the operation has completed successfully,
970// op.Done will return true, and the response of the operation is returned.
971// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
972func (op *ImportProductSetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*visionpb.ImportProductSetsResponse, error) {
973	var resp visionpb.ImportProductSetsResponse
974	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
975		return nil, err
976	}
977	if !op.Done() {
978		return nil, nil
979	}
980	return &resp, nil
981}
982
983// Metadata returns metadata associated with the long-running operation.
984// Metadata itself does not contact the server, but Poll does.
985// To get the latest metadata, call this method after a successful call to Poll.
986// If the metadata is not available, the returned metadata and error are both nil.
987func (op *ImportProductSetsOperation) Metadata() (*visionpb.BatchOperationMetadata, error) {
988	var meta visionpb.BatchOperationMetadata
989	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
990		return nil, nil
991	} else if err != nil {
992		return nil, err
993	}
994	return &meta, nil
995}
996
997// Done reports whether the long-running operation has completed.
998func (op *ImportProductSetsOperation) Done() bool {
999	return op.lro.Done()
1000}
1001
1002// Name returns the name of the long-running operation.
1003// The name is assigned by the server and is unique within the service from which the operation is created.
1004func (op *ImportProductSetsOperation) Name() string {
1005	return op.lro.Name()
1006}
1007
1008// PurgeProductsOperation manages a long-running operation from PurgeProducts.
1009type PurgeProductsOperation struct {
1010	lro *longrunning.Operation
1011}
1012
1013// PurgeProductsOperation returns a new PurgeProductsOperation from a given name.
1014// The name must be that of a previously created PurgeProductsOperation, possibly from a different process.
1015func (c *ProductSearchClient) PurgeProductsOperation(name string) *PurgeProductsOperation {
1016	return &PurgeProductsOperation{
1017		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
1018	}
1019}
1020
1021// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
1022//
1023// See documentation of Poll for error-handling information.
1024func (op *PurgeProductsOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
1025	return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...)
1026}
1027
1028// Poll fetches the latest state of the long-running operation.
1029//
1030// Poll also fetches the latest metadata, which can be retrieved by Metadata.
1031//
1032// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
1033// the operation has completed with failure, the error is returned and op.Done will return true.
1034// If Poll succeeds and the operation has completed successfully,
1035// op.Done will return true, and the response of the operation is returned.
1036// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
1037func (op *PurgeProductsOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
1038	return op.lro.Poll(ctx, nil, opts...)
1039}
1040
1041// Metadata returns metadata associated with the long-running operation.
1042// Metadata itself does not contact the server, but Poll does.
1043// To get the latest metadata, call this method after a successful call to Poll.
1044// If the metadata is not available, the returned metadata and error are both nil.
1045func (op *PurgeProductsOperation) Metadata() (*visionpb.BatchOperationMetadata, error) {
1046	var meta visionpb.BatchOperationMetadata
1047	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
1048		return nil, nil
1049	} else if err != nil {
1050		return nil, err
1051	}
1052	return &meta, nil
1053}
1054
1055// Done reports whether the long-running operation has completed.
1056func (op *PurgeProductsOperation) Done() bool {
1057	return op.lro.Done()
1058}
1059
1060// Name returns the name of the long-running operation.
1061// The name is assigned by the server and is unique within the service from which the operation is created.
1062func (op *PurgeProductsOperation) Name() string {
1063	return op.lro.Name()
1064}
1065
1066// ProductIterator manages a stream of *visionpb.Product.
1067type ProductIterator struct {
1068	items    []*visionpb.Product
1069	pageInfo *iterator.PageInfo
1070	nextFunc func() error
1071
1072	// Response is the raw response for the current page.
1073	// It must be cast to the RPC response type.
1074	// Calling Next() or InternalFetch() updates this value.
1075	Response interface{}
1076
1077	// InternalFetch is for use by the Google Cloud Libraries only.
1078	// It is not part of the stable interface of this package.
1079	//
1080	// InternalFetch returns results from a single call to the underlying RPC.
1081	// The number of results is no greater than pageSize.
1082	// If there are no more results, nextPageToken is empty and err is nil.
1083	InternalFetch func(pageSize int, pageToken string) (results []*visionpb.Product, nextPageToken string, err error)
1084}
1085
1086// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
1087func (it *ProductIterator) PageInfo() *iterator.PageInfo {
1088	return it.pageInfo
1089}
1090
1091// Next returns the next result. Its second return value is iterator.Done if there are no more
1092// results. Once Next returns Done, all subsequent calls will return Done.
1093func (it *ProductIterator) Next() (*visionpb.Product, error) {
1094	var item *visionpb.Product
1095	if err := it.nextFunc(); err != nil {
1096		return item, err
1097	}
1098	item = it.items[0]
1099	it.items = it.items[1:]
1100	return item, nil
1101}
1102
1103func (it *ProductIterator) bufLen() int {
1104	return len(it.items)
1105}
1106
1107func (it *ProductIterator) takeBuf() interface{} {
1108	b := it.items
1109	it.items = nil
1110	return b
1111}
1112
1113// ProductSetIterator manages a stream of *visionpb.ProductSet.
1114type ProductSetIterator struct {
1115	items    []*visionpb.ProductSet
1116	pageInfo *iterator.PageInfo
1117	nextFunc func() error
1118
1119	// Response is the raw response for the current page.
1120	// It must be cast to the RPC response type.
1121	// Calling Next() or InternalFetch() updates this value.
1122	Response interface{}
1123
1124	// InternalFetch is for use by the Google Cloud Libraries only.
1125	// It is not part of the stable interface of this package.
1126	//
1127	// InternalFetch returns results from a single call to the underlying RPC.
1128	// The number of results is no greater than pageSize.
1129	// If there are no more results, nextPageToken is empty and err is nil.
1130	InternalFetch func(pageSize int, pageToken string) (results []*visionpb.ProductSet, nextPageToken string, err error)
1131}
1132
1133// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
1134func (it *ProductSetIterator) PageInfo() *iterator.PageInfo {
1135	return it.pageInfo
1136}
1137
1138// Next returns the next result. Its second return value is iterator.Done if there are no more
1139// results. Once Next returns Done, all subsequent calls will return Done.
1140func (it *ProductSetIterator) Next() (*visionpb.ProductSet, error) {
1141	var item *visionpb.ProductSet
1142	if err := it.nextFunc(); err != nil {
1143		return item, err
1144	}
1145	item = it.items[0]
1146	it.items = it.items[1:]
1147	return item, nil
1148}
1149
1150func (it *ProductSetIterator) bufLen() int {
1151	return len(it.items)
1152}
1153
1154func (it *ProductSetIterator) takeBuf() interface{} {
1155	b := it.items
1156	it.items = nil
1157	return b
1158}
1159
1160// ReferenceImageIterator manages a stream of *visionpb.ReferenceImage.
1161type ReferenceImageIterator struct {
1162	items    []*visionpb.ReferenceImage
1163	pageInfo *iterator.PageInfo
1164	nextFunc func() error
1165
1166	// Response is the raw response for the current page.
1167	// It must be cast to the RPC response type.
1168	// Calling Next() or InternalFetch() updates this value.
1169	Response interface{}
1170
1171	// InternalFetch is for use by the Google Cloud Libraries only.
1172	// It is not part of the stable interface of this package.
1173	//
1174	// InternalFetch returns results from a single call to the underlying RPC.
1175	// The number of results is no greater than pageSize.
1176	// If there are no more results, nextPageToken is empty and err is nil.
1177	InternalFetch func(pageSize int, pageToken string) (results []*visionpb.ReferenceImage, nextPageToken string, err error)
1178}
1179
1180// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
1181func (it *ReferenceImageIterator) PageInfo() *iterator.PageInfo {
1182	return it.pageInfo
1183}
1184
1185// Next returns the next result. Its second return value is iterator.Done if there are no more
1186// results. Once Next returns Done, all subsequent calls will return Done.
1187func (it *ReferenceImageIterator) Next() (*visionpb.ReferenceImage, error) {
1188	var item *visionpb.ReferenceImage
1189	if err := it.nextFunc(); err != nil {
1190		return item, err
1191	}
1192	item = it.items[0]
1193	it.items = it.items[1:]
1194	return item, nil
1195}
1196
1197func (it *ReferenceImageIterator) bufLen() int {
1198	return len(it.items)
1199}
1200
1201func (it *ReferenceImageIterator) takeBuf() interface{} {
1202	b := it.items
1203	it.items = nil
1204	return b
1205}
1206