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