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