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