// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package cloudprivatecatalog provides access to the Cloud Private Catalog API.
//
// For product documentation, see: https://cloud.google.com/private-catalog/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/cloudprivatecatalog/v1beta1"
//   ...
//   ctx := context.Background()
//   cloudprivatecatalogService, err := cloudprivatecatalog.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   cloudprivatecatalogService, err := cloudprivatecatalog.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   cloudprivatecatalogService, err := cloudprivatecatalog.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package cloudprivatecatalog // import "google.golang.org/api/cloudprivatecatalog/v1beta1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "cloudprivatecatalog:v1beta1"
const apiName = "cloudprivatecatalog"
const apiVersion = "v1beta1"
const basePath = "https://cloudprivatecatalog.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Folders = NewFoldersService(s)
	s.Organizations = NewOrganizationsService(s)
	s.Projects = NewProjectsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Folders *FoldersService

	Organizations *OrganizationsService

	Projects *ProjectsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewFoldersService(s *Service) *FoldersService {
	rs := &FoldersService{s: s}
	rs.Catalogs = NewFoldersCatalogsService(s)
	rs.Products = NewFoldersProductsService(s)
	rs.Versions = NewFoldersVersionsService(s)
	return rs
}

type FoldersService struct {
	s *Service

	Catalogs *FoldersCatalogsService

	Products *FoldersProductsService

	Versions *FoldersVersionsService
}

func NewFoldersCatalogsService(s *Service) *FoldersCatalogsService {
	rs := &FoldersCatalogsService{s: s}
	return rs
}

type FoldersCatalogsService struct {
	s *Service
}

func NewFoldersProductsService(s *Service) *FoldersProductsService {
	rs := &FoldersProductsService{s: s}
	return rs
}

type FoldersProductsService struct {
	s *Service
}

func NewFoldersVersionsService(s *Service) *FoldersVersionsService {
	rs := &FoldersVersionsService{s: s}
	return rs
}

type FoldersVersionsService struct {
	s *Service
}

func NewOrganizationsService(s *Service) *OrganizationsService {
	rs := &OrganizationsService{s: s}
	rs.Catalogs = NewOrganizationsCatalogsService(s)
	rs.Products = NewOrganizationsProductsService(s)
	rs.Versions = NewOrganizationsVersionsService(s)
	return rs
}

type OrganizationsService struct {
	s *Service

	Catalogs *OrganizationsCatalogsService

	Products *OrganizationsProductsService

	Versions *OrganizationsVersionsService
}

func NewOrganizationsCatalogsService(s *Service) *OrganizationsCatalogsService {
	rs := &OrganizationsCatalogsService{s: s}
	return rs
}

type OrganizationsCatalogsService struct {
	s *Service
}

func NewOrganizationsProductsService(s *Service) *OrganizationsProductsService {
	rs := &OrganizationsProductsService{s: s}
	return rs
}

type OrganizationsProductsService struct {
	s *Service
}

func NewOrganizationsVersionsService(s *Service) *OrganizationsVersionsService {
	rs := &OrganizationsVersionsService{s: s}
	return rs
}

type OrganizationsVersionsService struct {
	s *Service
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Catalogs = NewProjectsCatalogsService(s)
	rs.Products = NewProjectsProductsService(s)
	rs.Versions = NewProjectsVersionsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Catalogs *ProjectsCatalogsService

	Products *ProjectsProductsService

	Versions *ProjectsVersionsService
}

func NewProjectsCatalogsService(s *Service) *ProjectsCatalogsService {
	rs := &ProjectsCatalogsService{s: s}
	return rs
}

type ProjectsCatalogsService struct {
	s *Service
}

func NewProjectsProductsService(s *Service) *ProjectsProductsService {
	rs := &ProjectsProductsService{s: s}
	return rs
}

type ProjectsProductsService struct {
	s *Service
}

func NewProjectsVersionsService(s *Service) *ProjectsVersionsService {
	rs := &ProjectsVersionsService{s: s}
	return rs
}

type ProjectsVersionsService struct {
	s *Service
}

// GoogleCloudPrivatecatalogV1beta1Catalog: The readonly representation
// of a catalog computed with a given resource
// context.
type GoogleCloudPrivatecatalogV1beta1Catalog struct {
	// CreateTime: Output only. The time when the catalog was created.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Output only. The description of the catalog.
	Description string `json:"description,omitempty"`

	// DisplayName: Output only. The descriptive name of the catalog as it
	// appears in UIs.
	DisplayName string `json:"displayName,omitempty"`

	// Name: Output only. The resource name of the target catalog, in the
	// format of
	// `catalogs/{catalog_id}'.
	Name string `json:"name,omitempty"`

	// UpdateTime: Output only. The time when the catalog was last updated.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreateTime") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudPrivatecatalogV1beta1Catalog) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudPrivatecatalogV1beta1Catalog
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudPrivatecatalogV1beta1Product: The readonly representation
// of a product computed with a given resource
// context.
type GoogleCloudPrivatecatalogV1beta1Product struct {
	// AssetType: Output only. The type of the product asset. It can be one
	// of the
	// following values:
	//
	// * `google.deploymentmanager.Template`
	// * `google.cloudprivatecatalog.ListingOnly`
	AssetType string `json:"assetType,omitempty"`

	// CreateTime: Output only. The time when the product was created.
	CreateTime string `json:"createTime,omitempty"`

	// DisplayMetadata: Output only. The display metadata to describe the
	// product.
	// The JSON schema of the metadata differs by Product.asset_type.
	// When the type is `google.deploymentmanager.Template`, the schema is
	// as
	// follows:
	//
	// ```
	// "$schema": http://json-schema.org/draft-04/schema#
	// type: object
	// properties:
	//   name:
	//     type: string
	//     minLength: 1
	//     maxLength: 64
	//   description:
	//     type: string
	//     minLength: 1
	//     maxLength: 2048
	//   tagline:
	//     type: string
	//     minLength: 1
	//     maxLength: 100
	//   support_info:
	//     type: string
	//     minLength: 1
	//     maxLength: 2048
	//   creator:
	//     type: string
	//     minLength: 1
	//     maxLength: 100
	//   documentation:
	//     type: array
	//     items:
	//       type: object
	//       properties:
	//         url:
	//           type: string
	//           pattern:
	//
	// "^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"
	//         title:
	//           type: string
	//           minLength: 1
	//           maxLength: 64
	//         description:
	//           type: string
	//           minLength: 1
	//           maxLength: 2048
	// required:
	// - name
	// - description
	// additionalProperties: false
	//
	// ```
	//
	// When the asset type is `google.cloudprivatecatalog.ListingOnly`, the
	// schema
	// is as follows:
	//
	// ```
	// "$schema": http://json-schema.org/draft-04/schema#
	// type: object
	// properties:
	//   name:
	//     type: string
	//     minLength: 1
	//     maxLength: 64
	//   description:
	//     type: string
	//     minLength: 1
	//     maxLength: 2048
	//   tagline:
	//     type: string
	//     minLength: 1
	//     maxLength: 100
	//   support_info:
	//     type: string
	//     minLength: 1
	//     maxLength: 2048
	//   creator:
	//     type: string
	//     minLength: 1
	//     maxLength: 100
	//   documentation:
	//     type: array
	//     items:
	//       type: object
	//       properties:
	//         url:
	//           type: string
	//           pattern:
	//
	// "^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"
	//         title:
	//           type: string
	//           minLength: 1
	//           maxLength: 64
	//         description:
	//           type: string
	//           minLength: 1
	//           maxLength: 2048
	//   signup_url:
	//     type: string
	//     pattern:
	//
	// "^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"
	// requ
	// ired:
	// - name
	// - description
	// - signup_url
	// additionalProperties: false
	// ```
	DisplayMetadata googleapi.RawMessage `json:"displayMetadata,omitempty"`

	// IconUri: Output only. The icon URI of the product.
	IconUri string `json:"iconUri,omitempty"`

	// Name: Output only. The resource name of the target product, in the
	// format of
	// `products/a-z*[a-z0-9]'.
	//
	// A unique identifier for the product under a catalog.
	Name string `json:"name,omitempty"`

	// UpdateTime: Output only. The time when the product was last updated.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AssetType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AssetType") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudPrivatecatalogV1beta1Product) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudPrivatecatalogV1beta1Product
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse: Response
// message for PrivateCatalog.SearchCatalogs.
type GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse struct {
	// Catalogs: The `Catalog`s computed from the resource context.
	Catalogs []*GoogleCloudPrivatecatalogV1beta1Catalog `json:"catalogs,omitempty"`

	// NextPageToken: A pagination token returned from a previous call to
	// SearchCatalogs that
	// indicates from where listing should continue.
	// This field is optional.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Catalogs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Catalogs") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudPrivatecatalogV1beta1SearchProductsResponse: Response
// message for PrivateCatalog.SearchProducts.
type GoogleCloudPrivatecatalogV1beta1SearchProductsResponse struct {
	// NextPageToken: A pagination token returned from a previous call to
	// SearchProducts that
	// indicates from where listing should continue.
	// This field is optional.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Products: The `Product` resources computed from the resource context.
	Products []*GoogleCloudPrivatecatalogV1beta1Product `json:"products,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudPrivatecatalogV1beta1SearchProductsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudPrivatecatalogV1beta1SearchProductsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse: Response
// message for PrivateCatalog.SearchVersions.
type GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse struct {
	// NextPageToken: A pagination token returned from a previous call to
	// SearchVersions that
	// indicates from where the listing should continue.
	// This field is optional.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Versions: The `Version` resources computed from the resource context.
	Versions []*GoogleCloudPrivatecatalogV1beta1Version `json:"versions,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudPrivatecatalogV1beta1Version: The consumer representation
// of a version which is a child resource under a
// `Product` with asset data.
type GoogleCloudPrivatecatalogV1beta1Version struct {
	// Asset: Output only. The asset which has been validated and is ready
	// to be
	// provisioned.
	// See
	// google.cloud.privatecatalogproducer.v1beta.Version.asset for details.
	Asset googleapi.RawMessage `json:"asset,omitempty"`

	// CreateTime: Output only. The time when the version was created.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Output only. The user-supplied description of the
	// version. Maximum of 256
	// characters.
	Description string `json:"description,omitempty"`

	// Name: Output only. The resource name of the version, in the
	// format
	// `catalogs/{catalog_id}/products/{product_id}/versions/a-z*[a-z0
	// -9]'.
	//
	// A unique identifier for the version under a product.
	Name string `json:"name,omitempty"`

	// UpdateTime: Output only. The time when the version was last updated.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Asset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Asset") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudPrivatecatalogV1beta1Version) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudPrivatecatalogV1beta1Version
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "cloudprivatecatalog.folders.catalogs.search":

type FoldersCatalogsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Catalog resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *FoldersCatalogsService) Search(resource string) *FoldersCatalogsSearchCall {
	c := &FoldersCatalogsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *FoldersCatalogsSearchCall) PageSize(pageSize int64) *FoldersCatalogsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchCatalogs that
// indicates where this listing should continue from.
// This field is optional.
func (c *FoldersCatalogsSearchCall) PageToken(pageToken string) *FoldersCatalogsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// catalogs. The supported queries are:
//
// * Get a single catalog: `name=catalogs/{catalog_id}`
func (c *FoldersCatalogsSearchCall) Query(query string) *FoldersCatalogsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FoldersCatalogsSearchCall) Fields(s ...googleapi.Field) *FoldersCatalogsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FoldersCatalogsSearchCall) IfNoneMatch(entityTag string) *FoldersCatalogsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FoldersCatalogsSearchCall) Context(ctx context.Context) *FoldersCatalogsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FoldersCatalogsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FoldersCatalogsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/catalogs:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.folders.catalogs.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FoldersCatalogsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Catalog resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/folders/{foldersId}/catalogs:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.folders.catalogs.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchCatalogs that\nindicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the catalogs. The supported queries are:\n\n* Get a single catalog: `name=catalogs/{catalog_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. It can be in following formats:\n\n* `projects/{project_id}`\n* `folders/{folder_id}`\n* `organizations/{organization_id}`",
	//       "location": "path",
	//       "pattern": "^folders/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/catalogs:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *FoldersCatalogsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.folders.products.search":

type FoldersProductsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Product resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *FoldersProductsService) Search(resource string) *FoldersProductsSearchCall {
	c := &FoldersProductsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *FoldersProductsSearchCall) PageSize(pageSize int64) *FoldersProductsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchProducts that
// indicates where this listing should continue from.
// This field is optional.
func (c *FoldersProductsSearchCall) PageToken(pageToken string) *FoldersProductsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// products.
//
// The supported queries are:
// * List products of all catalogs: empty
// * List products under a catalog: `parent=catalogs/{catalog_id}`
// * Get a product by
// name:
// `name=catalogs/{catalog_id}/products/{product_id}`
func (c *FoldersProductsSearchCall) Query(query string) *FoldersProductsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FoldersProductsSearchCall) Fields(s ...googleapi.Field) *FoldersProductsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FoldersProductsSearchCall) IfNoneMatch(entityTag string) *FoldersProductsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FoldersProductsSearchCall) Context(ctx context.Context) *FoldersProductsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FoldersProductsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FoldersProductsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/products:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.folders.products.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchProductsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchProductsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FoldersProductsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchProductsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchProductsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Product resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/folders/{foldersId}/products:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.folders.products.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchProducts that\nindicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the products.\n\nThe supported queries are:\n* List products of all catalogs: empty\n* List products under a catalog: `parent=catalogs/{catalog_id}`\n* Get a product by name:\n`name=catalogs/{catalog_id}/products/{product_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. See\nSearchCatalogsRequest.resource for details.",
	//       "location": "path",
	//       "pattern": "^folders/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/products:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchProductsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *FoldersProductsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchProductsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.folders.versions.search":

type FoldersVersionsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Version resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *FoldersVersionsService) Search(resource string) *FoldersVersionsSearchCall {
	c := &FoldersVersionsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *FoldersVersionsSearchCall) PageSize(pageSize int64) *FoldersVersionsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchVersions
// that indicates where this listing should continue from.
// This field is optional.
func (c *FoldersVersionsSearchCall) PageToken(pageToken string) *FoldersVersionsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// versions. Required.
//
// The supported queries are:
// * List versions under a
// product:
// `parent=catalogs/{catalog_id}/products/{product_id}`
// * Get a version by
// name:
// `name=catalogs/{catalog_id}/products/{product_id}/versions/{vers
// ion_id}`
func (c *FoldersVersionsSearchCall) Query(query string) *FoldersVersionsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FoldersVersionsSearchCall) Fields(s ...googleapi.Field) *FoldersVersionsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FoldersVersionsSearchCall) IfNoneMatch(entityTag string) *FoldersVersionsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FoldersVersionsSearchCall) Context(ctx context.Context) *FoldersVersionsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FoldersVersionsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FoldersVersionsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/versions:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.folders.versions.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FoldersVersionsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Version resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/folders/{foldersId}/versions:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.folders.versions.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchVersions\nthat indicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the versions. Required.\n\nThe supported queries are:\n* List versions under a product:\n`parent=catalogs/{catalog_id}/products/{product_id}`\n* Get a version by name:\n`name=catalogs/{catalog_id}/products/{product_id}/versions/{version_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. See\nSearchCatalogsRequest.resource for details.",
	//       "location": "path",
	//       "pattern": "^folders/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/versions:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *FoldersVersionsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.organizations.catalogs.search":

type OrganizationsCatalogsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Catalog resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *OrganizationsCatalogsService) Search(resource string) *OrganizationsCatalogsSearchCall {
	c := &OrganizationsCatalogsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *OrganizationsCatalogsSearchCall) PageSize(pageSize int64) *OrganizationsCatalogsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchCatalogs that
// indicates where this listing should continue from.
// This field is optional.
func (c *OrganizationsCatalogsSearchCall) PageToken(pageToken string) *OrganizationsCatalogsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// catalogs. The supported queries are:
//
// * Get a single catalog: `name=catalogs/{catalog_id}`
func (c *OrganizationsCatalogsSearchCall) Query(query string) *OrganizationsCatalogsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrganizationsCatalogsSearchCall) Fields(s ...googleapi.Field) *OrganizationsCatalogsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OrganizationsCatalogsSearchCall) IfNoneMatch(entityTag string) *OrganizationsCatalogsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OrganizationsCatalogsSearchCall) Context(ctx context.Context) *OrganizationsCatalogsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrganizationsCatalogsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsCatalogsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/catalogs:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.organizations.catalogs.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *OrganizationsCatalogsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Catalog resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/organizations/{organizationsId}/catalogs:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.organizations.catalogs.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchCatalogs that\nindicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the catalogs. The supported queries are:\n\n* Get a single catalog: `name=catalogs/{catalog_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. It can be in following formats:\n\n* `projects/{project_id}`\n* `folders/{folder_id}`\n* `organizations/{organization_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/catalogs:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *OrganizationsCatalogsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.organizations.products.search":

type OrganizationsProductsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Product resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *OrganizationsProductsService) Search(resource string) *OrganizationsProductsSearchCall {
	c := &OrganizationsProductsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *OrganizationsProductsSearchCall) PageSize(pageSize int64) *OrganizationsProductsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchProducts that
// indicates where this listing should continue from.
// This field is optional.
func (c *OrganizationsProductsSearchCall) PageToken(pageToken string) *OrganizationsProductsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// products.
//
// The supported queries are:
// * List products of all catalogs: empty
// * List products under a catalog: `parent=catalogs/{catalog_id}`
// * Get a product by
// name:
// `name=catalogs/{catalog_id}/products/{product_id}`
func (c *OrganizationsProductsSearchCall) Query(query string) *OrganizationsProductsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrganizationsProductsSearchCall) Fields(s ...googleapi.Field) *OrganizationsProductsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OrganizationsProductsSearchCall) IfNoneMatch(entityTag string) *OrganizationsProductsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OrganizationsProductsSearchCall) Context(ctx context.Context) *OrganizationsProductsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrganizationsProductsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsProductsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/products:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.organizations.products.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchProductsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchProductsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *OrganizationsProductsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchProductsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchProductsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Product resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/organizations/{organizationsId}/products:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.organizations.products.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchProducts that\nindicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the products.\n\nThe supported queries are:\n* List products of all catalogs: empty\n* List products under a catalog: `parent=catalogs/{catalog_id}`\n* Get a product by name:\n`name=catalogs/{catalog_id}/products/{product_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. See\nSearchCatalogsRequest.resource for details.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/products:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchProductsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *OrganizationsProductsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchProductsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.organizations.versions.search":

type OrganizationsVersionsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Version resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *OrganizationsVersionsService) Search(resource string) *OrganizationsVersionsSearchCall {
	c := &OrganizationsVersionsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *OrganizationsVersionsSearchCall) PageSize(pageSize int64) *OrganizationsVersionsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchVersions
// that indicates where this listing should continue from.
// This field is optional.
func (c *OrganizationsVersionsSearchCall) PageToken(pageToken string) *OrganizationsVersionsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// versions. Required.
//
// The supported queries are:
// * List versions under a
// product:
// `parent=catalogs/{catalog_id}/products/{product_id}`
// * Get a version by
// name:
// `name=catalogs/{catalog_id}/products/{product_id}/versions/{vers
// ion_id}`
func (c *OrganizationsVersionsSearchCall) Query(query string) *OrganizationsVersionsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrganizationsVersionsSearchCall) Fields(s ...googleapi.Field) *OrganizationsVersionsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OrganizationsVersionsSearchCall) IfNoneMatch(entityTag string) *OrganizationsVersionsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OrganizationsVersionsSearchCall) Context(ctx context.Context) *OrganizationsVersionsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrganizationsVersionsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsVersionsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/versions:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.organizations.versions.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *OrganizationsVersionsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Version resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/organizations/{organizationsId}/versions:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.organizations.versions.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchVersions\nthat indicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the versions. Required.\n\nThe supported queries are:\n* List versions under a product:\n`parent=catalogs/{catalog_id}/products/{product_id}`\n* Get a version by name:\n`name=catalogs/{catalog_id}/products/{product_id}/versions/{version_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. See\nSearchCatalogsRequest.resource for details.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/versions:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *OrganizationsVersionsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.projects.catalogs.search":

type ProjectsCatalogsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Catalog resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *ProjectsCatalogsService) Search(resource string) *ProjectsCatalogsSearchCall {
	c := &ProjectsCatalogsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *ProjectsCatalogsSearchCall) PageSize(pageSize int64) *ProjectsCatalogsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchCatalogs that
// indicates where this listing should continue from.
// This field is optional.
func (c *ProjectsCatalogsSearchCall) PageToken(pageToken string) *ProjectsCatalogsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// catalogs. The supported queries are:
//
// * Get a single catalog: `name=catalogs/{catalog_id}`
func (c *ProjectsCatalogsSearchCall) Query(query string) *ProjectsCatalogsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsCatalogsSearchCall) Fields(s ...googleapi.Field) *ProjectsCatalogsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsCatalogsSearchCall) IfNoneMatch(entityTag string) *ProjectsCatalogsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsCatalogsSearchCall) Context(ctx context.Context) *ProjectsCatalogsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsCatalogsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCatalogsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/catalogs:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.projects.catalogs.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsCatalogsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Catalog resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/projects/{projectsId}/catalogs:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.projects.catalogs.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchCatalogs that\nindicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the catalogs. The supported queries are:\n\n* Get a single catalog: `name=catalogs/{catalog_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. It can be in following formats:\n\n* `projects/{project_id}`\n* `folders/{folder_id}`\n* `organizations/{organization_id}`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/catalogs:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsCatalogsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchCatalogsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.projects.products.search":

type ProjectsProductsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Product resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *ProjectsProductsService) Search(resource string) *ProjectsProductsSearchCall {
	c := &ProjectsProductsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *ProjectsProductsSearchCall) PageSize(pageSize int64) *ProjectsProductsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchProducts that
// indicates where this listing should continue from.
// This field is optional.
func (c *ProjectsProductsSearchCall) PageToken(pageToken string) *ProjectsProductsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// products.
//
// The supported queries are:
// * List products of all catalogs: empty
// * List products under a catalog: `parent=catalogs/{catalog_id}`
// * Get a product by
// name:
// `name=catalogs/{catalog_id}/products/{product_id}`
func (c *ProjectsProductsSearchCall) Query(query string) *ProjectsProductsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsProductsSearchCall) Fields(s ...googleapi.Field) *ProjectsProductsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsProductsSearchCall) IfNoneMatch(entityTag string) *ProjectsProductsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsProductsSearchCall) Context(ctx context.Context) *ProjectsProductsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsProductsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsProductsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/products:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.projects.products.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchProductsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchProductsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsProductsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchProductsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchProductsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Product resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/projects/{projectsId}/products:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.projects.products.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchProducts that\nindicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the products.\n\nThe supported queries are:\n* List products of all catalogs: empty\n* List products under a catalog: `parent=catalogs/{catalog_id}`\n* Get a product by name:\n`name=catalogs/{catalog_id}/products/{product_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. See\nSearchCatalogsRequest.resource for details.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/products:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchProductsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsProductsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchProductsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "cloudprivatecatalog.projects.versions.search":

type ProjectsVersionsSearchCall struct {
	s            *Service
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Search Version resources that consumers have access to,
// within the
// scope of the consumer cloud resource hierarchy context.
func (r *ProjectsVersionsService) Search(resource string) *ProjectsVersionsSearchCall {
	c := &ProjectsVersionsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of entries that are requested.
func (c *ProjectsVersionsSearchCall) PageSize(pageSize int64) *ProjectsVersionsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A pagination token
// returned from a previous call to SearchVersions
// that indicates where this listing should continue from.
// This field is optional.
func (c *ProjectsVersionsSearchCall) PageToken(pageToken string) *ProjectsVersionsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": The query to filter the
// versions. Required.
//
// The supported queries are:
// * List versions under a
// product:
// `parent=catalogs/{catalog_id}/products/{product_id}`
// * Get a version by
// name:
// `name=catalogs/{catalog_id}/products/{product_id}/versions/{vers
// ion_id}`
func (c *ProjectsVersionsSearchCall) Query(query string) *ProjectsVersionsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsVersionsSearchCall) Fields(s ...googleapi.Field) *ProjectsVersionsSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsVersionsSearchCall) IfNoneMatch(entityTag string) *ProjectsVersionsSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsVersionsSearchCall) Context(ctx context.Context) *ProjectsVersionsSearchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsVersionsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsVersionsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191227")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+resource}/versions:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudprivatecatalog.projects.versions.search" call.
// Exactly one of
// *GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse.ServerResponse
// .Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsVersionsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Search Version resources that consumers have access to, within the\nscope of the consumer cloud resource hierarchy context.",
	//   "flatPath": "v1beta1/projects/{projectsId}/versions:search",
	//   "httpMethod": "GET",
	//   "id": "cloudprivatecatalog.projects.versions.search",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The maximum number of entries that are requested.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A pagination token returned from a previous call to SearchVersions\nthat indicates where this listing should continue from.\nThis field is optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "The query to filter the versions. Required.\n\nThe supported queries are:\n* List versions under a product:\n`parent=catalogs/{catalog_id}/products/{product_id}`\n* Get a version by name:\n`name=catalogs/{catalog_id}/products/{product_id}/versions/{version_id}`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resource": {
	//       "description": "Required. The name of the resource context. See\nSearchCatalogsRequest.resource for details.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+resource}/versions:search",
	//   "response": {
	//     "$ref": "GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsVersionsSearchCall) Pages(ctx context.Context, f func(*GoogleCloudPrivatecatalogV1beta1SearchVersionsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}
