// Copyright 2020 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 apigee provides access to the Apigee API.
//
// For product documentation, see: https://cloud.google.com/apigee-api-management/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/apigee/v1"
//   ...
//   ctx := context.Background()
//   apigeeService, err := apigee.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:
//
//   apigeeService, err := apigee.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, ...)
//   apigeeService, err := apigee.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package apigee // import "google.golang.org/api/apigee/v1"

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"
	internaloption "google.golang.org/api/option/internaloption"
	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
var _ = internaloption.WithDefaultEndpoint

const apiId = "apigee:v1"
const apiName = "apigee"
const apiVersion = "v1"
const basePath = "https://apigee.googleapis.com/"
const mtlsBasePath = "https://apigee.mtls.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...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	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.Hybrid = NewHybridService(s)
	s.Organizations = NewOrganizationsService(s)
	return s, nil
}

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

	Hybrid *HybridService

	Organizations *OrganizationsService
}

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

func NewHybridService(s *Service) *HybridService {
	rs := &HybridService{s: s}
	rs.Issuers = NewHybridIssuersService(s)
	return rs
}

type HybridService struct {
	s *Service

	Issuers *HybridIssuersService
}

func NewHybridIssuersService(s *Service) *HybridIssuersService {
	rs := &HybridIssuersService{s: s}
	return rs
}

type HybridIssuersService struct {
	s *Service
}

func NewOrganizationsService(s *Service) *OrganizationsService {
	rs := &OrganizationsService{s: s}
	rs.Analytics = NewOrganizationsAnalyticsService(s)
	rs.Apiproducts = NewOrganizationsApiproductsService(s)
	rs.Apis = NewOrganizationsApisService(s)
	rs.Apps = NewOrganizationsAppsService(s)
	rs.Deployments = NewOrganizationsDeploymentsService(s)
	rs.Developers = NewOrganizationsDevelopersService(s)
	rs.Envgroups = NewOrganizationsEnvgroupsService(s)
	rs.Environments = NewOrganizationsEnvironmentsService(s)
	rs.Instances = NewOrganizationsInstancesService(s)
	rs.Keyvaluemaps = NewOrganizationsKeyvaluemapsService(s)
	rs.Operations = NewOrganizationsOperationsService(s)
	rs.Reports = NewOrganizationsReportsService(s)
	rs.Sharedflows = NewOrganizationsSharedflowsService(s)
	return rs
}

type OrganizationsService struct {
	s *Service

	Analytics *OrganizationsAnalyticsService

	Apiproducts *OrganizationsApiproductsService

	Apis *OrganizationsApisService

	Apps *OrganizationsAppsService

	Deployments *OrganizationsDeploymentsService

	Developers *OrganizationsDevelopersService

	Envgroups *OrganizationsEnvgroupsService

	Environments *OrganizationsEnvironmentsService

	Instances *OrganizationsInstancesService

	Keyvaluemaps *OrganizationsKeyvaluemapsService

	Operations *OrganizationsOperationsService

	Reports *OrganizationsReportsService

	Sharedflows *OrganizationsSharedflowsService
}

func NewOrganizationsAnalyticsService(s *Service) *OrganizationsAnalyticsService {
	rs := &OrganizationsAnalyticsService{s: s}
	rs.Datastores = NewOrganizationsAnalyticsDatastoresService(s)
	return rs
}

type OrganizationsAnalyticsService struct {
	s *Service

	Datastores *OrganizationsAnalyticsDatastoresService
}

func NewOrganizationsAnalyticsDatastoresService(s *Service) *OrganizationsAnalyticsDatastoresService {
	rs := &OrganizationsAnalyticsDatastoresService{s: s}
	return rs
}

type OrganizationsAnalyticsDatastoresService struct {
	s *Service
}

func NewOrganizationsApiproductsService(s *Service) *OrganizationsApiproductsService {
	rs := &OrganizationsApiproductsService{s: s}
	rs.Attributes_ = NewOrganizationsApiproductsAttributesService(s)
	return rs
}

type OrganizationsApiproductsService struct {
	s *Service

	Attributes_ *OrganizationsApiproductsAttributesService
}

func NewOrganizationsApiproductsAttributesService(s *Service) *OrganizationsApiproductsAttributesService {
	rs := &OrganizationsApiproductsAttributesService{s: s}
	return rs
}

type OrganizationsApiproductsAttributesService struct {
	s *Service
}

func NewOrganizationsApisService(s *Service) *OrganizationsApisService {
	rs := &OrganizationsApisService{s: s}
	rs.Deployments = NewOrganizationsApisDeploymentsService(s)
	rs.Keyvaluemaps = NewOrganizationsApisKeyvaluemapsService(s)
	rs.Revisions = NewOrganizationsApisRevisionsService(s)
	return rs
}

type OrganizationsApisService struct {
	s *Service

	Deployments *OrganizationsApisDeploymentsService

	Keyvaluemaps *OrganizationsApisKeyvaluemapsService

	Revisions *OrganizationsApisRevisionsService
}

func NewOrganizationsApisDeploymentsService(s *Service) *OrganizationsApisDeploymentsService {
	rs := &OrganizationsApisDeploymentsService{s: s}
	return rs
}

type OrganizationsApisDeploymentsService struct {
	s *Service
}

func NewOrganizationsApisKeyvaluemapsService(s *Service) *OrganizationsApisKeyvaluemapsService {
	rs := &OrganizationsApisKeyvaluemapsService{s: s}
	return rs
}

type OrganizationsApisKeyvaluemapsService struct {
	s *Service
}

func NewOrganizationsApisRevisionsService(s *Service) *OrganizationsApisRevisionsService {
	rs := &OrganizationsApisRevisionsService{s: s}
	rs.Deployments = NewOrganizationsApisRevisionsDeploymentsService(s)
	return rs
}

type OrganizationsApisRevisionsService struct {
	s *Service

	Deployments *OrganizationsApisRevisionsDeploymentsService
}

func NewOrganizationsApisRevisionsDeploymentsService(s *Service) *OrganizationsApisRevisionsDeploymentsService {
	rs := &OrganizationsApisRevisionsDeploymentsService{s: s}
	return rs
}

type OrganizationsApisRevisionsDeploymentsService struct {
	s *Service
}

func NewOrganizationsAppsService(s *Service) *OrganizationsAppsService {
	rs := &OrganizationsAppsService{s: s}
	return rs
}

type OrganizationsAppsService struct {
	s *Service
}

func NewOrganizationsDeploymentsService(s *Service) *OrganizationsDeploymentsService {
	rs := &OrganizationsDeploymentsService{s: s}
	return rs
}

type OrganizationsDeploymentsService struct {
	s *Service
}

func NewOrganizationsDevelopersService(s *Service) *OrganizationsDevelopersService {
	rs := &OrganizationsDevelopersService{s: s}
	rs.Apps = NewOrganizationsDevelopersAppsService(s)
	rs.Attributes_ = NewOrganizationsDevelopersAttributesService(s)
	return rs
}

type OrganizationsDevelopersService struct {
	s *Service

	Apps *OrganizationsDevelopersAppsService

	Attributes_ *OrganizationsDevelopersAttributesService
}

func NewOrganizationsDevelopersAppsService(s *Service) *OrganizationsDevelopersAppsService {
	rs := &OrganizationsDevelopersAppsService{s: s}
	rs.Attributes_ = NewOrganizationsDevelopersAppsAttributesService(s)
	rs.Keys = NewOrganizationsDevelopersAppsKeysService(s)
	return rs
}

type OrganizationsDevelopersAppsService struct {
	s *Service

	Attributes_ *OrganizationsDevelopersAppsAttributesService

	Keys *OrganizationsDevelopersAppsKeysService
}

func NewOrganizationsDevelopersAppsAttributesService(s *Service) *OrganizationsDevelopersAppsAttributesService {
	rs := &OrganizationsDevelopersAppsAttributesService{s: s}
	return rs
}

type OrganizationsDevelopersAppsAttributesService struct {
	s *Service
}

func NewOrganizationsDevelopersAppsKeysService(s *Service) *OrganizationsDevelopersAppsKeysService {
	rs := &OrganizationsDevelopersAppsKeysService{s: s}
	rs.Apiproducts = NewOrganizationsDevelopersAppsKeysApiproductsService(s)
	rs.Create_ = NewOrganizationsDevelopersAppsKeysCreateService(s)
	return rs
}

type OrganizationsDevelopersAppsKeysService struct {
	s *Service

	Apiproducts *OrganizationsDevelopersAppsKeysApiproductsService

	Create_ *OrganizationsDevelopersAppsKeysCreateService
}

func NewOrganizationsDevelopersAppsKeysApiproductsService(s *Service) *OrganizationsDevelopersAppsKeysApiproductsService {
	rs := &OrganizationsDevelopersAppsKeysApiproductsService{s: s}
	return rs
}

type OrganizationsDevelopersAppsKeysApiproductsService struct {
	s *Service
}

func NewOrganizationsDevelopersAppsKeysCreateService(s *Service) *OrganizationsDevelopersAppsKeysCreateService {
	rs := &OrganizationsDevelopersAppsKeysCreateService{s: s}
	return rs
}

type OrganizationsDevelopersAppsKeysCreateService struct {
	s *Service
}

func NewOrganizationsDevelopersAttributesService(s *Service) *OrganizationsDevelopersAttributesService {
	rs := &OrganizationsDevelopersAttributesService{s: s}
	return rs
}

type OrganizationsDevelopersAttributesService struct {
	s *Service
}

func NewOrganizationsEnvgroupsService(s *Service) *OrganizationsEnvgroupsService {
	rs := &OrganizationsEnvgroupsService{s: s}
	rs.Attachments = NewOrganizationsEnvgroupsAttachmentsService(s)
	return rs
}

type OrganizationsEnvgroupsService struct {
	s *Service

	Attachments *OrganizationsEnvgroupsAttachmentsService
}

func NewOrganizationsEnvgroupsAttachmentsService(s *Service) *OrganizationsEnvgroupsAttachmentsService {
	rs := &OrganizationsEnvgroupsAttachmentsService{s: s}
	return rs
}

type OrganizationsEnvgroupsAttachmentsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsService(s *Service) *OrganizationsEnvironmentsService {
	rs := &OrganizationsEnvironmentsService{s: s}
	rs.Analytics = NewOrganizationsEnvironmentsAnalyticsService(s)
	rs.Apis = NewOrganizationsEnvironmentsApisService(s)
	rs.Caches = NewOrganizationsEnvironmentsCachesService(s)
	rs.Deployments = NewOrganizationsEnvironmentsDeploymentsService(s)
	rs.Flowhooks = NewOrganizationsEnvironmentsFlowhooksService(s)
	rs.Keystores = NewOrganizationsEnvironmentsKeystoresService(s)
	rs.Keyvaluemaps = NewOrganizationsEnvironmentsKeyvaluemapsService(s)
	rs.OptimizedStats = NewOrganizationsEnvironmentsOptimizedStatsService(s)
	rs.Queries = NewOrganizationsEnvironmentsQueriesService(s)
	rs.References = NewOrganizationsEnvironmentsReferencesService(s)
	rs.Resourcefiles = NewOrganizationsEnvironmentsResourcefilesService(s)
	rs.Sharedflows = NewOrganizationsEnvironmentsSharedflowsService(s)
	rs.Stats = NewOrganizationsEnvironmentsStatsService(s)
	rs.Targetservers = NewOrganizationsEnvironmentsTargetserversService(s)
	return rs
}

type OrganizationsEnvironmentsService struct {
	s *Service

	Analytics *OrganizationsEnvironmentsAnalyticsService

	Apis *OrganizationsEnvironmentsApisService

	Caches *OrganizationsEnvironmentsCachesService

	Deployments *OrganizationsEnvironmentsDeploymentsService

	Flowhooks *OrganizationsEnvironmentsFlowhooksService

	Keystores *OrganizationsEnvironmentsKeystoresService

	Keyvaluemaps *OrganizationsEnvironmentsKeyvaluemapsService

	OptimizedStats *OrganizationsEnvironmentsOptimizedStatsService

	Queries *OrganizationsEnvironmentsQueriesService

	References *OrganizationsEnvironmentsReferencesService

	Resourcefiles *OrganizationsEnvironmentsResourcefilesService

	Sharedflows *OrganizationsEnvironmentsSharedflowsService

	Stats *OrganizationsEnvironmentsStatsService

	Targetservers *OrganizationsEnvironmentsTargetserversService
}

func NewOrganizationsEnvironmentsAnalyticsService(s *Service) *OrganizationsEnvironmentsAnalyticsService {
	rs := &OrganizationsEnvironmentsAnalyticsService{s: s}
	rs.Admin = NewOrganizationsEnvironmentsAnalyticsAdminService(s)
	rs.Exports = NewOrganizationsEnvironmentsAnalyticsExportsService(s)
	return rs
}

type OrganizationsEnvironmentsAnalyticsService struct {
	s *Service

	Admin *OrganizationsEnvironmentsAnalyticsAdminService

	Exports *OrganizationsEnvironmentsAnalyticsExportsService
}

func NewOrganizationsEnvironmentsAnalyticsAdminService(s *Service) *OrganizationsEnvironmentsAnalyticsAdminService {
	rs := &OrganizationsEnvironmentsAnalyticsAdminService{s: s}
	return rs
}

type OrganizationsEnvironmentsAnalyticsAdminService struct {
	s *Service
}

func NewOrganizationsEnvironmentsAnalyticsExportsService(s *Service) *OrganizationsEnvironmentsAnalyticsExportsService {
	rs := &OrganizationsEnvironmentsAnalyticsExportsService{s: s}
	return rs
}

type OrganizationsEnvironmentsAnalyticsExportsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsApisService(s *Service) *OrganizationsEnvironmentsApisService {
	rs := &OrganizationsEnvironmentsApisService{s: s}
	rs.Deployments = NewOrganizationsEnvironmentsApisDeploymentsService(s)
	rs.Revisions = NewOrganizationsEnvironmentsApisRevisionsService(s)
	return rs
}

type OrganizationsEnvironmentsApisService struct {
	s *Service

	Deployments *OrganizationsEnvironmentsApisDeploymentsService

	Revisions *OrganizationsEnvironmentsApisRevisionsService
}

func NewOrganizationsEnvironmentsApisDeploymentsService(s *Service) *OrganizationsEnvironmentsApisDeploymentsService {
	rs := &OrganizationsEnvironmentsApisDeploymentsService{s: s}
	return rs
}

type OrganizationsEnvironmentsApisDeploymentsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsApisRevisionsService(s *Service) *OrganizationsEnvironmentsApisRevisionsService {
	rs := &OrganizationsEnvironmentsApisRevisionsService{s: s}
	rs.Debugsessions = NewOrganizationsEnvironmentsApisRevisionsDebugsessionsService(s)
	rs.Deployments = NewOrganizationsEnvironmentsApisRevisionsDeploymentsService(s)
	return rs
}

type OrganizationsEnvironmentsApisRevisionsService struct {
	s *Service

	Debugsessions *OrganizationsEnvironmentsApisRevisionsDebugsessionsService

	Deployments *OrganizationsEnvironmentsApisRevisionsDeploymentsService
}

func NewOrganizationsEnvironmentsApisRevisionsDebugsessionsService(s *Service) *OrganizationsEnvironmentsApisRevisionsDebugsessionsService {
	rs := &OrganizationsEnvironmentsApisRevisionsDebugsessionsService{s: s}
	rs.Data = NewOrganizationsEnvironmentsApisRevisionsDebugsessionsDataService(s)
	return rs
}

type OrganizationsEnvironmentsApisRevisionsDebugsessionsService struct {
	s *Service

	Data *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataService
}

func NewOrganizationsEnvironmentsApisRevisionsDebugsessionsDataService(s *Service) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataService {
	rs := &OrganizationsEnvironmentsApisRevisionsDebugsessionsDataService{s: s}
	return rs
}

type OrganizationsEnvironmentsApisRevisionsDebugsessionsDataService struct {
	s *Service
}

func NewOrganizationsEnvironmentsApisRevisionsDeploymentsService(s *Service) *OrganizationsEnvironmentsApisRevisionsDeploymentsService {
	rs := &OrganizationsEnvironmentsApisRevisionsDeploymentsService{s: s}
	return rs
}

type OrganizationsEnvironmentsApisRevisionsDeploymentsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsCachesService(s *Service) *OrganizationsEnvironmentsCachesService {
	rs := &OrganizationsEnvironmentsCachesService{s: s}
	return rs
}

type OrganizationsEnvironmentsCachesService struct {
	s *Service
}

func NewOrganizationsEnvironmentsDeploymentsService(s *Service) *OrganizationsEnvironmentsDeploymentsService {
	rs := &OrganizationsEnvironmentsDeploymentsService{s: s}
	return rs
}

type OrganizationsEnvironmentsDeploymentsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsFlowhooksService(s *Service) *OrganizationsEnvironmentsFlowhooksService {
	rs := &OrganizationsEnvironmentsFlowhooksService{s: s}
	return rs
}

type OrganizationsEnvironmentsFlowhooksService struct {
	s *Service
}

func NewOrganizationsEnvironmentsKeystoresService(s *Service) *OrganizationsEnvironmentsKeystoresService {
	rs := &OrganizationsEnvironmentsKeystoresService{s: s}
	rs.Aliases = NewOrganizationsEnvironmentsKeystoresAliasesService(s)
	return rs
}

type OrganizationsEnvironmentsKeystoresService struct {
	s *Service

	Aliases *OrganizationsEnvironmentsKeystoresAliasesService
}

func NewOrganizationsEnvironmentsKeystoresAliasesService(s *Service) *OrganizationsEnvironmentsKeystoresAliasesService {
	rs := &OrganizationsEnvironmentsKeystoresAliasesService{s: s}
	return rs
}

type OrganizationsEnvironmentsKeystoresAliasesService struct {
	s *Service
}

func NewOrganizationsEnvironmentsKeyvaluemapsService(s *Service) *OrganizationsEnvironmentsKeyvaluemapsService {
	rs := &OrganizationsEnvironmentsKeyvaluemapsService{s: s}
	return rs
}

type OrganizationsEnvironmentsKeyvaluemapsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsOptimizedStatsService(s *Service) *OrganizationsEnvironmentsOptimizedStatsService {
	rs := &OrganizationsEnvironmentsOptimizedStatsService{s: s}
	return rs
}

type OrganizationsEnvironmentsOptimizedStatsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsQueriesService(s *Service) *OrganizationsEnvironmentsQueriesService {
	rs := &OrganizationsEnvironmentsQueriesService{s: s}
	return rs
}

type OrganizationsEnvironmentsQueriesService struct {
	s *Service
}

func NewOrganizationsEnvironmentsReferencesService(s *Service) *OrganizationsEnvironmentsReferencesService {
	rs := &OrganizationsEnvironmentsReferencesService{s: s}
	return rs
}

type OrganizationsEnvironmentsReferencesService struct {
	s *Service
}

func NewOrganizationsEnvironmentsResourcefilesService(s *Service) *OrganizationsEnvironmentsResourcefilesService {
	rs := &OrganizationsEnvironmentsResourcefilesService{s: s}
	return rs
}

type OrganizationsEnvironmentsResourcefilesService struct {
	s *Service
}

func NewOrganizationsEnvironmentsSharedflowsService(s *Service) *OrganizationsEnvironmentsSharedflowsService {
	rs := &OrganizationsEnvironmentsSharedflowsService{s: s}
	rs.Deployments = NewOrganizationsEnvironmentsSharedflowsDeploymentsService(s)
	rs.Revisions = NewOrganizationsEnvironmentsSharedflowsRevisionsService(s)
	return rs
}

type OrganizationsEnvironmentsSharedflowsService struct {
	s *Service

	Deployments *OrganizationsEnvironmentsSharedflowsDeploymentsService

	Revisions *OrganizationsEnvironmentsSharedflowsRevisionsService
}

func NewOrganizationsEnvironmentsSharedflowsDeploymentsService(s *Service) *OrganizationsEnvironmentsSharedflowsDeploymentsService {
	rs := &OrganizationsEnvironmentsSharedflowsDeploymentsService{s: s}
	return rs
}

type OrganizationsEnvironmentsSharedflowsDeploymentsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsSharedflowsRevisionsService(s *Service) *OrganizationsEnvironmentsSharedflowsRevisionsService {
	rs := &OrganizationsEnvironmentsSharedflowsRevisionsService{s: s}
	return rs
}

type OrganizationsEnvironmentsSharedflowsRevisionsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsStatsService(s *Service) *OrganizationsEnvironmentsStatsService {
	rs := &OrganizationsEnvironmentsStatsService{s: s}
	return rs
}

type OrganizationsEnvironmentsStatsService struct {
	s *Service
}

func NewOrganizationsEnvironmentsTargetserversService(s *Service) *OrganizationsEnvironmentsTargetserversService {
	rs := &OrganizationsEnvironmentsTargetserversService{s: s}
	return rs
}

type OrganizationsEnvironmentsTargetserversService struct {
	s *Service
}

func NewOrganizationsInstancesService(s *Service) *OrganizationsInstancesService {
	rs := &OrganizationsInstancesService{s: s}
	rs.Attachments = NewOrganizationsInstancesAttachmentsService(s)
	return rs
}

type OrganizationsInstancesService struct {
	s *Service

	Attachments *OrganizationsInstancesAttachmentsService
}

func NewOrganizationsInstancesAttachmentsService(s *Service) *OrganizationsInstancesAttachmentsService {
	rs := &OrganizationsInstancesAttachmentsService{s: s}
	return rs
}

type OrganizationsInstancesAttachmentsService struct {
	s *Service
}

func NewOrganizationsKeyvaluemapsService(s *Service) *OrganizationsKeyvaluemapsService {
	rs := &OrganizationsKeyvaluemapsService{s: s}
	return rs
}

type OrganizationsKeyvaluemapsService struct {
	s *Service
}

func NewOrganizationsOperationsService(s *Service) *OrganizationsOperationsService {
	rs := &OrganizationsOperationsService{s: s}
	return rs
}

type OrganizationsOperationsService struct {
	s *Service
}

func NewOrganizationsReportsService(s *Service) *OrganizationsReportsService {
	rs := &OrganizationsReportsService{s: s}
	return rs
}

type OrganizationsReportsService struct {
	s *Service
}

func NewOrganizationsSharedflowsService(s *Service) *OrganizationsSharedflowsService {
	rs := &OrganizationsSharedflowsService{s: s}
	rs.Deployments = NewOrganizationsSharedflowsDeploymentsService(s)
	rs.Revisions = NewOrganizationsSharedflowsRevisionsService(s)
	return rs
}

type OrganizationsSharedflowsService struct {
	s *Service

	Deployments *OrganizationsSharedflowsDeploymentsService

	Revisions *OrganizationsSharedflowsRevisionsService
}

func NewOrganizationsSharedflowsDeploymentsService(s *Service) *OrganizationsSharedflowsDeploymentsService {
	rs := &OrganizationsSharedflowsDeploymentsService{s: s}
	return rs
}

type OrganizationsSharedflowsDeploymentsService struct {
	s *Service
}

func NewOrganizationsSharedflowsRevisionsService(s *Service) *OrganizationsSharedflowsRevisionsService {
	rs := &OrganizationsSharedflowsRevisionsService{s: s}
	rs.Deployments = NewOrganizationsSharedflowsRevisionsDeploymentsService(s)
	return rs
}

type OrganizationsSharedflowsRevisionsService struct {
	s *Service

	Deployments *OrganizationsSharedflowsRevisionsDeploymentsService
}

func NewOrganizationsSharedflowsRevisionsDeploymentsService(s *Service) *OrganizationsSharedflowsRevisionsDeploymentsService {
	rs := &OrganizationsSharedflowsRevisionsDeploymentsService{s: s}
	return rs
}

type OrganizationsSharedflowsRevisionsDeploymentsService struct {
	s *Service
}

// GoogleApiHttpBody: Message that represents an arbitrary HTTP body. It
// should only be used for payload formats that can't be represented as
// JSON, such as raw binary or an HTML page. This message can be used
// both in streaming and non-streaming API methods in the request as
// well as the response. It can be used as a top-level request field,
// which is convenient if one wants to extract parameters from either
// the URL or HTTP template into the request fields and also want access
// to the raw HTTP body. Example: message GetResourceRequest { // A
// unique request id. string request_id = 1; // The raw HTTP body is
// bound to this field. google.api.HttpBody http_body = 2; } service
// ResourceService { rpc GetResource(GetResourceRequest) returns
// (google.api.HttpBody); rpc UpdateResource(google.api.HttpBody)
// returns (google.protobuf.Empty); } Example with streaming methods:
// service CaldavService { rpc GetCalendar(stream google.api.HttpBody)
// returns (stream google.api.HttpBody); rpc UpdateCalendar(stream
// google.api.HttpBody) returns (stream google.api.HttpBody); } Use of
// this type only changes how the request and response bodies are
// handled, all other features will continue to work unchanged.
type GoogleApiHttpBody struct {
	// ContentType: The HTTP Content-Type header value specifying the
	// content type of the body.
	ContentType string `json:"contentType,omitempty"`

	// Data: The HTTP request/response body as raw binary.
	Data string `json:"data,omitempty"`

	// Extensions: Application specific response metadata. Must be set in
	// the first response for streaming APIs.
	Extensions []googleapi.RawMessage `json:"extensions,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ContentType") 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. "ContentType") 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 *GoogleApiHttpBody) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleApiHttpBody
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Access struct {
	Get *GoogleCloudApigeeV1AccessGet `json:"Get,omitempty"`

	Remove *GoogleCloudApigeeV1AccessRemove `json:"Remove,omitempty"`

	Set *GoogleCloudApigeeV1AccessSet `json:"Set,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Get") 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. "Get") 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 *GoogleCloudApigeeV1Access) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Access
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1AccessGet: Get action. For example, "Get" : {
// "name" : "target.name", "value" : "default" }
type GoogleCloudApigeeV1AccessGet struct {
	Name string `json:"name,omitempty"`

	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1AccessGet) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1AccessGet
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1AccessRemove: Remove action. For example, "Remove"
// : { "name" : "target.name", "success" : true }
type GoogleCloudApigeeV1AccessRemove struct {
	Name string `json:"name,omitempty"`

	Success bool `json:"success,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1AccessRemove) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1AccessRemove
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1AccessSet: Set action. For example, "Set" : {
// "name" : "target.name", "success" : true, "value" : "default" }
type GoogleCloudApigeeV1AccessSet struct {
	Name string `json:"name,omitempty"`

	Success bool `json:"success,omitempty"`

	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1AccessSet) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1AccessSet
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Alias: A reference to a certificate or key,
// certificate pair.
type GoogleCloudApigeeV1Alias struct {
	// Alias: The resource ID for this alias. Values must match regular
	// expression `[^/]{1,255}`.
	Alias string `json:"alias,omitempty"`

	// CertsInfo: The chain of certificates under this alias.
	CertsInfo *GoogleCloudApigeeV1Certificate `json:"certsInfo,omitempty"`

	// Type: The type of alias.
	//
	// Possible values:
	//   "ALIAS_TYPE_UNSPECIFIED"
	//   "CERT"
	//   "KEY_CERT"
	Type string `json:"type,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Alias") 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. "Alias") 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 *GoogleCloudApigeeV1Alias) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Alias
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1AliasRevisionConfig struct {
	// Location: The location of the alias file, e.g. a GCS URI.
	Location string `json:"location,omitempty"`

	// Name: The name of the alias revision included in the keystore. Must
	// be of the form:
	// 'organizations/{org}/environments/{env}/keystores/{keystore}/aliases/{
	// alias}/revisions/{rev}'.
	Name string `json:"name,omitempty"`

	// Possible values:
	//   "ALIAS_TYPE_UNSPECIFIED"
	//   "CERT"
	//   "KEY_CERT"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Location") 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. "Location") 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 *GoogleCloudApigeeV1AliasRevisionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1AliasRevisionConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ApiProduct struct {
	// ApiResources: Comma-separated list of API resources to be bundled in
	// the API Product. By default, the resource paths are mapped from the
	// `proxy.pathsuffix` variable. The proxy path suffix is defined as the
	// URI fragment following the ProxyEndpoint base path. For example, if
	// the `apiResources` element is defined to be `/forecastrss` and the
	// base path defined for the API proxy is `/weather`, then only requests
	// to `/weather/forecastrss` are permitted by the API product. You can
	// select a specific path, or you can select all subpaths with the
	// following wildcard: - /**: Indicates that all sub-URIs are included.
	// - /* : Indicates that only URIs one level down are included. By
	// default, / supports the same resources as /** as well as the base
	// path defined by the API proxy. For example, if the base path of the
	// API proxy is `/v1/weatherapikey`, then the API product supports
	// requests to `/v1/weatherapikey` and to any sub-URIs, such as
	// `/v1/weatherapikey/forecastrss`, `/v1/weatherapikey/region/CA`, and
	// so on. For more information, see: - Manage API products - Managing a
	// transaction recording policy using the API
	ApiResources []string `json:"apiResources,omitempty"`

	// ApprovalType: Specifies how API keys are approved to access the APIs
	// defined by the API product. If set to `manual`, the consumer key is
	// generated and returned in "pending" state. In this case, the API keys
	// won't work until they have been explicitly approved. If set to
	// `auto`, the consumer key is generated and returned in "approved"
	// state and can be used immediately. *NOTE:* Typically, `auto` is used
	// to provide access to free or trial API products that provide limited
	// quota or capabilities.
	ApprovalType string `json:"approvalType,omitempty"`

	// Attributes: Array of attributes that may be used to extend the
	// default API product profile with customer-specific metadata. You can
	// specify a maximum of 18 attributes. Use this property to specify the
	// access level of the API product as either `public`, `private`, or
	// `internal`. Only products marked `public` are available to developers
	// in the Apigee developer portal. For example, you can set a product to
	// `internal` while it is in development and then change access to
	// `public` when it is ready to release on the portal. API products
	// marked as `private` do not appear on the portal but can be accessed
	// by external developers. For monetization, you can use the attributes
	// field to: - Specify transaction success criteria - Specify custom
	// attributes on which you base rate plan charges.
	Attributes []*GoogleCloudApigeeV1Attribute `json:"attributes,omitempty"`

	// CreatedAt: Response only. Creation time of this environment as
	// milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Description: An overview of the API product. Include key information
	// about the API product that is not captured by other fields.
	Description string `json:"description,omitempty"`

	// DisplayName: The name to be displayed in the UI or developer portal
	// to developers registering for API access.
	DisplayName string `json:"displayName,omitempty"`

	// Environments: A comma-separated list of environment names to which
	// the API product is bound. Requests to environments that are not
	// listed are rejected. By specifying one or more environments, you can
	// bind the resources listed in the API product to a specific
	// environment, preventing developers from accessing those resources
	// through API proxies deployed in another environment. This setting is
	// used, for example, to prevent resources associated with API proxies
	// in 'prod' from being accessed by API proxies deployed in 'test'.
	Environments []string `json:"environments,omitempty"`

	// LastModifiedAt: Response only. Modified time of this environment as
	// milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: The internal name of the API Product. Characters you can use in
	// the name are restricted to: A-Z0-9._\-$ %. *NOTE:* The internal name
	// cannot be edited when updating the API product.
	Name string `json:"name,omitempty"`

	// Proxies: A comma-separated list of API proxy names to which this API
	// product is bound. By specifying API proxies, you can associate
	// resources in the API product with specific API proxies, preventing
	// developers from accessing those resources through other API proxies.
	// Edge rejects requests to API proxies that are not listed. *NOTE:* The
	// API proxy names must already exist in the specified environment as
	// they will be validated upon creation.
	Proxies []string `json:"proxies,omitempty"`

	// Quota: The number of request messages permitted per app by this API
	// product for the specified `quotaInterval` and `quotaTimeUnit`. For
	// example, a `quota` of 50, for a `quotaInterval` of 12 and a
	// `quotaTimeUnit` of hours means 50 requests are allowed every 12
	// hours.
	Quota string `json:"quota,omitempty"`

	// QuotaInterval: The time interval over which the number of request
	// messages is calculated.
	QuotaInterval string `json:"quotaInterval,omitempty"`

	// QuotaTimeUnit: The time unit defined for the `quotaInterval`. Valid
	// values include minute, hour, day, or month.
	QuotaTimeUnit string `json:"quotaTimeUnit,omitempty"`

	// Scopes: A comma-separated list of OAuth scopes that are validated at
	// runtime. Edge validates that the scopes in any access token presented
	// match the scopes defined in the OAuth policy assoicated with the API
	// product.
	Scopes []string `json:"scopes,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ApiResources") 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. "ApiResources") 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 *GoogleCloudApigeeV1ApiProduct) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ApiProduct
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ApiProductRef struct {
	// Apiproduct: Name of the API product.
	Apiproduct string `json:"apiproduct,omitempty"`

	// Status: Status of the API product.
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Apiproduct") 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. "Apiproduct") 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 *GoogleCloudApigeeV1ApiProductRef) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ApiProductRef
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ApiProxy: Metadata describing the API proxy
type GoogleCloudApigeeV1ApiProxy struct {
	// LatestRevisionId: The id of the most recently created revision for
	// this api proxy.
	LatestRevisionId string `json:"latestRevisionId,omitempty"`

	// MetaData: Metadata describing the API proxy.
	MetaData *GoogleCloudApigeeV1EntityMetadata `json:"metaData,omitempty"`

	// Name: Name of the API proxy.
	Name string `json:"name,omitempty"`

	// Revision: List of revisons defined for the API proxy.
	Revision []string `json:"revision,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "LatestRevisionId") 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. "LatestRevisionId") 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 *GoogleCloudApigeeV1ApiProxy) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ApiProxy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ApiProxyRevision: API proxy revision.
type GoogleCloudApigeeV1ApiProxyRevision struct {
	// Basepaths: Base URL of the API proxy.
	Basepaths []string `json:"basepaths,omitempty"`

	// ConfigurationVersion: Version of the API proxy configuration schema
	// to which the API proxy conforms. Currently, the only supported value
	// is 4.0 (`majorVersion.minorVersion`). This setting may be used in the
	// future to track the evolution of the API proxy format.
	ConfigurationVersion *GoogleCloudApigeeV1ConfigVersion `json:"configurationVersion,omitempty"`

	// ContextInfo: Revision number, app name, and organization for the API
	// proxy.
	ContextInfo string `json:"contextInfo,omitempty"`

	// CreatedAt: Time that the API proxy revision was created in
	// milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Description: Description of the API proxy revision.
	Description string `json:"description,omitempty"`

	// DisplayName: Human-readable name of the API proxy.
	DisplayName string `json:"displayName,omitempty"`

	// EntityMetaDataAsProperties: Metadata describing the API proxy
	// revision as a key-value map.
	EntityMetaDataAsProperties map[string]string `json:"entityMetaDataAsProperties,omitempty"`

	// LastModifiedAt: Time that the API proxy revision was last modified in
	// milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: Name of the API proxy.
	Name string `json:"name,omitempty"`

	// Policies: List of policy names included in the API proxy revision..
	Policies []string `json:"policies,omitempty"`

	// Proxies: List of proxy names included in the API proxy revision.
	Proxies []string `json:"proxies,omitempty"`

	// ProxyEndpoints: List of ProxyEndpoints in the `/proxies` directory of
	// the API proxy. Typically, this element is included only when the API
	// proxy was created using the Edge UI. This is a 'manifest' setting
	// designed to provide visibility into the contents of the API proxy.
	ProxyEndpoints []string `json:"proxyEndpoints,omitempty"`

	// ResourceFiles: List of resource files included in the API proxy
	// revision.
	ResourceFiles *GoogleCloudApigeeV1ResourceFiles `json:"resourceFiles,omitempty"`

	// Resources: List of the resources included in the API proxy revision
	// formatted as "{type}://{name}".
	Resources []string `json:"resources,omitempty"`

	// Revision: API proxy revision.
	Revision string `json:"revision,omitempty"`

	// SharedFlows: List of the shared flows included in the API proxy
	// revision.
	SharedFlows []string `json:"sharedFlows,omitempty"`

	// Spec: OpenAPI Specification that is associated with the API proxy.
	// The value is set to a URL or to a path in the specification store.
	Spec string `json:"spec,omitempty"`

	// TargetEndpoints: List of TargetEndpoints in the `/targets` directory
	// of the API proxy. Typically, this element is included only when the
	// API proxy was created using the Edge UI. This is a 'manifest' setting
	// designed to provide visibility into the contents of the API proxy.
	TargetEndpoints []string `json:"targetEndpoints,omitempty"`

	// TargetServers: List of TargetServers referenced in any TargetEndpoint
	// in the API proxy. Typically, you will see this element only when the
	// API proxy was created using the Edge UI. This is a 'manifest' setting
	// designed to provide visibility into the contents of the API proxy.
	TargetServers []string `json:"targetServers,omitempty"`

	// Targets: List of the targets included in the API proxy revision.
	Targets []string `json:"targets,omitempty"`

	// Teams: List of the teams included in the API proxy revision.
	Teams []string `json:"teams,omitempty"`

	// Type: Type. Set to `Application`. Maintained for compatibility with
	// the Apigee Edge API.
	Type string `json:"type,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Basepaths") 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. "Basepaths") 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 *GoogleCloudApigeeV1ApiProxyRevision) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ApiProxyRevision
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1App struct {
	// ApiProducts: List of API products associated with the app.
	ApiProducts []*GoogleCloudApigeeV1ApiProductRef `json:"apiProducts,omitempty"`

	// AppId: ID of the app.
	AppId string `json:"appId,omitempty"`

	// Attributes: List of attributes.
	Attributes []*GoogleCloudApigeeV1Attribute `json:"attributes,omitempty"`

	// CallbackUrl: Callback URL used by OAuth 2.0 authorization servers to
	// communicate authorization codes back to apps.
	CallbackUrl string `json:"callbackUrl,omitempty"`

	// CompanyName: Name of the company that owns the app.
	CompanyName string `json:"companyName,omitempty"`

	// CreatedAt: Output only. Unix time when the app was created.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Credentials: Output only. Set of credentials for the app. Credentials
	// are API key/secret pairs associated with API products.
	Credentials []*GoogleCloudApigeeV1Credential `json:"credentials,omitempty"`

	// DeveloperId: ID of the developer.
	DeveloperId string `json:"developerId,omitempty"`

	// KeyExpiresIn: Duration, in milliseconds, of the consumer key that
	// will be generated for the app. The default value, -1, indicates an
	// infinite validity period. Once set, the expiration can't be updated.
	// json key: keyExpiresIn
	KeyExpiresIn int64 `json:"keyExpiresIn,omitempty,string"`

	// LastModifiedAt: Output only. Last modified time as milliseconds since
	// epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: Name of the app.
	Name string `json:"name,omitempty"`

	// Scopes: Scopes to apply to the app. The specified scope names must
	// already exist on the API product that you associate with the app.
	Scopes []string `json:"scopes,omitempty"`

	// Status: Status of the credential.
	Status string `json:"status,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ApiProducts") 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. "ApiProducts") 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 *GoogleCloudApigeeV1App) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1App
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1AsyncQuery struct {
	// Created: Creation time of the query.
	Created string `json:"created,omitempty"`

	// Error: Error is set when query fails.
	Error string `json:"error,omitempty"`

	// ExecutionTime: ExecutionTime is available only after the query is
	// completed.
	ExecutionTime string `json:"executionTime,omitempty"`

	// Name: Asynchronous Query Name.
	Name string `json:"name,omitempty"`

	// QueryParams: Contains information like metrics, dimenstions etc of
	// the AsyncQuery.
	QueryParams *GoogleCloudApigeeV1QueryMetadata `json:"queryParams,omitempty"`

	// ReportDefinitionId: Asynchronous Report ID.
	ReportDefinitionId string `json:"reportDefinitionId,omitempty"`

	// Result: Result is available only after the query is completed.
	Result *GoogleCloudApigeeV1AsyncQueryResult `json:"result,omitempty"`

	// ResultFileSize: ResultFileSize is available only after the query is
	// completed.
	ResultFileSize string `json:"resultFileSize,omitempty"`

	// ResultRows: ResultRows is available only after the query is
	// completed.
	ResultRows int64 `json:"resultRows,omitempty,string"`

	// Self: Self link of the query. Example:
	// `/organizations/myorg/environments/myenv/queries/9cfc0d85-0f30-46d6-ae
	// 6f-318d0cb961bd`
	Self string `json:"self,omitempty"`

	// State: Query state could be "enqueued", "running", "completed",
	// "failed".
	State string `json:"state,omitempty"`

	// Updated: Last updated timestamp for the query.
	Updated string `json:"updated,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Created") 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. "Created") 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 *GoogleCloudApigeeV1AsyncQuery) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1AsyncQuery
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1AsyncQueryResult struct {
	// Expires: Query result will be unaccessable after this time.
	Expires string `json:"expires,omitempty"`

	// Self: Self link of the query results. Example:
	// `/organizations/myorg/environments/myenv/queries/9cfc0d85-0f30-46d6-ae
	// 6f-318d0cb961bd/result`
	Self string `json:"self,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Expires") 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. "Expires") 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 *GoogleCloudApigeeV1AsyncQueryResult) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1AsyncQueryResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Attribute: Key-value pair to store extra metadata.
type GoogleCloudApigeeV1Attribute struct {
	// Name: API key of the attribute.
	Name string `json:"name,omitempty"`

	// Value: Value of the attribute.
	Value string `json:"value,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1Attribute) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Attribute
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Attributes struct {
	// Attribute: List of attributes.
	Attribute []*GoogleCloudApigeeV1Attribute `json:"attribute,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Attribute") 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. "Attribute") 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 *GoogleCloudApigeeV1Attributes) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Attributes
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1CertInfo: An X.509 certificate as defined in RFC
// 5280.
type GoogleCloudApigeeV1CertInfo struct {
	// BasicConstraints: The X.509 basic constraints extension.
	BasicConstraints string `json:"basicConstraints,omitempty"`

	// ExpiryDate: The X.509 validity / notAfter in milliseconds since the
	// epoch.
	ExpiryDate int64 `json:"expiryDate,omitempty,string"`

	// IsValid: "Yes" if certificate is valid, "No" if expired and "Not yet"
	// if not yet valid.
	IsValid string `json:"isValid,omitempty"`

	// Issuer: The X.509 issuer.
	Issuer string `json:"issuer,omitempty"`

	// PublicKey: The public key component of the X.509 subject public key
	// info.
	PublicKey string `json:"publicKey,omitempty"`

	// SerialNumber: The X.509 serial number.
	SerialNumber string `json:"serialNumber,omitempty"`

	// SigAlgName: The X.509 signatureAlgorithm.
	SigAlgName string `json:"sigAlgName,omitempty"`

	// Subject: The X.509 subject.
	Subject string `json:"subject,omitempty"`

	// SubjectAlternativeNames: The X.509 subject alternative names (SANs)
	// extension.
	SubjectAlternativeNames []string `json:"subjectAlternativeNames,omitempty"`

	// ValidFrom: The X.509 validity / notBefore in milliseconds since the
	// epoch.
	ValidFrom int64 `json:"validFrom,omitempty,string"`

	// Version: The X.509 version.
	Version int64 `json:"version,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BasicConstraints") 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. "BasicConstraints") 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 *GoogleCloudApigeeV1CertInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1CertInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Certificate struct {
	// CertInfo: The chain of certificates under this name.
	CertInfo []*GoogleCloudApigeeV1CertInfo `json:"certInfo,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CertInfo") 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. "CertInfo") 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 *GoogleCloudApigeeV1Certificate) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Certificate
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1CommonNameConfig struct {
	MatchWildCards bool `json:"matchWildCards,omitempty"`

	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MatchWildCards") 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. "MatchWildCards") 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 *GoogleCloudApigeeV1CommonNameConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1CommonNameConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ConfigVersion: Version of the API proxy
// configuration schema. Currently, only 4.0 is supported.
type GoogleCloudApigeeV1ConfigVersion struct {
	// MajorVersion: Major version of the API proxy configuration schema.
	MajorVersion int64 `json:"majorVersion,omitempty"`

	// MinorVersion: Minor version of the API proxy configuration schema.
	MinorVersion int64 `json:"minorVersion,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MajorVersion") 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. "MajorVersion") 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 *GoogleCloudApigeeV1ConfigVersion) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ConfigVersion
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Credential struct {
	// ApiProducts: List of API products this credential can be used for.
	ApiProducts []*GoogleCloudApigeeV1ApiProductRef `json:"apiProducts,omitempty"`

	// Attributes: List of attributes associated with this credential.
	Attributes []*GoogleCloudApigeeV1Attribute `json:"attributes,omitempty"`

	// ConsumerKey: Consumer key.
	ConsumerKey string `json:"consumerKey,omitempty"`

	// ConsumerSecret: Secret key.
	ConsumerSecret string `json:"consumerSecret,omitempty"`

	// ExpiresAt: Time the credential will expire in milliseconds since
	// epoch.
	ExpiresAt int64 `json:"expiresAt,omitempty,string"`

	// IssuedAt: Time the credential was issued in milliseconds since epoch.
	IssuedAt int64 `json:"issuedAt,omitempty,string"`

	// Scopes: List of scopes to apply to the app. Specified scopes must
	// already exist on the API product that you associate with the app.
	Scopes []string `json:"scopes,omitempty"`

	// Status: Status of the credential.
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiProducts") 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. "ApiProducts") 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 *GoogleCloudApigeeV1Credential) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Credential
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1CustomReport struct {
	// ChartType: This field contains the chart type for the report
	ChartType string `json:"chartType,omitempty"`

	// Comments: Legacy field: not used. This field contains a list of
	// comments associated with custom report
	Comments []string `json:"comments,omitempty"`

	// CreatedAt: Output only. Unix time when the app was created json key:
	// createdAt
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Dimensions: This contains the list of dimensions for the report
	Dimensions []string `json:"dimensions,omitempty"`

	// DisplayName: This is the display name for the report
	DisplayName string `json:"displayName,omitempty"`

	// Environment: Output only. Environment name
	Environment string `json:"environment,omitempty"`

	// Filter: This field contains the filter expression
	Filter string `json:"filter,omitempty"`

	// FromTime: Legacy field: not used. Contains the from time for the
	// report
	FromTime string `json:"fromTime,omitempty"`

	// LastModifiedAt: Output only. Modified time of this entity as
	// milliseconds since epoch. json key: lastModifiedAt
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// LastViewedAt: Output only. Last viewed time of this entity as
	// milliseconds since epoch
	LastViewedAt int64 `json:"lastViewedAt,omitempty,string"`

	// Limit: Legacy field: not used This field contains the limit for the
	// result retrieved
	Limit string `json:"limit,omitempty"`

	// Metrics: Required. This contains the list of metrics
	Metrics []*GoogleCloudApigeeV1CustomReportMetric `json:"metrics,omitempty"`

	// Name: Required. Unique identifier for the report T his is a legacy
	// field used to encode custom report unique id
	Name string `json:"name,omitempty"`

	// Offset: Legacy field: not used. This field contains the offset for
	// the data
	Offset string `json:"offset,omitempty"`

	// Organization: Output only. Organization name
	Organization string `json:"organization,omitempty"`

	// Properties: This field contains report properties such as ui metadata
	// etc.
	Properties []*GoogleCloudApigeeV1ReportProperty `json:"properties,omitempty"`

	// SortByCols: Legacy field: not used much. Contains the list of sort by
	// columns
	SortByCols []string `json:"sortByCols,omitempty"`

	// SortOrder: Legacy field: not used much. Contains the sort order for
	// the sort columns
	SortOrder string `json:"sortOrder,omitempty"`

	// Tags: Legacy field: not used. This field contains a list of tags
	// associated with custom report
	Tags []string `json:"tags,omitempty"`

	// TimeUnit: This field contains the time unit of aggregation for the
	// report
	TimeUnit string `json:"timeUnit,omitempty"`

	// ToTime: Legacy field: not used. Contains the end time for the report
	ToTime string `json:"toTime,omitempty"`

	// Topk: Legacy field: not used. This field contains the top k parameter
	// value for restricting the result
	Topk string `json:"topk,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ChartType") 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. "ChartType") 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 *GoogleCloudApigeeV1CustomReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1CustomReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1CustomReportMetric: This encapsulates a metric
// property of the form sum(message_count) where name is message_count
// and function is sum
type GoogleCloudApigeeV1CustomReportMetric struct {
	// Function: aggregate function
	Function string `json:"function,omitempty"`

	// Name: name of the metric
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Function") 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. "Function") 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 *GoogleCloudApigeeV1CustomReportMetric) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1CustomReportMetric
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DataCollectorConfig: A DataCollector and its
// configuration.
type GoogleCloudApigeeV1DataCollectorConfig struct {
	// Name: The name of the data collector. Must be of the form
	// 'organizations/{org}/datacollectors/{dc}'.
	Name string `json:"name,omitempty"`

	// Type: The data type this DataCollector accepts.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - For future compatibility.
	//   "INTEGER" - For integer values.
	//   "FLOAT" - For float values.
	//   "STRING" - For string values.
	//   "BOOLEAN" - For boolean values.
	//   "DATETIME" - For datetime values.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1DataCollectorConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DataCollectorConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Datastore: The data store defines the connection
// to export data repository (Cloud Storage, BigQuery), including the
// credentials used to access the data repository.
type GoogleCloudApigeeV1Datastore struct {
	// CreateTime: Output only. Datastore create time, in milliseconds since
	// the epoch of 1970-01-01T00:00:00Z
	CreateTime int64 `json:"createTime,omitempty,string"`

	// DatastoreConfig: Datastore Configurations.
	DatastoreConfig *GoogleCloudApigeeV1DatastoreConfig `json:"datastoreConfig,omitempty"`

	// DisplayName: Required. Display name in UI
	DisplayName string `json:"displayName,omitempty"`

	// LastUpdateTime: Output only. Datastore last update time, in
	// milliseconds since the epoch of 1970-01-01T00:00:00Z
	LastUpdateTime int64 `json:"lastUpdateTime,omitempty,string"`

	// Org: Output only. Organization that the datastore belongs to
	Org string `json:"org,omitempty"`

	// Self: Output only. Resource link of Datastore. Example:
	// `/organizations/{org}/analytics/datastores/{uuid}`
	Self string `json:"self,omitempty"`

	// TargetType: Destination storage type. Supported types `gcs` or
	// `bigquery`.
	TargetType string `json:"targetType,omitempty"`

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

	// 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 *GoogleCloudApigeeV1Datastore) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Datastore
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DatastoreConfig: Configuration detail for
// datastore
type GoogleCloudApigeeV1DatastoreConfig struct {
	// BucketName: Name of the Cloud Storage bucket. Required for `gcs`
	// target_type.
	BucketName string `json:"bucketName,omitempty"`

	// DatasetName: BigQuery dataset name Required for `bigquery`
	// target_type.
	DatasetName string `json:"datasetName,omitempty"`

	// Path: Path of Cloud Storage bucket Required for `gcs` target_type.
	Path string `json:"path,omitempty"`

	// ProjectId: Required. GCP project in which the datastore exists
	ProjectId string `json:"projectId,omitempty"`

	// TablePrefix: Prefix of BigQuery table Required for `bigquery`
	// target_type.
	TablePrefix string `json:"tablePrefix,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BucketName") 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. "BucketName") 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 *GoogleCloudApigeeV1DatastoreConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DatastoreConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DateRange: Date range of the data to export.
type GoogleCloudApigeeV1DateRange struct {
	// End: Required. End date (exclusive) of the data to export in the
	// format `yyyy-mm-dd`. The date range ends at 00:00:00 UTC on the end
	// date- which will not be in the output.
	End string `json:"end,omitempty"`

	// Start: Required. Start date of the data to export in the format
	// `yyyy-mm-dd`. The date range begins at 00:00:00 UTC on the start
	// date.
	Start string `json:"start,omitempty"`

	// ForceSendFields is a list of field names (e.g. "End") 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. "End") 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 *GoogleCloudApigeeV1DateRange) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DateRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1DebugMask struct {
	// FaultJSONPaths: List of JSON paths that specify the JSON elements to
	// be filtered from JSON payloads in error flows.
	FaultJSONPaths []string `json:"faultJSONPaths,omitempty"`

	// FaultXPaths: List of XPaths that specify the XML elements to be
	// filtered from XML payloads in error flows.
	FaultXPaths []string `json:"faultXPaths,omitempty"`

	// Name: Name of the debug mask.
	Name string `json:"name,omitempty"`

	// Namespaces: Map of namespaces to URIs.
	Namespaces map[string]string `json:"namespaces,omitempty"`

	// RequestJSONPaths: List of JSON paths that specify the JSON elements
	// to be filtered from JSON request message payloads.
	RequestJSONPaths []string `json:"requestJSONPaths,omitempty"`

	// RequestXPaths: List of XPaths that specify the XML elements to be
	// filtered from XML request message payloads.
	RequestXPaths []string `json:"requestXPaths,omitempty"`

	// ResponseJSONPaths: List of JSON paths that specify the JSON elements
	// to be filtered from JSON response message payloads.
	ResponseJSONPaths []string `json:"responseJSONPaths,omitempty"`

	// ResponseXPaths: List of XPaths that specify the XML elements to be
	// filtered from XML response message payloads.
	ResponseXPaths []string `json:"responseXPaths,omitempty"`

	// Variables: List of variables that should be masked from the debug
	// output.
	Variables []string `json:"variables,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "FaultJSONPaths") 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. "FaultJSONPaths") 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 *GoogleCloudApigeeV1DebugMask) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DebugMask
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1DebugSession struct {
	// Count: Optional. The number of request to be traced. Min = 1, Max =
	// 15, Default = 10.
	Count int64 `json:"count,omitempty"`

	// Filter: Optional. A conditional statement which is evaluated against
	// the request message to determine if it should be traced. Syntax
	// matches that of on API Proxy bundle flow Condition.
	Filter string `json:"filter,omitempty"`

	// Name: A unique ID for this DebugSession.
	Name string `json:"name,omitempty"`

	// Timeout: Optional. The time in seconds after which this DebugSession
	// should end. This value will override the value in query param, if
	// both are provided.
	Timeout int64 `json:"timeout,omitempty,string"`

	// Tracesize: Optional. The maximum number of bytes captured from the
	// response payload. Min = 0, Max = 5120, Default = 5120.
	Tracesize int64 `json:"tracesize,omitempty"`

	// Validity: Optional. The length of time, in seconds, that this debug
	// session is valid, starting from when it's received in the control
	// plane. Min = 1, Max = 15, Default = 10.
	Validity int64 `json:"validity,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Count") 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. "Count") 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 *GoogleCloudApigeeV1DebugSession) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DebugSession
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DebugSessionTransaction: A transaction contains
// all of the debug information of the entire message flow of an API
// call processed by the runtime plane. The information is collected and
// recorded at critical points of the message flow in the runtime
// apiproxy.
type GoogleCloudApigeeV1DebugSessionTransaction struct {
	// Completed: Flag indicating whether a transaction is completed or not
	Completed bool `json:"completed,omitempty"`

	// Point: List of debug data collected by runtime plane at various
	// defined points in the flow.
	Point []*GoogleCloudApigeeV1Point `json:"point,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Completed") 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. "Completed") 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 *GoogleCloudApigeeV1DebugSessionTransaction) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DebugSessionTransaction
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1DeleteCustomReportResponse struct {
	// Message: The response contains only a message field.
	Message string `json:"message,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Message") 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. "Message") 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 *GoogleCloudApigeeV1DeleteCustomReportResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeleteCustomReportResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Deployment struct {
	// ApiProxy: API proxy.
	ApiProxy string `json:"apiProxy,omitempty"`

	// BasePath: Base path for the deployment.
	BasePath string `json:"basePath,omitempty"`

	// DeployStartTime: Time the API proxy was marked `deployed` in the
	// control plane in millisconds since epoch.
	DeployStartTime int64 `json:"deployStartTime,omitempty,string"`

	// Environment: Environment.
	Environment string `json:"environment,omitempty"`

	// Errors: Errors reported for this deployment. Populated only when
	// state == ERROR. This field is not populated in List APIs.
	Errors []*GoogleRpcStatus `json:"errors,omitempty"`

	// Instances: Status reported by each runtime instance. This field is
	// not populated in List APIs.
	Instances []*GoogleCloudApigeeV1InstanceDeploymentStatus `json:"instances,omitempty"`

	// Pods: Status reported by runtime pods. This field is not populated
	// for List APIs.
	Pods []*GoogleCloudApigeeV1PodStatus `json:"pods,omitempty"`

	// Revision: API proxy revision.
	Revision string `json:"revision,omitempty"`

	// RouteConflicts: Conflicts in the desired state routing configuration.
	// The presence of conflicts does not cause the state to be ERROR, but
	// it will mean that some of the deployments basepaths are not routed to
	// its environment. If the conflicts change, the state will transition
	// to PROGRESSING until the latest configuration is rolled out to all
	// instances. This field is not populated in List APIs.
	RouteConflicts []*GoogleCloudApigeeV1DeploymentChangeReportRoutingConflict `json:"routeConflicts,omitempty"`

	// State: Current state of the deployment. This field is not populated
	// in List APIs.
	//
	// Possible values:
	//   "RUNTIME_STATE_UNSPECIFIED" - This value should never be returned.
	//   "READY" - The runtime has loaded the deployment.
	//   "PROGRESSING" - The deployment is not fully ready in the runtime.
	//   "ERROR" - There is an error with the deployment that requires
	// intervention.
	State string `json:"state,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ApiProxy") 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. "ApiProxy") 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 *GoogleCloudApigeeV1Deployment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Deployment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DeploymentChangeReport: Response for
// GenerateDeployChangeReport and GenerateUndeployChangeReport. This
// report contains any validation failures that would cause the
// deployment to be rejected, as well changes and conflicts in routing
// that may occur due to the new deployment. The existence of a routing
// warning does not necessarily imply that the deployment request is
// bad, if the desired state of the deployment request is to effect a
// routing change. The primary purposes of the routing messages are: 1)
// To inform users of routing changes that may have an effect on traffic
// currently being routed to other existing deployments. 2) To warn
// users if some basepath in the proxy will not receive traffic due to
// an existing deployment having already claimed that basepath. The
// presence of routing conflicts/changes will not cause non-dry-run
// DeployApiProxy/UndeployApiProxy requests to be rejected.
type GoogleCloudApigeeV1DeploymentChangeReport struct {
	// RoutingChanges: All routing changes that may result from a deployment
	// request.
	RoutingChanges []*GoogleCloudApigeeV1DeploymentChangeReportRoutingChange `json:"routingChanges,omitempty"`

	// RoutingConflicts: All basepath conflicts detected for a deployment
	// request.
	RoutingConflicts []*GoogleCloudApigeeV1DeploymentChangeReportRoutingConflict `json:"routingConflicts,omitempty"`

	// ValidationErrors: Validation errors that would cause the deployment
	// change request to be rejected.
	ValidationErrors *GoogleRpcPreconditionFailure `json:"validationErrors,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "RoutingChanges") 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. "RoutingChanges") 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 *GoogleCloudApigeeV1DeploymentChangeReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeploymentChangeReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DeploymentChangeReportRoutingChange: Describes a
// potential routing change that may occur as a result of some
// deployment operation.
type GoogleCloudApigeeV1DeploymentChangeReportRoutingChange struct {
	// Description: A human-readable description of this routing change.
	Description string `json:"description,omitempty"`

	// EnvironmentGroup: The name of the environment group affected by this
	// routing change.
	EnvironmentGroup string `json:"environmentGroup,omitempty"`

	// FromDeployment: The basepath/deployment that may stop receiving some
	// traffic.
	FromDeployment *GoogleCloudApigeeV1DeploymentChangeReportRoutingDeployment `json:"fromDeployment,omitempty"`

	// ShouldSequenceRollout: True if using sequenced rollout would make
	// this routing change safer. Note: this does not necessarily imply that
	// automated sequenced rollout mode is supported for the operation.
	ShouldSequenceRollout bool `json:"shouldSequenceRollout,omitempty"`

	// ToDeployment: The basepath/deployment that may start receiving that
	// traffic. May be null if no deployment is able to receive the traffic.
	ToDeployment *GoogleCloudApigeeV1DeploymentChangeReportRoutingDeployment `json:"toDeployment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *GoogleCloudApigeeV1DeploymentChangeReportRoutingChange) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeploymentChangeReportRoutingChange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DeploymentChangeReportRoutingConflict: Describes a
// routing conflict that may cause a deployment not to receive traffic
// at some basepath.
type GoogleCloudApigeeV1DeploymentChangeReportRoutingConflict struct {
	// ConflictingDeployment: The existing basepath/deployment causing the
	// conflict.
	ConflictingDeployment *GoogleCloudApigeeV1DeploymentChangeReportRoutingDeployment `json:"conflictingDeployment,omitempty"`

	// Description: A human-readable description of this conflict.
	Description string `json:"description,omitempty"`

	// EnvironmentGroup: The name of the environment group in which this
	// conflict exists.
	EnvironmentGroup string `json:"environmentGroup,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ConflictingDeployment") 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. "ConflictingDeployment") 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 *GoogleCloudApigeeV1DeploymentChangeReportRoutingConflict) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeploymentChangeReportRoutingConflict
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DeploymentChangeReportRoutingDeployment: A tuple
// representing a basepath and the deployment containing it.
type GoogleCloudApigeeV1DeploymentChangeReportRoutingDeployment struct {
	// ApiProxy: The name of the deployed proxy revision containing the
	// basepath.
	ApiProxy string `json:"apiProxy,omitempty"`

	// Basepath: The basepath receiving traffic.
	Basepath string `json:"basepath,omitempty"`

	// Environment: The name of the environment in which the proxy is
	// deployed.
	Environment string `json:"environment,omitempty"`

	// Revision: The name of the deployed proxy revision containing the
	// basepath.
	Revision string `json:"revision,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiProxy") 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. "ApiProxy") 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 *GoogleCloudApigeeV1DeploymentChangeReportRoutingDeployment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeploymentChangeReportRoutingDeployment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1DeploymentConfig struct {
	// Attributes: Additional key-value metadata about the deployment.
	Attributes map[string]string `json:"attributes,omitempty"`

	// BasePath: Base path where the application needs to be hosted. Default
	// value is assumed to be "/".
	BasePath string `json:"basePath,omitempty"`

	// Location: The location of the proxy bundle, as a uri.
	Location string `json:"location,omitempty"`

	// Name: The name of the API or shared flow revision to be deployed.
	// Must be of the form 'organizations/{org}/apis/{api}/revisions/{rev}'
	// or 'organizations/{org}/sharedflows/{sf}/revisions/{rev}'.
	Name string `json:"name,omitempty"`

	// ProxyUid: The uid of the proxy revision.
	ProxyUid string `json:"proxyUid,omitempty"`

	// Uid: A unique id that will only change if the deployment is deleted
	// and recreated.
	Uid string `json:"uid,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Attributes") 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. "Attributes") 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 *GoogleCloudApigeeV1DeploymentConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeploymentConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Developer struct {
	// AccessType: Access type.
	AccessType string `json:"accessType,omitempty"`

	// AppFamily: Developer app family.
	AppFamily string `json:"appFamily,omitempty"`

	// Apps: List of apps associated with the developer.
	Apps []string `json:"apps,omitempty"`

	// Attributes: Optional. Developer attributes (name/value pairs). The
	// custom attribute limit is 18.
	Attributes []*GoogleCloudApigeeV1Attribute `json:"attributes,omitempty"`

	// Companies: List of companies associated with the developer.
	Companies []string `json:"companies,omitempty"`

	// CreatedAt: Output only. Time at which the developer was created in
	// milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// DeveloperId: ID of the developer. **Note**: IDs are generated
	// internally by Apigee and are not guaranteed to stay the same over
	// time.
	DeveloperId string `json:"developerId,omitempty"`

	// Email: Required. Email address of the developer. This value is used
	// to uniquely identify the developer in Apigee hybrid.
	Email string `json:"email,omitempty"`

	// FirstName: Required. First name of the developer.
	FirstName string `json:"firstName,omitempty"`

	// LastModifiedAt: Output only. Time at which the developer was last
	// modified in milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// LastName: Required. Last name of the developer.
	LastName string `json:"lastName,omitempty"`

	// OrganizationName: Output only. Name of the Apigee organization in
	// which the developer resides.
	OrganizationName string `json:"organizationName,omitempty"`

	// Status: Output only. Status of the developer. Valid values are
	// `active` and `inactive`.
	Status string `json:"status,omitempty"`

	// UserName: Required. User name of the developer. Not used by Apigee
	// hybrid.
	UserName string `json:"userName,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AccessType") 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. "AccessType") 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 *GoogleCloudApigeeV1Developer) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Developer
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1DeveloperApp struct {
	// ApiProducts: List of API products associated with the developer app.
	ApiProducts []string `json:"apiProducts,omitempty"`

	// AppFamily: Developer app family.
	AppFamily string `json:"appFamily,omitempty"`

	// AppId: ID of the developer app.
	AppId string `json:"appId,omitempty"`

	// Attributes: List of attributes for the developer app.
	Attributes []*GoogleCloudApigeeV1Attribute `json:"attributes,omitempty"`

	// CallbackUrl: Callback URL used by OAuth 2.0 authorization servers to
	// communicate authorization codes back to developer apps.
	CallbackUrl string `json:"callbackUrl,omitempty"`

	// CreatedAt: Output only. Time the developer app was created in
	// milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Credentials: Output only. Set of credentials for the developer app
	// consisting of the consumer key/secret pairs associated with the API
	// products.
	Credentials []*GoogleCloudApigeeV1Credential `json:"credentials,omitempty"`

	// DeveloperId: ID of the developer.
	DeveloperId string `json:"developerId,omitempty"`

	// KeyExpiresIn: Expiration time, in milliseconds, for the consumer key
	// that is generated for the developer app. If not set or left to the
	// default value of `-1`, the API key never expires. The expiration time
	// can't be updated after it is set.
	KeyExpiresIn int64 `json:"keyExpiresIn,omitempty,string"`

	// LastModifiedAt: Output only. Time the developer app was modified in
	// milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: Name of the developer app.
	Name string `json:"name,omitempty"`

	// Scopes: Scopes to apply to the developer app. The specified scopes
	// must already exist for the API product that you associate with the
	// developer app.
	Scopes []string `json:"scopes,omitempty"`

	// Status: Status of the credential. Valid values include `approved` or
	// `revoked`.
	Status string `json:"status,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ApiProducts") 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. "ApiProducts") 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 *GoogleCloudApigeeV1DeveloperApp) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeveloperApp
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1DeveloperAppKey struct {
	// ApiProducts: List of API products for which the credential can be
	// used. **Note**: Do not specify the list of API products when creating
	// a consumer key and secret for a developer app. Instead, use the
	// UpdateDeveloperAppKey API to make the association after the consumer
	// key and secret are created.
	ApiProducts []interface{} `json:"apiProducts,omitempty"`

	// Attributes: List of attributes associated with the credential.
	Attributes []*GoogleCloudApigeeV1Attribute `json:"attributes,omitempty"`

	// ConsumerKey: Consumer key.
	ConsumerKey string `json:"consumerKey,omitempty"`

	// ConsumerSecret: Secret key.
	ConsumerSecret string `json:"consumerSecret,omitempty"`

	// ExpiresAt: Time the developer app expires in milliseconds since
	// epoch.
	ExpiresAt int64 `json:"expiresAt,omitempty,string"`

	// IssuedAt: Time the developer app was created in milliseconds since
	// epoch.
	IssuedAt int64 `json:"issuedAt,omitempty,string"`

	// Scopes: Scopes to apply to the app. The specified scope names must
	// already be defined for the API product that you associate with the
	// app.
	Scopes []string `json:"scopes,omitempty"`

	// Status: Status of the credential. Valid values include `approved` or
	// `revoked`.
	Status string `json:"status,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ApiProducts") 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. "ApiProducts") 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 *GoogleCloudApigeeV1DeveloperAppKey) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DeveloperAppKey
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1DimensionMetric: This message type encapsulates a
// metric grouped by dimension.
type GoogleCloudApigeeV1DimensionMetric struct {
	// Metrics: This field contains a list of metrics.
	Metrics []*GoogleCloudApigeeV1Metric `json:"metrics,omitempty"`

	// Name: This field contains the name of the dimension.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Metrics") 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. "Metrics") 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 *GoogleCloudApigeeV1DimensionMetric) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1DimensionMetric
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1EntityMetadata: Metadata common to many entities
// in this API.
type GoogleCloudApigeeV1EntityMetadata struct {
	// CreatedAt: Time at which the API proxy was created, in milliseconds
	// since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// LastModifiedAt: Time at which the API proxy was most recently
	// modified, in milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// SubType: The type of entity described
	SubType string `json:"subType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreatedAt") 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. "CreatedAt") 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 *GoogleCloudApigeeV1EntityMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1EntityMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Environment struct {
	// CreatedAt: Output only. Creation time of this environment as
	// milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Description: Optional. Description of the environment.
	Description string `json:"description,omitempty"`

	// DisplayName: Optional. Display name for this environment.
	DisplayName string `json:"displayName,omitempty"`

	// LastModifiedAt: Output only. Last modification time of this
	// environment as milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: Required. Name of the environment. Values must match the
	// regular expression `^[.\\p{Alnum}-_]{1,255}$`
	Name string `json:"name,omitempty"`

	// Properties: Optional. Key-value pairs that may be used for
	// customizing the environment.
	Properties *GoogleCloudApigeeV1Properties `json:"properties,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CreatedAt") 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. "CreatedAt") 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 *GoogleCloudApigeeV1Environment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Environment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1EnvironmentConfig struct {
	// CreateTime: The time at which this environment config was created.
	CreateTime string `json:"createTime,omitempty"`

	// DataCollectors: The list of Data Collectors used by deployments in
	// the environment.
	DataCollectors []*GoogleCloudApigeeV1DataCollectorConfig `json:"dataCollectors,omitempty"`

	// DebugMask: Debug mask that applies to all deployments in the
	// environment.
	DebugMask *GoogleCloudApigeeV1DebugMask `json:"debugMask,omitempty"`

	// Deployments: A list of deployments in the environment
	Deployments []*GoogleCloudApigeeV1DeploymentConfig `json:"deployments,omitempty"`

	// FeatureFlags: Feature flags inherited from the org and environment
	// parents.
	FeatureFlags map[string]string `json:"featureFlags,omitempty"`

	// Flowhooks: A list of flow hooks in the environment.
	Flowhooks []*GoogleCloudApigeeV1FlowHookConfig `json:"flowhooks,omitempty"`

	// Keystores: A list of keystores in the environment.
	Keystores []*GoogleCloudApigeeV1KeystoreConfig `json:"keystores,omitempty"`

	// Name: The name of the environment config. Must be of the form
	// 'organizations/{org}/environments/{env}/configs/{config_id}
	Name string `json:"name,omitempty"`

	// Provider: This field can be used by the control plane to add some
	// context information about itself. This information could help detect
	// the source of the document during diagnostics and debugging.
	Provider string `json:"provider,omitempty"`

	// PubsubTopic: Name of the pubsub topic for this environment.
	PubsubTopic string `json:"pubsubTopic,omitempty"`

	// ResourceReferences: A list of resource references in the environment.
	ResourceReferences []*GoogleCloudApigeeV1ReferenceConfig `json:"resourceReferences,omitempty"`

	// Resources: A list of resource versions in the environment.
	Resources []*GoogleCloudApigeeV1ResourceConfig `json:"resources,omitempty"`

	// RevisionId: Revision id that defines the ordering on the environment
	// config. The higher the revision, the more recently the configuration
	// was deployed.
	RevisionId int64 `json:"revisionId,omitempty,string"`

	// SequenceNumber: DEPRECATED: use revision_id
	SequenceNumber int64 `json:"sequenceNumber,omitempty,string"`

	// Targets: A list of target servers in the environment. Disabled target
	// servers are not included.
	Targets []*GoogleCloudApigeeV1TargetServerConfig `json:"targets,omitempty"`

	// Uid: A unique id for the environment config that will only change if
	// the environment is deleted and recreated.
	Uid string `json:"uid,omitempty"`

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

	// 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 *GoogleCloudApigeeV1EnvironmentConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1EnvironmentConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1EnvironmentGroup: EnvironmentGroup configuration.
// An environment group is used to group one or more Apigee environments
// under a single host name.
type GoogleCloudApigeeV1EnvironmentGroup struct {
	// CreatedAt: Output only. The time at which the environment group was
	// created as milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Hostnames: Required. Host names for this environment group.
	Hostnames []string `json:"hostnames,omitempty"`

	// LastModifiedAt: Output only. The time at which the environment group
	// was last updated as milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: ID of the environment group.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CreatedAt") 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. "CreatedAt") 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 *GoogleCloudApigeeV1EnvironmentGroup) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1EnvironmentGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1EnvironmentGroupAttachment:
// EnvironmentGroupAttachment is a resource which defines an attachment
// of an environment to an environment group.
type GoogleCloudApigeeV1EnvironmentGroupAttachment struct {
	// CreatedAt: Output only. The time at which the environment group
	// attachment was created as milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Environment: Required. ID of the attached environment.
	Environment string `json:"environment,omitempty"`

	// Name: ID of the environment group attachment.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CreatedAt") 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. "CreatedAt") 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 *GoogleCloudApigeeV1EnvironmentGroupAttachment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1EnvironmentGroupAttachment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1EnvironmentGroupConfig: EnvironmentGroupConfig is
// a revisioned snapshot of an EnvironmentGroup and its associated
// routing rules.
type GoogleCloudApigeeV1EnvironmentGroupConfig struct {
	// Hostnames: Host names for the environment group.
	Hostnames []string `json:"hostnames,omitempty"`

	// Name: Name of the environment group in the following format:
	// `organizations/{org}/envgroups/{envgroup}`.
	Name string `json:"name,omitempty"`

	// RevisionId: Revision id that defines the ordering of the
	// EnvironmentGroupConfig resource. The higher the revision, the more
	// recently the configuration was deployed.
	RevisionId int64 `json:"revisionId,omitempty,string"`

	// RoutingRules: Ordered list of routing rules defining how traffic to
	// this environment group's hostnames should be routed to different
	// environments.
	RoutingRules []*GoogleCloudApigeeV1RoutingRule `json:"routingRules,omitempty"`

	// Uid: A unique id for the environment group config that will only
	// change if the environment group is deleted and recreated.
	Uid string `json:"uid,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Hostnames") 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. "Hostnames") 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 *GoogleCloudApigeeV1EnvironmentGroupConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1EnvironmentGroupConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Export: Details of an export job.
type GoogleCloudApigeeV1Export struct {
	// Created: Output only. Time the export job was created.
	Created string `json:"created,omitempty"`

	// DatastoreName: Name of the datastore that is the destination of the
	// export job [datastore]
	DatastoreName string `json:"datastoreName,omitempty"`

	// Description: Description of the export job.
	Description string `json:"description,omitempty"`

	// Error: Output only. Error is set when export fails
	Error string `json:"error,omitempty"`

	// ExecutionTime: Output only. Execution time for this export job. If
	// the job is still in progress, it will be set to the amount of time
	// that has elapsed since`created`, in seconds. Else, it will set to
	// (`updated` - `created`), in seconds.
	ExecutionTime string `json:"executionTime,omitempty"`

	// Name: Display name of the export job.
	Name string `json:"name,omitempty"`

	// Self: Output only. Self link of the export job. A URI that can be
	// used to retrieve the status of an export job. Example:
	// `/organizations/myorg/environments/myenv/analytics/exports/9cfc0d85-0f
	// 30-46d6-ae6f-318d0cb961bd`
	Self string `json:"self,omitempty"`

	// State: Output only. Status of the export job. Valid values include
	// `enqueued`, `running`, `completed`, and `failed`.
	State string `json:"state,omitempty"`

	// Updated: Output only. Time the export job was last updated.
	Updated string `json:"updated,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Created") 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. "Created") 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 *GoogleCloudApigeeV1Export) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Export
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ExportRequest: Request body for
// [CreateExportRequest]
type GoogleCloudApigeeV1ExportRequest struct {
	// CsvDelimiter: Optional. Delimiter used in the CSV file, if
	// `outputFormat` is set to `csv`. Defaults to the `,` (comma)
	// character. Supported delimiter characters include comma (`,`), pipe
	// (`|`), and tab (`\t`).
	CsvDelimiter string `json:"csvDelimiter,omitempty"`

	// DatastoreName: Required. Name of the preconfigured datastore.
	DatastoreName string `json:"datastoreName,omitempty"`

	// DateRange: Required. Date range of the data to export.
	DateRange *GoogleCloudApigeeV1DateRange `json:"dateRange,omitempty"`

	// Description: Optional. Description of the export job.
	Description string `json:"description,omitempty"`

	// Name: Required. Display name of the export job.
	Name string `json:"name,omitempty"`

	// OutputFormat: Optional. Output format of the export. Valid values
	// include: `csv` or `json`. Defaults to `json`. Note: Configure the
	// delimiter for CSV output using the `csvDelimiter` property.
	OutputFormat string `json:"outputFormat,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CsvDelimiter") 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. "CsvDelimiter") 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 *GoogleCloudApigeeV1ExportRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ExportRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1FlowHook struct {
	// ContinueOnError: Optional. Flag that specifies whether execution
	// should continue if the flow hook throws an exception. Set to `true`
	// to continue execution. Set to `false` to stop execution if the flow
	// hook throws an exception.Defaults to `true`.
	ContinueOnError bool `json:"continueOnError,omitempty"`

	// Description: Description of the flow hook.
	Description string `json:"description,omitempty"`

	// FlowHookPoint: Output only. Where in the API call flow the flow hook
	// is invoked. Must be one of `PreProxyFlowHook`, `PostProxyFlowHook`,
	// `PreTargetFlowHook`, or `PostTargetFlowHook`.
	FlowHookPoint string `json:"flowHookPoint,omitempty"`

	// SharedFlow: Shared flow attached to this flow hook, or empty if there
	// is none attached.
	SharedFlow string `json:"sharedFlow,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ContinueOnError") 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. "ContinueOnError") 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 *GoogleCloudApigeeV1FlowHook) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1FlowHook
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1FlowHookConfig struct {
	// ContinueOnError: Should the flow abort after an error in the flow
	// hook. Should default to true if unset.
	ContinueOnError bool `json:"continueOnError,omitempty"`

	// Name: The name of the flow hook. Must be of the form
	// 'organizations/{org}/environments/{env}/flowhooks/{point}'. Known
	// points are PreProxyFlowHook, PostProxyFlowHook, PreTargetFlowHook,
	// and PostTargetFlowHook
	Name string `json:"name,omitempty"`

	// SharedFlowName: The name of the shared flow to invoke. Must be of the
	// form 'organizations/{org}/sharedflows/{sharedflow}'.
	SharedFlowName string `json:"sharedFlowName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContinueOnError") 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. "ContinueOnError") 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 *GoogleCloudApigeeV1FlowHookConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1FlowHookConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1GetSyncAuthorizationRequest: Request for
// GetSyncAuthorization.
type GoogleCloudApigeeV1GetSyncAuthorizationRequest struct {
}

type GoogleCloudApigeeV1IngressConfig struct {
	// EnvironmentGroups: List of environment groups in the organization.
	EnvironmentGroups []*GoogleCloudApigeeV1EnvironmentGroupConfig `json:"environmentGroups,omitempty"`

	// Name: Name of the resource in the following format:
	// `organizations/{org}/deployedIngressConfig`.
	Name string `json:"name,omitempty"`

	// RevisionCreateTime: Time at which the IngressConfig revision was
	// created.
	RevisionCreateTime string `json:"revisionCreateTime,omitempty"`

	// RevisionId: Revision id that defines the ordering on IngressConfig
	// resources. The higher the revision, the more recently the
	// configuration was deployed.
	RevisionId int64 `json:"revisionId,omitempty,string"`

	// Uid: A unique id for the ingress config that will only change if the
	// organization is deleted and recreated.
	Uid string `json:"uid,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "EnvironmentGroups")
	// 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. "EnvironmentGroups") 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 *GoogleCloudApigeeV1IngressConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1IngressConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Instance: Apigee runtime instance.
type GoogleCloudApigeeV1Instance struct {
	// CreatedAt: Output only. Time the instance was created in milliseconds
	// since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Description: Optional. Description of the instance.
	Description string `json:"description,omitempty"`

	// DiskEncryptionKeyName: Optional. Customer Managed Encryption Key
	// (CMEK) used for disk & volume encryption.
	DiskEncryptionKeyName string `json:"diskEncryptionKeyName,omitempty"`

	// DisplayName: Optional. Display name for the instance.
	DisplayName string `json:"displayName,omitempty"`

	// Host: Output only. Hostname or IP address of the exposed Apigee
	// endpoint used by clients to connect to the service.
	Host string `json:"host,omitempty"`

	// LastModifiedAt: Output only. Time the instance was last modified in
	// milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Location: Required. Compute Engine location where the instance
	// resides.
	Location string `json:"location,omitempty"`

	// Name: Required. Resource ID of the instance. Values must match the
	// regular expression `^a-z{0,30}[a-z\d]$`.
	Name string `json:"name,omitempty"`

	// Port: Output only. Port number of the exposed Apigee endpoint.
	Port string `json:"port,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CreatedAt") 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. "CreatedAt") 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 *GoogleCloudApigeeV1Instance) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Instance
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1InstanceAttachment: InstanceAttachment represents
// the installation of an environment onto an instance.
type GoogleCloudApigeeV1InstanceAttachment struct {
	// CreatedAt: Output only. Time the attachment was created in
	// milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Environment: ID of the attached environment.
	Environment string `json:"environment,omitempty"`

	// Name: Output only. ID of the attachment.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CreatedAt") 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. "CreatedAt") 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 *GoogleCloudApigeeV1InstanceAttachment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1InstanceAttachment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1InstanceDeploymentStatus: The status of a
// deployment as reported by a single instance.
type GoogleCloudApigeeV1InstanceDeploymentStatus struct {
	// DeployedRevisions: Revisions currently deployed in MPs.
	DeployedRevisions []*GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRevision `json:"deployedRevisions,omitempty"`

	// DeployedRoutes: The current routes deployed in the ingress routing
	// table. A route which is missing will be shown with no destination
	// environment.
	DeployedRoutes []*GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRoute `json:"deployedRoutes,omitempty"`

	// Instance: ID of the instance reporting the status.
	Instance string `json:"instance,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeployedRevisions")
	// 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. "DeployedRevisions") 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 *GoogleCloudApigeeV1InstanceDeploymentStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1InstanceDeploymentStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRevision:
// Revisions deployed in the MPs.
type GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRevision struct {
	// Percentage: The percentage of MP replicas reporting this revision
	Percentage int64 `json:"percentage,omitempty"`

	// Revision: The proxy revision reported as deployed.
	Revision string `json:"revision,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Percentage") 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. "Percentage") 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 *GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRevision) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRevision
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRoute: A route
// deployed in the ingress routing table.
type GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRoute struct {
	// Basepath: The basepath in the routing table.
	Basepath string `json:"basepath,omitempty"`

	// Envgroup: The envgroup where this route is installed.
	Envgroup string `json:"envgroup,omitempty"`

	// Environment: The destination environment. This will be empty if the
	// route is not yet reported.
	Environment string `json:"environment,omitempty"`

	// Percentage: The percentage of ingress replicas reporting this route.
	Percentage int64 `json:"percentage,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Basepath") 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. "Basepath") 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 *GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRoute) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1InstanceDeploymentStatusDeployedRoute
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1KeyAliasReference struct {
	// AliasId: The alias id. Must exist in the keystore referred to by
	// reference.
	AliasId string `json:"aliasId,omitempty"`

	// Reference: The reference name. Must be of the form:
	// organizations/{org}/environments/{env}/references/{ref}.
	Reference string `json:"reference,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AliasId") 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. "AliasId") 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 *GoogleCloudApigeeV1KeyAliasReference) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1KeyAliasReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1KeyValueMap: A collection of key, value string
// pairs
type GoogleCloudApigeeV1KeyValueMap struct {
	// Encrypted: Optional. If `true` entry values will be encrypted.
	Encrypted bool `json:"encrypted,omitempty"`

	// Name: Required. The id of the key value map.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Encrypted") 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. "Encrypted") 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 *GoogleCloudApigeeV1KeyValueMap) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1KeyValueMap
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Keystore: A datastore for Certificates and Aliases
type GoogleCloudApigeeV1Keystore struct {
	// Aliases: Output only. The aliases in this keystore.
	Aliases []string `json:"aliases,omitempty"`

	// Name: Required. The resource ID for this keystore. Values must match
	// the regular expression `[\w[:space:]-.]{1,255}`.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Aliases") 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. "Aliases") 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 *GoogleCloudApigeeV1Keystore) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Keystore
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1KeystoreConfig struct {
	// Aliases: Aliases in the keystore.
	Aliases []*GoogleCloudApigeeV1AliasRevisionConfig `json:"aliases,omitempty"`

	// Name: The resource name. Must be of the form:
	// 'organizations/{org}/environments/{env}/keystores/{keystore}'.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Aliases") 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. "Aliases") 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 *GoogleCloudApigeeV1KeystoreConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1KeystoreConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListApiProductsResponse struct {
	// ApiProduct: Lists all API product names defined for an organization.
	ApiProduct []*GoogleCloudApigeeV1ApiProduct `json:"apiProduct,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ApiProduct") 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. "ApiProduct") 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 *GoogleCloudApigeeV1ListApiProductsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListApiProductsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListApiProxiesResponse struct {
	Proxies []*GoogleCloudApigeeV1ApiProxy `json:"proxies,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Proxies") 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. "Proxies") 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 *GoogleCloudApigeeV1ListApiProxiesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListApiProxiesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListAppsResponse struct {
	App []*GoogleCloudApigeeV1App `json:"app,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "App") 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. "App") 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 *GoogleCloudApigeeV1ListAppsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListAppsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListAsyncQueriesResponse: The response for
// ListAsyncQueries.
type GoogleCloudApigeeV1ListAsyncQueriesResponse struct {
	// Queries: The asynchronous queries belong to requested resource name.
	Queries []*GoogleCloudApigeeV1AsyncQuery `json:"queries,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Queries") 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. "Queries") 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 *GoogleCloudApigeeV1ListAsyncQueriesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListAsyncQueriesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListCustomReportsResponse: This message
// encapsulates a list of custom report definitions
type GoogleCloudApigeeV1ListCustomReportsResponse struct {
	Qualifier []*GoogleCloudApigeeV1CustomReport `json:"qualifier,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Qualifier") 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. "Qualifier") 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 *GoogleCloudApigeeV1ListCustomReportsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListCustomReportsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListDatastoresResponse: The response for
// ListDatastores
type GoogleCloudApigeeV1ListDatastoresResponse struct {
	// Datastores: A list of datastores
	Datastores []*GoogleCloudApigeeV1Datastore `json:"datastores,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Datastores") 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. "Datastores") 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 *GoogleCloudApigeeV1ListDatastoresResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListDatastoresResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListDebugSessionsResponse struct {
	// NextPageToken: Page token that you can include in a
	// ListDebugSessionsRequest to retrieve the next page. If omitted, no
	// subsequent pages exist.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Sessions: Session info that includes debug session ID and the first
	// transaction creation timestamp.
	Sessions []*GoogleCloudApigeeV1Session `json:"sessions,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 *GoogleCloudApigeeV1ListDebugSessionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListDebugSessionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListDeploymentsResponse struct {
	// Deployments: List of deployments.
	Deployments []*GoogleCloudApigeeV1Deployment `json:"deployments,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Deployments") 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. "Deployments") 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 *GoogleCloudApigeeV1ListDeploymentsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListDeploymentsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListDeveloperAppsResponse struct {
	// App: List of developer apps and their credentials.
	App []*GoogleCloudApigeeV1DeveloperApp `json:"app,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "App") 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. "App") 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 *GoogleCloudApigeeV1ListDeveloperAppsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListDeveloperAppsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse: Response
// for ListEnvironmentGroupAttachments.
type GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse struct {
	// EnvironmentGroupAttachments: EnvironmentGroupAttachments for the
	// specified environment group.
	EnvironmentGroupAttachments []*GoogleCloudApigeeV1EnvironmentGroupAttachment `json:"environmentGroupAttachments,omitempty"`

	// NextPageToken: Page token that you can include in a
	// ListEnvironmentGroupAttachments request to retrieve the next page. If
	// omitted, no subsequent pages exist.
	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.
	// "EnvironmentGroupAttachments") 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.
	// "EnvironmentGroupAttachments") 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 *GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListEnvironmentGroupsResponse: Response for
// ListEnvironmentGroups.
type GoogleCloudApigeeV1ListEnvironmentGroupsResponse struct {
	// EnvironmentGroups: EnvironmentGroups in the specified organization.
	EnvironmentGroups []*GoogleCloudApigeeV1EnvironmentGroup `json:"environmentGroups,omitempty"`

	// NextPageToken: Page token that you can include in a
	// ListEnvironmentGroups request to retrieve the next page. If omitted,
	// no subsequent pages exist.
	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. "EnvironmentGroups")
	// 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. "EnvironmentGroups") 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 *GoogleCloudApigeeV1ListEnvironmentGroupsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListEnvironmentGroupsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListEnvironmentResourcesResponse: Response for
// ListEnvironmentResources
type GoogleCloudApigeeV1ListEnvironmentResourcesResponse struct {
	// ResourceFile: List of resources files.
	ResourceFile []*GoogleCloudApigeeV1ResourceFile `json:"resourceFile,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ResourceFile") 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. "ResourceFile") 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 *GoogleCloudApigeeV1ListEnvironmentResourcesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListEnvironmentResourcesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListExportsResponse: The response for ListExports
type GoogleCloudApigeeV1ListExportsResponse struct {
	// Exports: Details of the export jobs.
	Exports []*GoogleCloudApigeeV1Export `json:"exports,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Exports") 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. "Exports") 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 *GoogleCloudApigeeV1ListExportsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListExportsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListHybridIssuersResponse struct {
	// Issuers: Lists of hybrid services and its trusted issuer email ids.
	Issuers []*GoogleCloudApigeeV1ServiceIssuersMapping `json:"issuers,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Issuers") 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. "Issuers") 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 *GoogleCloudApigeeV1ListHybridIssuersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListHybridIssuersResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListInstanceAttachmentsResponse: Response for
// ListInstanceAttachments.
type GoogleCloudApigeeV1ListInstanceAttachmentsResponse struct {
	// Attachments: Attachments for the instance.
	Attachments []*GoogleCloudApigeeV1InstanceAttachment `json:"attachments,omitempty"`

	// NextPageToken: Page token that you can include in a
	// ListInstanceAttachments request to retrieve the next page of content.
	// If omitted, no subsequent pages exist.
	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. "Attachments") 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. "Attachments") 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 *GoogleCloudApigeeV1ListInstanceAttachmentsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListInstanceAttachmentsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ListInstancesResponse: Response for ListInstances.
type GoogleCloudApigeeV1ListInstancesResponse struct {
	// Instances: Instances in the specified organization.
	Instances []*GoogleCloudApigeeV1Instance `json:"instances,omitempty"`

	// NextPageToken: Page token that you can include in a ListInstance
	// request to retrieve the next page of content. If omitted, no
	// subsequent pages exist.
	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. "Instances") 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. "Instances") 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 *GoogleCloudApigeeV1ListInstancesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListInstancesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListOfDevelopersResponse struct {
	// Developer: List of developers.
	Developer []*GoogleCloudApigeeV1Developer `json:"developer,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Developer") 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. "Developer") 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 *GoogleCloudApigeeV1ListOfDevelopersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListOfDevelopersResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListOrganizationsResponse struct {
	// Organizations: List of Apigee organizations and associated GCP
	// projects.
	Organizations []*GoogleCloudApigeeV1OrganizationProjectMapping `json:"organizations,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Organizations") 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. "Organizations") 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 *GoogleCloudApigeeV1ListOrganizationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListOrganizationsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ListSharedFlowsResponse struct {
	SharedFlows []*GoogleCloudApigeeV1SharedFlow `json:"sharedFlows,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "SharedFlows") 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. "SharedFlows") 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 *GoogleCloudApigeeV1ListSharedFlowsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ListSharedFlowsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Metadata: This message type encapsulates
// additional information about query execution.
type GoogleCloudApigeeV1Metadata struct {
	// Errors: List of error messages as strings.
	Errors []string `json:"errors,omitempty"`

	// Notices: List of additional information such as data source, if
	// result was truncated etc. E.g "notices": [ "Source:Postgres", "PG
	// Host:uappg0rw.e2e.apigeeks.net", "query served
	// by:4b64601e-40de-4eb1-bfb9-eeee7ac929ed", "Table used:
	// edge.api.uapgroup2.agg_api" ]
	Notices []string `json:"notices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Errors") 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. "Errors") 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 *GoogleCloudApigeeV1Metadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Metadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Metric: This message type encapsulates the metric
// data point. Example: { "name": "sum(message_count)", "values" : [ {
// "timestamp": 1549004400000, "value": "39.0" }, { "timestamp" :
// 1548997200000, "value" : "0.0" } ] } or { "name":
// "sum(message_count)", "values" : ["39.0"] }
type GoogleCloudApigeeV1Metric struct {
	// Name: This field contains the metric name.
	Name string `json:"name,omitempty"`

	// Values: List of metric values. Possible value format:
	// "values":["39.0"] or "values":[ { "value": "39.0", "timestamp":
	// 1232434354} ]
	Values []interface{} `json:"values,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1Metric) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Metric
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1OperationMetadata: Metadata describing an
// Operation.
type GoogleCloudApigeeV1OperationMetadata struct {
	// Possible values:
	//   "OPERATION_TYPE_UNSPECIFIED"
	//   "INSERT"
	//   "DELETE"
	//   "UPDATE"
	OperationType string `json:"operationType,omitempty"`

	// Possible values:
	//   "STATE_UNSPECIFIED"
	//   "NOT_STARTED"
	//   "IN_PROGRESS"
	//   "FINISHED"
	State string `json:"state,omitempty"`

	// TargetResourceName: Name of the resource for which the operation is
	// operating on.
	TargetResourceName string `json:"targetResourceName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OperationType") 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. "OperationType") 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 *GoogleCloudApigeeV1OperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1OperationMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1OptimizedStats struct {
	// Response: This field wraps the stats response for Js Optimized
	// Scenario with a Response key. E.g. { "Response": { "TimeUnit": [],
	// "metaData": { "errors": [], "notices": [ "Source:Postgres", "Table
	// used: edge.api.aaxgroup001.agg_api", "PG
	// Host:ruappg08-ro.production.apigeeks.net", "query served
	// by:80c4ebca-6a10-4a2e-8faf-c60c1ee306ca" ] }, "resultTruncated":
	// false, "stats": { "data": [ { "identifier": { "names": [ "apiproxy"
	// ], "values": [ "sirjee" ] }, "metric": [ { "env": "prod", "name":
	// "sum(message_count)", "values": [ 36.0 ] }, { "env": "prod", "name":
	// "sum(is_error)", "values": [ 36.0 ] } ] } ] } } }
	Response *GoogleCloudApigeeV1OptimizedStatsResponse `json:"Response,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Response") 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. "Response") 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 *GoogleCloudApigeeV1OptimizedStats) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1OptimizedStats
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1OptimizedStatsNode: This message type encapsulates
// a data node as represented below: { "identifier": { "names": [
// "apiproxy" ], "values": [ "sirjee" ] }, "metric": [ { "env": "prod",
// "name": "sum(message_count)", "values": [ 36.0 ] } ] } OR { "env":
// "prod", "name": "sum(message_count)", "values": [ 36.0 ] } Depending
// on whether a dimension is present in the query or not the data node
// type can be a simple metric value or dimension identifier with list
// of metrics.
type GoogleCloudApigeeV1OptimizedStatsNode struct {
	Data []interface{} `json:"data,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Data") 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. "Data") 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 *GoogleCloudApigeeV1OptimizedStatsNode) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1OptimizedStatsNode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1OptimizedStatsResponse: This message type
// encapsulates a response format for Js Optimized Scenario.
type GoogleCloudApigeeV1OptimizedStatsResponse struct {
	// TimeUnit: This field contains a list of time unit values. Time unit
	// refers to an epoch timestamp value.
	TimeUnit googleapi.Int64s `json:"TimeUnit,omitempty"`

	// MetaData: This field contains metadata information about the query
	// executed
	MetaData *GoogleCloudApigeeV1Metadata `json:"metaData,omitempty"`

	// ResultTruncated: This ia a boolean field to indicate if the results
	// were truncated based on the limit parameter.
	ResultTruncated bool `json:"resultTruncated,omitempty"`

	// Stats: This field contains a stats results.
	Stats *GoogleCloudApigeeV1OptimizedStatsNode `json:"stats,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TimeUnit") 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. "TimeUnit") 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 *GoogleCloudApigeeV1OptimizedStatsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1OptimizedStatsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Organization struct {
	// AnalyticsRegion: Required. Primary GCP region for analytics data
	// storage. For valid values, see [Create an
	// organization](https://docs.apigee.com/hybrid/latest/precog-provision).
	AnalyticsRegion string `json:"analyticsRegion,omitempty"`

	// Attributes: Not used by Apigee.
	Attributes []string `json:"attributes,omitempty"`

	// AuthorizedNetwork: Compute Engine network used for ServiceNetworking
	// to be peered with Apigee runtime instances. See [Getting started with
	// the Service Networking
	// API](https://cloud.google.com/service-infrastructure/docs/service-netw
	// orking/getting-started). Valid only when [RuntimeType] is set to
	// CLOUD. The value can be updated only when there are no runtime
	// instances. For example: "default". **Note:** Not supported for Apigee
	// hybrid.
	AuthorizedNetwork string `json:"authorizedNetwork,omitempty"`

	// CaCertificate: Output only. Base64-encoded public certificate for the
	// root CA of the Apigee organization. Valid only when [RuntimeType] is
	// CLOUD.
	CaCertificate string `json:"caCertificate,omitempty"`

	// CreatedAt: Output only. Time that the Apigee organization was created
	// in milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// CustomerName: Not used by Apigee.
	CustomerName string `json:"customerName,omitempty"`

	// Description: Description of the Apigee organization.
	Description string `json:"description,omitempty"`

	DisplayName string `json:"displayName,omitempty"`

	// Environments: Output only. List of environments in the Apigee
	// organization.
	Environments []string `json:"environments,omitempty"`

	// LastModifiedAt: Output only. Time that the Apigee organization was
	// last modified in milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: Output only. Name of the Apigee organization.
	Name string `json:"name,omitempty"`

	// ProjectId: The project ID associated with the Apigee organization.
	ProjectId string `json:"projectId,omitempty"`

	// Properties: Properties defined in the Apigee organization profile.
	Properties *GoogleCloudApigeeV1Properties `json:"properties,omitempty"`

	// RuntimeType: Output only. Runtime type of the Apigee organization
	// based on the Apigee subscription purchased.
	//
	// Possible values:
	//   "RUNTIME_TYPE_UNSPECIFIED"
	//   "CLOUD" - Google-managed Apigee runtime.
	//   "HYBRID" - User-managed Apigee hybrid runtime.
	RuntimeType string `json:"runtimeType,omitempty"`

	// SubscriptionType: Output only. Subscription type of the Apigee
	// organization. Valid values include trial (free, limited, and for
	// evaluation purposes only) or paid (full subscription has been
	// purchased). See [Apigee
	// pricing](https://cloud.google.com/apigee/pricing/).
	//
	// Possible values:
	//   "SUBSCRIPTION_TYPE_UNSPECIFIED"
	//   "PAID" - Full subscription to Apigee has been purchased.
	//   "TRIAL" - Subscription to Apigee is free, limited, and used for
	// evaluation purposes only.
	SubscriptionType string `json:"subscriptionType,omitempty"`

	// Type: Not used by Apigee.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Subscription type not specified.
	//   "TYPE_TRIAL" - Subscription to Apigee is free, limited, and used
	// for evaluation purposes only.
	//   "TYPE_PAID" - Full subscription to Apigee has been purchased. See
	// [Apigee pricing](https://cloud.google.com/apigee/pricing/).
	//   "TYPE_INTERNAL" - For internal users only.
	Type string `json:"type,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AnalyticsRegion") 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. "AnalyticsRegion") 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 *GoogleCloudApigeeV1Organization) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Organization
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1OrganizationProjectMapping struct {
	// Organization: Name of the Apigee organization.
	Organization string `json:"organization,omitempty"`

	// ProjectIds: List of GCP projects associated with the Apigee
	// organization.
	ProjectIds []string `json:"projectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Organization") 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. "Organization") 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 *GoogleCloudApigeeV1OrganizationProjectMapping) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1OrganizationProjectMapping
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1PodStatus struct {
	// AppVersion: Version of the application running in the pod.
	AppVersion string `json:"appVersion,omitempty"`

	// DeploymentStatus: Status of the deployment. Valid values include: -
	// `deployed`: Successful. - `error` : Failed. - `pending` : Pod has not
	// yet reported on the deployment.
	DeploymentStatus string `json:"deploymentStatus,omitempty"`

	// DeploymentStatusTime: Time the deployment status was reported in
	// milliseconds since epoch.
	DeploymentStatusTime int64 `json:"deploymentStatusTime,omitempty,string"`

	// DeploymentTime: Time the proxy was deployed in milliseconds since
	// epoch.
	DeploymentTime int64 `json:"deploymentTime,omitempty,string"`

	// PodName: Name of the pod which is reporting the status.
	PodName string `json:"podName,omitempty"`

	// PodStatus: Overall status of the pod (not this specific deployment).
	// Valid values include: - `active`: Up to date. - `stale` : Recently
	// out of date. Pods that have not reported status in a long time are
	// excluded from the output.
	PodStatus string `json:"podStatus,omitempty"`

	// PodStatusTime: Time the pod status was reported in milliseconds since
	// epoch.
	PodStatusTime int64 `json:"podStatusTime,omitempty,string"`

	// StatusCode: Code associated with the deployment status.
	StatusCode string `json:"statusCode,omitempty"`

	// StatusCodeDetails: Human-readable message associated with the status
	// code.
	StatusCodeDetails string `json:"statusCodeDetails,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppVersion") 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. "AppVersion") 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 *GoogleCloudApigeeV1PodStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1PodStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Point: Point is a group of information collected
// by runtime plane at critical points of the message flow of the
// processed API request. This is a list of supported point IDs,
// categorized to three major buckets. For each category, debug points
// that we are currently supporting are listed below: - Flow status
// debug points: StateChange FlowInfo Condition Execution DebugMask
// Error - Flow control debug points: FlowCallout Paused Resumed
// FlowReturn BreakFlow Error - Runtime debug points: ScriptExecutor
// FlowCalloutStepDefinition CustomTarget StepDefinition
// Oauth2ServicePoint RaiseFault NodeJS The detail information of the
// given debug point is stored in a list of results.
type GoogleCloudApigeeV1Point struct {
	// Id: Name of a step in the transaction.
	Id string `json:"id,omitempty"`

	// Results: List of results extracted from a given debug point.
	Results []*GoogleCloudApigeeV1Result `json:"results,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") 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. "Id") 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 *GoogleCloudApigeeV1Point) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Point
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Properties: Message for compatibility with legacy
// Edge specification for Java Properties object in JSON.
type GoogleCloudApigeeV1Properties struct {
	// Property: List of all properties in the object
	Property []*GoogleCloudApigeeV1Property `json:"property,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Property") 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. "Property") 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 *GoogleCloudApigeeV1Properties) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Properties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Property: A single property entry in the
// Properties message.
type GoogleCloudApigeeV1Property struct {
	// Name: The property key
	Name string `json:"name,omitempty"`

	// Value: The property value
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1Property) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Property
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1Query struct {
	// CsvDelimiter: Delimiter used in the CSV file, if `outputFormat` is
	// set to `csv`. Defaults to the `,` (comma) character. Supported
	// delimiter characters include comma (`,`), pipe (`|`), and tab (`\t`).
	CsvDelimiter string `json:"csvDelimiter,omitempty"`

	// Dimensions: A list of dimensions.
	// https://docs.apigee.com/api-platform/analytics/analytics-reference#dimensions
	Dimensions []string `json:"dimensions,omitempty"`

	// Filter: Boolean expression that can be used to filter data. Filter
	// expressions can be combined using AND/OR terms and should be fully
	// parenthesized to avoid ambiguity. See Analytics metrics, dimensions,
	// and filters reference
	// https://docs.apigee.com/api-platform/analytics/analytics-reference
	// for more information on the fields available to filter on. For more
	// information on the tokens that you use to build filter expressions,
	// see Filter expression syntax.
	// https://docs.apigee.com/api-platform/analytics/asynch-reports-api#filter-expression-syntax
	Filter string `json:"filter,omitempty"`

	// GroupByTimeUnit: Time unit used to group the result set. Valid values
	// include: second, minute, hour, day, week, or month. If a query
	// includes groupByTimeUnit, then the result is an aggregation based on
	// the specified time unit and the resultant timestamp does not include
	// milliseconds precision. If a query omits groupByTimeUnit, then the
	// resultant timestamp includes milliseconds precision.
	GroupByTimeUnit string `json:"groupByTimeUnit,omitempty"`

	// Limit: Maximum number of rows that can be returned in the result.
	Limit int64 `json:"limit,omitempty"`

	// Metrics: A list of Metrics.
	Metrics []*GoogleCloudApigeeV1QueryMetric `json:"metrics,omitempty"`

	// Name: Asynchronous Query Name.
	Name string `json:"name,omitempty"`

	// OutputFormat: Valid values include: `csv` or `json`. Defaults to
	// `json`. Note: Configure the delimiter for CSV output using the
	// csvDelimiter property.
	OutputFormat string `json:"outputFormat,omitempty"`

	// ReportDefinitionId: Asynchronous Report ID.
	ReportDefinitionId string `json:"reportDefinitionId,omitempty"`

	// TimeRange: Required. Time range for the query. Can use the following
	// predefined strings to specify the time range: `last60minutes`
	// `last24hours` `last7days` Or, specify the timeRange as a structure
	// describing start and end timestamps in the ISO format:
	// yyyy-mm-ddThh:mm:ssZ. Example: "timeRange": { "start":
	// "2018-07-29T00:13:00Z", "end": "2018-08-01T00:18:00Z" }
	TimeRange interface{} `json:"timeRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CsvDelimiter") 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. "CsvDelimiter") 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 *GoogleCloudApigeeV1Query) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Query
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1QueryMetadata struct {
	// Dimensions: Dimensions of the AsyncQuery.
	Dimensions []string `json:"dimensions,omitempty"`

	// EndTimestamp: End timestamp of the query range.
	EndTimestamp string `json:"endTimestamp,omitempty"`

	// Metrics: Metrics of the AsyncQuery. Example:
	// ["name:message_count,func:sum,alias:sum_message_count"]
	Metrics []string `json:"metrics,omitempty"`

	// OutputFormat: Output format.
	OutputFormat string `json:"outputFormat,omitempty"`

	// StartTimestamp: Start timestamp of the query range.
	StartTimestamp string `json:"startTimestamp,omitempty"`

	// TimeUnit: Query GroupBy time unit.
	TimeUnit string `json:"timeUnit,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Dimensions") 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. "Dimensions") 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 *GoogleCloudApigeeV1QueryMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1QueryMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1QueryMetric: More info about Metric:
// https://docs.apigee.com/api-platform/analytics/analytics-reference#metrics
type GoogleCloudApigeeV1QueryMetric struct {
	// Alias: Alias for the metric. Alias will be used to replace metric
	// name in query results.
	Alias string `json:"alias,omitempty"`

	// Function: Aggregation function: avg, min, max, or sum.
	Function string `json:"function,omitempty"`

	// Name: Required. Metric name.
	Name string `json:"name,omitempty"`

	// Operator: One of `+`, `-`, `/`, `%`, `*`.
	Operator string `json:"operator,omitempty"`

	// Value: Operand value should be provided when operator is set.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alias") 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. "Alias") 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 *GoogleCloudApigeeV1QueryMetric) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1QueryMetric
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Reference: A Reference configuration. References
// must refer to a keystore that also exists in the parent environment.
type GoogleCloudApigeeV1Reference struct {
	// Description: Optional. A human-readable description of this
	// reference.
	Description string `json:"description,omitempty"`

	// Name: Required. The resource id of this reference. Values must match
	// the regular expression [\w\s\-.]+.
	Name string `json:"name,omitempty"`

	// Refers: Required. The id of the resource to which this reference
	// refers. Must be the id of a resource that exists in the parent
	// environment and is of the given resource_type.
	Refers string `json:"refers,omitempty"`

	// ResourceType: The type of resource referred to by this reference.
	// Valid values are 'KeyStore' or 'TrustStore'.
	ResourceType string `json:"resourceType,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *GoogleCloudApigeeV1Reference) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Reference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ReferenceConfig struct {
	// Name: The name of the reference. Must be of the form
	// 'organizations/{org}/environments/{env}/references/{ref}'.
	Name string `json:"name,omitempty"`

	// ResourceName: The name of the referred resource. Only references to
	// keystore resources are supported. Must be of the form
	// 'organizations/{org}/environments/{env}/keystores/{ks}'.
	ResourceName string `json:"resourceName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1ReferenceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ReferenceConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ReportInstanceStatusRequest: Request for
// ReportInstanceStatus.
type GoogleCloudApigeeV1ReportInstanceStatusRequest struct {
	// InstanceUid: A unique ID for the instance which is guaranteed to be
	// unique in case the user installs multiple hybrid runtimes with the
	// same instance ID.
	InstanceUid string `json:"instanceUid,omitempty"`

	// ReportTime: The time the report was generated in the runtime. Used to
	// prevent an old status from overwriting a newer one. An instance
	// should space out it's status reports so that clock skew does not play
	// a factor.
	ReportTime string `json:"reportTime,omitempty"`

	// Resources: Status for config resources
	Resources []*GoogleCloudApigeeV1ResourceStatus `json:"resources,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InstanceUid") 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. "InstanceUid") 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 *GoogleCloudApigeeV1ReportInstanceStatusRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ReportInstanceStatusRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ReportInstanceStatusResponse: Placeholder for
// future enhancements to status reporting protocol
type GoogleCloudApigeeV1ReportInstanceStatusResponse struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

type GoogleCloudApigeeV1ReportProperty struct {
	// Property: name of the property
	Property string `json:"property,omitempty"`

	// Value: property values
	Value []*GoogleCloudApigeeV1Attribute `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Property") 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. "Property") 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 *GoogleCloudApigeeV1ReportProperty) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ReportProperty
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ResourceConfig struct {
	// Location: The location of the resource as a URI.
	Location string `json:"location,omitempty"`

	// Name: The resource name. Only environment-scoped resource files are
	// supported. Must be of the form
	// 'organizations/{org}/environments/{env}/resourcefiles/{type}/{file}/re
	// visions/{rev}'.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Location") 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. "Location") 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 *GoogleCloudApigeeV1ResourceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ResourceConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ResourceFile: Metadata about a resource file.
type GoogleCloudApigeeV1ResourceFile struct {
	// Name: ID of the resource file.
	Name string `json:"name,omitempty"`

	// Type: Resource file type. {{ resource_file_type }}
	Type string `json:"type,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1ResourceFile) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ResourceFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ResourceFiles: List of resource files.
type GoogleCloudApigeeV1ResourceFiles struct {
	// ResourceFile: List of resource files.
	ResourceFile []*GoogleCloudApigeeV1ResourceFile `json:"resourceFile,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourceFile") 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. "ResourceFile") 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 *GoogleCloudApigeeV1ResourceFiles) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ResourceFiles
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1ResourceStatus: The status of a resource loaded in
// the runtime.
type GoogleCloudApigeeV1ResourceStatus struct {
	// Resource: The resource name. Currently only two resources are
	// supported: EnvironmentGroup -
	// organizations/{org}/envgroups/{envgroup} EnvironmentConfig -
	// organizations/{org}/environments/{environment}/deployedConfig
	Resource string `json:"resource,omitempty"`

	// Revisions: Revisions of the resource currently deployed in the
	// instance.
	Revisions []*GoogleCloudApigeeV1RevisionStatus `json:"revisions,omitempty"`

	// TotalReplicas: The total number of replicas that should have this
	// resource.
	TotalReplicas int64 `json:"totalReplicas,omitempty"`

	// Uid: The uid of the resource. In the unexpected case that the
	// instance has multiple uids for the same name, they should be reported
	// under separate ResourceStatuses.
	Uid string `json:"uid,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Resource") 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. "Resource") 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 *GoogleCloudApigeeV1ResourceStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ResourceStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Result: Result is short for "action result", could
// be different types identified by "action_result" field. Supported
// types: 1. DebugInfo : generic debug info collected by runtime
// recorded as a list of properties. For example, the contents could be
// virtual host info, state change result, or execution metadata.
// Required fields : properties, timestamp 2. RequestMessage:
// information of a http request. Contains headers, request URI and http
// methods type.Required fields : headers, uri, verb 3. ResponseMessage:
// information of a http response. Contains headers, reason phrase and
// http status code. Required fields : headers, reasonPhrase, statusCode
// 4. ErrorMessage: information of a http error message. Contains detail
// error message, reason phrase and status code. Required fields :
// content, headers, reasonPhrase, statusCode 5. VariableAccess: a list
// of variable access actions, can be Get, Set and Remove. Required
// fields : accessList
type GoogleCloudApigeeV1Result struct {
	// ActionResult: Type of the action result. Can be one of the five:
	// DebugInfo, RequestMessage, ResponseMessage, ErrorMessage,
	// VariableAccess
	ActionResult string `json:"ActionResult,omitempty"`

	// AccessList: A list of variable access actions agaist the api proxy.
	// Supported values: Get, Set, Remove.
	AccessList []*GoogleCloudApigeeV1Access `json:"accessList,omitempty"`

	// Content: Error message content. for example, "content" :
	// "{\"fault\":{\"faultstring\":\"API timed
	// out\",\"detail\":{\"errorcode\":\"flow.APITimedOut\"}}}"
	Content string `json:"content,omitempty"`

	// Headers: A list of HTTP headers. for example, '"headers" : [ { "name"
	// : "Content-Length", "value" : "83" }, { "name" : "Content-Type",
	// "value" : "application/json" } ]'
	Headers []*GoogleCloudApigeeV1Property `json:"headers,omitempty"`

	// Properties: Name value pairs used for DebugInfo ActionResult.
	Properties *GoogleCloudApigeeV1Properties `json:"properties,omitempty"`

	// ReasonPhrase: HTTP response phrase
	ReasonPhrase string `json:"reasonPhrase,omitempty"`

	// StatusCode: HTTP response code
	StatusCode string `json:"statusCode,omitempty"`

	// Timestamp: Timestamp of when the result is recorded. Its format is
	// dd-mm-yy hh:mm:ss:xxx. For example, "timestamp" : "12-08-19
	// 00:31:59:960"
	Timestamp string `json:"timestamp,omitempty"`

	// URI: The relative path of the api proxy. for example, "uRI" :
	// "/iloveapis"
	URI string `json:"uRI,omitempty"`

	// Verb: HTTP method verb
	Verb string `json:"verb,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActionResult") 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. "ActionResult") 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 *GoogleCloudApigeeV1Result) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Result
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1RevisionStatus: The status of a specific resource
// revision.
type GoogleCloudApigeeV1RevisionStatus struct {
	// Errors: Errors reported when attempting to load this revision.
	Errors []*GoogleCloudApigeeV1UpdateError `json:"errors,omitempty"`

	// JsonSpec: The json content of the resource revision.
	JsonSpec string `json:"jsonSpec,omitempty"`

	// Replicas: The number of replicas that have successfully loaded this
	// revision.
	Replicas int64 `json:"replicas,omitempty"`

	// RevisionId: The revision of the resource.
	RevisionId string `json:"revisionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Errors") 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. "Errors") 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 *GoogleCloudApigeeV1RevisionStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1RevisionStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1RoutingRule struct {
	// Basepath: URI path prefix used to route to the specified environment.
	// May contain one or more wildcards. For example, path segments
	// consisting of a single `*` character will match any string.
	Basepath string `json:"basepath,omitempty"`

	// Environment: Name of an environment bound to the environment group in
	// the following format: `organizations/{org}/environments/{env}`.
	Environment string `json:"environment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Basepath") 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. "Basepath") 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 *GoogleCloudApigeeV1RoutingRule) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1RoutingRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Schema: Response for Schema call
type GoogleCloudApigeeV1Schema struct {
	// Dimensions: List of schema fiels grouped as dimensions.
	Dimensions []*GoogleCloudApigeeV1SchemaSchemaElement `json:"dimensions,omitempty"`

	// Meta: Additional metadata associated with schema. This is a legacy
	// field and usually consists of an empty array of strings.
	Meta []string `json:"meta,omitempty"`

	// Metrics: List of schema fields grouped as dimensions. These are
	// fields that can be used with an aggregate function such as sum, avg,
	// min, max.
	Metrics []*GoogleCloudApigeeV1SchemaSchemaElement `json:"metrics,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Dimensions") 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. "Dimensions") 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 *GoogleCloudApigeeV1Schema) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Schema
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1SchemaSchemaElement: Message type for the schema
// element
type GoogleCloudApigeeV1SchemaSchemaElement struct {
	// Name: Name of the field
	Name string `json:"name,omitempty"`

	// Properties: Property of the schema field E.g. { "createTime":
	// "2016-02-26T10:23:09.592Z", "custom": "false", "type": "string" }
	Properties *GoogleCloudApigeeV1SchemaSchemaProperty `json:"properties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1SchemaSchemaElement) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1SchemaSchemaElement
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1SchemaSchemaProperty: Message type for schema
// property
type GoogleCloudApigeeV1SchemaSchemaProperty struct {
	// CreateTime: Creation time of the field
	CreateTime string `json:"createTime,omitempty"`

	// Custom: Custom is a flag signifying if the field was provided as part
	// of the standard dataset or a custom field created by the customer
	Custom string `json:"custom,omitempty"`

	// Type: Data type of the field.
	Type string `json:"type,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 *GoogleCloudApigeeV1SchemaSchemaProperty) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1SchemaSchemaProperty
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1ServiceIssuersMapping struct {
	// EmailIds: List of trusted issuer email ids.
	EmailIds []string `json:"emailIds,omitempty"`

	// Service: String indicating the Apigee service name.
	Service string `json:"service,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EmailIds") 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. "EmailIds") 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 *GoogleCloudApigeeV1ServiceIssuersMapping) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1ServiceIssuersMapping
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Session: Session carries the debug session id and
// its creation time.
type GoogleCloudApigeeV1Session struct {
	// Id: The debug session ID.
	Id string `json:"id,omitempty"`

	// TimestampMs: The first transaction creation timestamp in millisecond,
	// recoreded by UAP.
	TimestampMs int64 `json:"timestampMs,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Id") 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. "Id") 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 *GoogleCloudApigeeV1Session) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Session
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1SharedFlow: The metadata describing a shared flow
type GoogleCloudApigeeV1SharedFlow struct {
	// LatestRevisionId: The id of the most recently created revision for
	// this shared flow.
	LatestRevisionId string `json:"latestRevisionId,omitempty"`

	// MetaData: Metadata describing the shared flow.
	MetaData *GoogleCloudApigeeV1EntityMetadata `json:"metaData,omitempty"`

	// Name: The ID of the shared flow.
	Name string `json:"name,omitempty"`

	// Revision: A list of revisions of this shared flow.
	Revision []string `json:"revision,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "LatestRevisionId") 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. "LatestRevisionId") 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 *GoogleCloudApigeeV1SharedFlow) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1SharedFlow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1SharedFlowRevision: The metadata describing a
// shared flow revision.
type GoogleCloudApigeeV1SharedFlowRevision struct {
	// ConfigurationVersion: The version of the configuration schema to
	// which this shared flow conforms. The only supported value currently
	// is majorVersion 4 and minorVersion 0. This setting may be used in the
	// future to enable evolution of the shared flow format.
	ConfigurationVersion *GoogleCloudApigeeV1ConfigVersion `json:"configurationVersion,omitempty"`

	// ContextInfo: A textual description of the shared flow revision.
	ContextInfo string `json:"contextInfo,omitempty"`

	// CreatedAt: Time at which this shared flow revision was created, in
	// milliseconds since epoch.
	CreatedAt int64 `json:"createdAt,omitempty,string"`

	// Description: Description of the shared flow revision.
	Description string `json:"description,omitempty"`

	// DisplayName: The human readable name of this shared flow.
	DisplayName string `json:"displayName,omitempty"`

	// EntityMetaDataAsProperties: A Key-Value map of metadata about this
	// shared flow revision.
	EntityMetaDataAsProperties map[string]string `json:"entityMetaDataAsProperties,omitempty"`

	// LastModifiedAt: Time at which this shared flow revision was most
	// recently modified, in milliseconds since epoch.
	LastModifiedAt int64 `json:"lastModifiedAt,omitempty,string"`

	// Name: The resource ID of the parent shared flow.
	Name string `json:"name,omitempty"`

	// Policies: A list of policy names included in this shared flow
	// revision.
	Policies []string `json:"policies,omitempty"`

	// ResourceFiles: The resource files included in this shared flow
	// revision.
	ResourceFiles *GoogleCloudApigeeV1ResourceFiles `json:"resourceFiles,omitempty"`

	// Resources: A list of the resources included in this shared flow
	// revision formatted as "{type}://{name}".
	Resources []string `json:"resources,omitempty"`

	// Revision: The resource ID of this revision.
	Revision string `json:"revision,omitempty"`

	// SharedFlows: A list of the shared flow names included in this shared
	// flow revision.
	SharedFlows []string `json:"sharedFlows,omitempty"`

	// Type: The string "Application"
	Type string `json:"type,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "ConfigurationVersion") 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. "ConfigurationVersion") 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 *GoogleCloudApigeeV1SharedFlowRevision) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1SharedFlowRevision
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Stats: This message type encapsulates a stats
// response.
type GoogleCloudApigeeV1Stats struct {
	// Environments: This field contains a list of query results on
	// environment level.
	Environments []*GoogleCloudApigeeV1StatsEnvironmentStats `json:"environments,omitempty"`

	// MetaData: This field contains the metadata information.
	MetaData *GoogleCloudApigeeV1Metadata `json:"metaData,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Environments") 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. "Environments") 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 *GoogleCloudApigeeV1Stats) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Stats
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1StatsEnvironmentStats: This message type
// encapsulates the environment wrapper: "environments": [ { "metrics":
// [ { "name": "sum(message_count)", "values": [ "2.52056245E8" ] } ],
// "name": "prod" } ]
type GoogleCloudApigeeV1StatsEnvironmentStats struct {
	// Dimensions: This field contains the list of metrics grouped under
	// dimensions.
	Dimensions []*GoogleCloudApigeeV1DimensionMetric `json:"dimensions,omitempty"`

	// Metrics: In the final response, only one of the following fields will
	// be present based on the dimensions provided. If no dimensions are
	// provided, then only a top level metrics is provided. If dimensions
	// are included, then there will be a top level dimensions field under
	// environments which will contain metrics values and the dimension
	// name. Example: "environments": [ { "dimensions": [ { "metrics": [ {
	// "name": "sum(message_count)", "values": [ "2.14049521E8" ] } ],
	// "name": "nit_proxy" } ], "name": "prod" } ] OR "environments": [ {
	// "metrics": [ { "name": "sum(message_count)", "values": [
	// "2.19026331E8" ] } ], "name": "prod" } ] This field contains the list
	// of metric values.
	Metrics []*GoogleCloudApigeeV1Metric `json:"metrics,omitempty"`

	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Dimensions") 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. "Dimensions") 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 *GoogleCloudApigeeV1StatsEnvironmentStats) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1StatsEnvironmentStats
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1Subscription: Pub/Sub subscription of an
// environment.
type GoogleCloudApigeeV1Subscription struct {
	// Name: Full name of the Pub/Sub subcription. Use the following
	// structure in your request: `subscription
	// "projects/foo/subscription/bar"
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *GoogleCloudApigeeV1Subscription) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1Subscription
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1SyncAuthorization struct {
	// Etag: Entity tag (ETag) used for optimistic concurrency control as a
	// way to help prevent simultaneous updates from overwriting each other.
	// For example, when you call
	// [getSyncAuthorization](getSyncAuthorization) an ETag is returned in
	// the response. Pass that ETag when calling the
	// [setSyncAuthorization](setSyncAuthorization) to ensure that you are
	// updating the correct version. If you don't pass the ETag in the call
	// to `setSyncAuthorization`, then the existing authorization is
	// overwritten indiscriminately. **Note**: We strongly recommend that
	// you use the ETag in the read-modify-write cycle to avoid race
	// conditions.
	Etag string `json:"etag,omitempty"`

	// Identities: Required. Array of service accounts to grant access to
	// control plane resources, each specified using the following format:
	// `serviceAccount:` service-account-name. The service-account-name is
	// formatted like an email address. For example:
	// `my-synchronizer-manager-service_account@my_project_id.iam.gserviceacc
	// ount.com` You might specify multiple service accounts, for example,
	// if you have multiple environments and wish to assign a unique service
	// account to each one. The service accounts must have **Apigee
	// Synchronizer Manager** role. See also [Create service
	// accounts](https://docs.apigee.com/hybrid/latest/sa-about#create-the-se
	// rvice-accounts).
	Identities []string `json:"identities,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Etag") 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. "Etag") 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 *GoogleCloudApigeeV1SyncAuthorization) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1SyncAuthorization
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1TargetServer: TargetServer configuration.
// TargetServers are used to decouple a proxy's TargetEndpoint
// HTTPTargetConnections from concrete URLs for backend services.
type GoogleCloudApigeeV1TargetServer struct {
	// Description: Optional. A human-readable description of this
	// TargetServer.
	Description string `json:"description,omitempty"`

	// Host: Required. The host name this target connects to. Value must be
	// a valid hostname as described by RFC-1123.
	Host string `json:"host,omitempty"`

	// IsEnabled: Optional. Enabling/disabling a TargetServer is useful when
	// TargetServers are used in load balancing configurations, and one or
	// more TargetServers need to taken out of rotation periodically.
	// Defaults to true.
	IsEnabled bool `json:"isEnabled,omitempty"`

	// Name: Required. The resource id of this target server. Values must
	// match the regular expression
	Name string `json:"name,omitempty"`

	// Port: Required. The port number this target connects to on the given
	// host. Value must be between 1 and 65535, inclusive.
	Port int64 `json:"port,omitempty"`

	// SSLInfo: Optional. Specifies TLS configuration info for this
	// TargetServer. The JSON name is `sSLInfo` for legacy/backwards
	// compatibility reasons -- Edge originally supported SSL, and the name
	// is still used for TLS configuration.
	SSLInfo *GoogleCloudApigeeV1TlsInfo `json:"sSLInfo,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *GoogleCloudApigeeV1TargetServer) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1TargetServer
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1TargetServerConfig struct {
	// Host: Target host name.
	Host string `json:"host,omitempty"`

	// Name: The target server revision name. Must be of the form
	// 'organizations/{org}/environments/{env}/targetservers/{ts_id}/revision
	// s/{rev}'.
	Name string `json:"name,omitempty"`

	// Port: Target port.
	Port int64 `json:"port,omitempty"`

	// TlsInfo: TLS settings for the target.
	TlsInfo *GoogleCloudApigeeV1TlsInfoConfig `json:"tlsInfo,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Host") 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. "Host") 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 *GoogleCloudApigeeV1TargetServerConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1TargetServerConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1TestDatastoreResponse: The response for
// TestDatastore
type GoogleCloudApigeeV1TestDatastoreResponse struct {
	// Error: Output only. Error message of test connection failure
	Error string `json:"error,omitempty"`

	// State: Output only. It could be `completed` or `failed`
	State string `json:"state,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Error") 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. "Error") 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 *GoogleCloudApigeeV1TestDatastoreResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1TestDatastoreResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1TlsInfo: TLS configuration information for
// VirtualHosts and TargetServers.
type GoogleCloudApigeeV1TlsInfo struct {
	// Ciphers: The SSL/TLS cipher suites to be used. Must be one of the
	// cipher suite names listed in:
	// http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#ciphersuites
	Ciphers []string `json:"ciphers,omitempty"`

	// ClientAuthEnabled: Optional. Enables two-way TLS.
	ClientAuthEnabled bool `json:"clientAuthEnabled,omitempty"`

	// CommonName: The TLS Common Name of the certificate.
	CommonName *GoogleCloudApigeeV1TlsInfoCommonName `json:"commonName,omitempty"`

	// Enabled: Required. Enables one-way TLS.
	Enabled bool `json:"enabled,omitempty"`

	// IgnoreValidationErrors: If true, Edge ignores TLS certificate errors.
	// Valid when configuring TLS for target servers and target endpoints,
	// and when configuring virtual hosts that use 2-way TLS. When used with
	// a target endpoint/target server, if the backend system uses SNI and
	// returns a cert with a subject Distinguished Name (DN) that does not
	// match the hostname, there is no way to ignore the error and the
	// connection fails.
	IgnoreValidationErrors bool `json:"ignoreValidationErrors,omitempty"`

	// KeyAlias: Required if `client_auth_enabled` is true. The resource ID
	// for the alias containing the private key and cert.
	KeyAlias string `json:"keyAlias,omitempty"`

	// KeyStore: Required if `client_auth_enabled` is true. The resource ID
	// of the keystore. References not yet supported.
	KeyStore string `json:"keyStore,omitempty"`

	// Protocols: The TLS versioins to be used.
	Protocols []string `json:"protocols,omitempty"`

	// TrustStore: The resource ID of the truststore. References not yet
	// supported.
	TrustStore string `json:"trustStore,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Ciphers") 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. "Ciphers") 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 *GoogleCloudApigeeV1TlsInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1TlsInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1TlsInfoCommonName struct {
	// Value: The TLS Common Name string of the certificate.
	Value string `json:"value,omitempty"`

	// WildcardMatch: Indicates whether the cert should be matched against
	// as a wildcard cert.
	WildcardMatch bool `json:"wildcardMatch,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Value") 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. "Value") 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 *GoogleCloudApigeeV1TlsInfoCommonName) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1TlsInfoCommonName
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudApigeeV1TlsInfoConfig struct {
	// Ciphers: Whitelist of supported ciphers.
	Ciphers []string `json:"ciphers,omitempty"`

	// ClientAuthEnabled: Indicates if client auth is enabled for the
	// target. Enables two-way TLS.
	ClientAuthEnabled bool `json:"clientAuthEnabled,omitempty"`

	// CommonName: Common name to validate the target against.
	CommonName *GoogleCloudApigeeV1CommonNameConfig `json:"commonName,omitempty"`

	// Enabled: Enables one-way TLS.
	Enabled bool `json:"enabled,omitempty"`

	// IgnoreValidationErrors: If true, ignore TLS certificate validation
	// errors.
	IgnoreValidationErrors bool `json:"ignoreValidationErrors,omitempty"`

	// KeyAlias: The name of the Alias used for client side auth. It must be
	// of the form:
	// organizations/{org}/environments/{env}/keystores/{keystore}/aliases/{a
	// lias}
	KeyAlias string `json:"keyAlias,omitempty"`

	// KeyAliasReference: A pair of reference name and alias to use for
	// client side auth.
	KeyAliasReference *GoogleCloudApigeeV1KeyAliasReference `json:"keyAliasReference,omitempty"`

	// Protocols: Whitelist of supported TLS protocols.
	Protocols []string `json:"protocols,omitempty"`

	// TrustStore: The name of the Keystore or keystore reference containing
	// trusted certificates for the server. It must be of either the form
	// organizations/{org}/environments/{env}/keystores/{keystore} or
	// organizations/{org}/environments/{env}/references/{reference}.
	TrustStore string `json:"trustStore,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Ciphers") 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. "Ciphers") 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 *GoogleCloudApigeeV1TlsInfoConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1TlsInfoConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudApigeeV1UpdateError: Details on why a resource update
// failed in the runtime.
type GoogleCloudApigeeV1UpdateError struct {
	// Code: Status code.
	//
	// Possible values:
	//   "OK" - Not an error; returned on success HTTP Mapping: 200 OK
	//   "CANCELLED" - The operation was cancelled, typically by the caller.
	// HTTP Mapping: 499 Client Closed Request
	//   "UNKNOWN" - Unknown error. For example, this error may be returned
	// when a `Status` value received from another address space belongs to
	// an error space that is not known in this address space. Also errors
	// raised by APIs that do not return enough error information may be
	// converted to this error. HTTP Mapping: 500 Internal Server Error
	//   "INVALID_ARGUMENT" - The client specified an invalid argument. Note
	// that this differs from `FAILED_PRECONDITION`. `INVALID_ARGUMENT`
	// indicates arguments that are problematic regardless of the state of
	// the system (e.g., a malformed file name). HTTP Mapping: 400 Bad
	// Request
	//   "DEADLINE_EXCEEDED" - The deadline expired before the operation
	// could complete. For operations that change the state of the system,
	// this error may be returned even if the operation has completed
	// successfully. For example, a successful response from a server could
	// have been delayed long enough for the deadline to expire. HTTP
	// Mapping: 504 Gateway Timeout
	//   "NOT_FOUND" - Some requested entity (e.g., file or directory) was
	// not found. Note to server developers: if a request is denied for an
	// entire class of users, such as gradual feature rollout or
	// undocumented allowlist, `NOT_FOUND` may be used. If a request is
	// denied for some users within a class of users, such as user-based
	// access control, `PERMISSION_DENIED` must be used. HTTP Mapping: 404
	// Not Found
	//   "ALREADY_EXISTS" - The entity that a client attempted to create
	// (e.g., file or directory) already exists. HTTP Mapping: 409 Conflict
	//   "PERMISSION_DENIED" - The caller does not have permission to
	// execute the specified operation. `PERMISSION_DENIED` must not be used
	// for rejections caused by exhausting some resource (use
	// `RESOURCE_EXHAUSTED` instead for those errors). `PERMISSION_DENIED`
	// must not be used if the caller can not be identified (use
	// `UNAUTHENTICATED` instead for those errors). This error code does not
	// imply the request is valid or the requested entity exists or
	// satisfies other pre-conditions. HTTP Mapping: 403 Forbidden
	//   "UNAUTHENTICATED" - The request does not have valid authentication
	// credentials for the operation. HTTP Mapping: 401 Unauthorized
	//   "RESOURCE_EXHAUSTED" - Some resource has been exhausted, perhaps a
	// per-user quota, or perhaps the entire file system is out of space.
	// HTTP Mapping: 429 Too Many Requests
	//   "FAILED_PRECONDITION" - The operation was rejected because the
	// system is not in a state required for the operation's execution. For
	// example, the directory to be deleted is non-empty, an rmdir operation
	// is applied to a non-directory, etc. Service implementors can use the
	// following guidelines to decide between `FAILED_PRECONDITION`,
	// `ABORTED`, and `UNAVAILABLE`: (a) Use `UNAVAILABLE` if the client can
	// retry just the failing call. (b) Use `ABORTED` if the client should
	// retry at a higher level (e.g., when a client-specified test-and-set
	// fails, indicating the client should restart a read-modify-write
	// sequence). (c) Use `FAILED_PRECONDITION` if the client should not
	// retry until the system state has been explicitly fixed. E.g., if an
	// "rmdir" fails because the directory is non-empty,
	// `FAILED_PRECONDITION` should be returned since the client should not
	// retry unless the files are deleted from the directory. HTTP Mapping:
	// 400 Bad Request
	//   "ABORTED" - The operation was aborted, typically due to a
	// concurrency issue such as a sequencer check failure or transaction
	// abort. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 409 Conflict
	//   "OUT_OF_RANGE" - The operation was attempted past the valid range.
	// E.g., seeking or reading past end-of-file. Unlike `INVALID_ARGUMENT`,
	// this error indicates a problem that may be fixed if the system state
	// changes. For example, a 32-bit file system will generate
	// `INVALID_ARGUMENT` if asked to read at an offset that is not in the
	// range [0,2^32-1], but it will generate `OUT_OF_RANGE` if asked to
	// read from an offset past the current file size. There is a fair bit
	// of overlap between `FAILED_PRECONDITION` and `OUT_OF_RANGE`. We
	// recommend using `OUT_OF_RANGE` (the more specific error) when it
	// applies so that callers who are iterating through a space can easily
	// look for an `OUT_OF_RANGE` error to detect when they are done. HTTP
	// Mapping: 400 Bad Request
	//   "UNIMPLEMENTED" - The operation is not implemented or is not
	// supported/enabled in this service. HTTP Mapping: 501 Not Implemented
	//   "INTERNAL" - Internal errors. This means that some invariants
	// expected by the underlying system have been broken. This error code
	// is reserved for serious errors. HTTP Mapping: 500 Internal Server
	// Error
	//   "UNAVAILABLE" - The service is currently unavailable. This is most
	// likely a transient condition, which can be corrected by retrying with
	// a backoff. Note that it is not always safe to retry non-idempotent
	// operations. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 503 Service Unavailable
	//   "DATA_LOSS" - Unrecoverable data loss or corruption. HTTP Mapping:
	// 500 Internal Server Error
	Code string `json:"code,omitempty"`

	// Message: User-friendly error message.
	Message string `json:"message,omitempty"`

	// Resource: The sub resource specific to this error (e.g. a proxy
	// deployed within the EnvironmentConfig). If empty the error refers to
	// the top level resource.
	Resource string `json:"resource,omitempty"`

	// Type: A string that uniquely identifies the type of error. This
	// provides a more reliable means to deduplicate errors across revisions
	// and instances.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") 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. "Code") 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 *GoogleCloudApigeeV1UpdateError) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudApigeeV1UpdateError
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleIamV1AuditConfig: Specifies the audit configuration for a
// service. The configuration determines which permission types are
// logged, and what identities, if any, are exempted from logging. An
// AuditConfig must have one or more AuditLogConfigs. If there are
// AuditConfigs for both `allServices` and a specific service, the union
// of the two AuditConfigs is used for that service: the log_types
// specified in each AuditConfig are enabled, and the exempted_members
// in each AuditLogConfig are exempted. Example Policy with multiple
// AuditConfigs: { "audit_configs": [ { "service": "allServices",
// "audit_log_configs": [ { "log_type": "DATA_READ", "exempted_members":
// [ "user:jose@example.com" ] }, { "log_type": "DATA_WRITE" }, {
// "log_type": "ADMIN_READ" } ] }, { "service":
// "sampleservice.googleapis.com", "audit_log_configs": [ { "log_type":
// "DATA_READ" }, { "log_type": "DATA_WRITE", "exempted_members": [
// "user:aliya@example.com" ] } ] } ] } For sampleservice, this policy
// enables DATA_READ, DATA_WRITE and ADMIN_READ logging. It also exempts
// jose@example.com from DATA_READ logging, and aliya@example.com from
// DATA_WRITE logging.
type GoogleIamV1AuditConfig struct {
	// AuditLogConfigs: The configuration for logging of each type of
	// permission.
	AuditLogConfigs []*GoogleIamV1AuditLogConfig `json:"auditLogConfigs,omitempty"`

	// Service: Specifies a service that will be enabled for audit logging.
	// For example, `storage.googleapis.com`, `cloudsql.googleapis.com`.
	// `allServices` is a special value that covers all services.
	Service string `json:"service,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AuditLogConfigs") 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. "AuditLogConfigs") 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 *GoogleIamV1AuditConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleIamV1AuditConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleIamV1AuditLogConfig: Provides the configuration for logging a
// type of permissions. Example: { "audit_log_configs": [ { "log_type":
// "DATA_READ", "exempted_members": [ "user:jose@example.com" ] }, {
// "log_type": "DATA_WRITE" } ] } This enables 'DATA_READ' and
// 'DATA_WRITE' logging, while exempting jose@example.com from DATA_READ
// logging.
type GoogleIamV1AuditLogConfig struct {
	// ExemptedMembers: Specifies the identities that do not cause logging
	// for this type of permission. Follows the same format of
	// Binding.members.
	ExemptedMembers []string `json:"exemptedMembers,omitempty"`

	// LogType: The log type that this config enables.
	//
	// Possible values:
	//   "LOG_TYPE_UNSPECIFIED" - Default case. Should never be this.
	//   "ADMIN_READ" - Admin reads. Example: CloudIAM getIamPolicy
	//   "DATA_WRITE" - Data writes. Example: CloudSQL Users create
	//   "DATA_READ" - Data reads. Example: CloudSQL Users list
	LogType string `json:"logType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExemptedMembers") 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. "ExemptedMembers") 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 *GoogleIamV1AuditLogConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleIamV1AuditLogConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleIamV1Binding: Associates `members` with a `role`.
type GoogleIamV1Binding struct {
	// Condition: The condition that is associated with this binding. If the
	// condition evaluates to `true`, then this binding applies to the
	// current request. If the condition evaluates to `false`, then this
	// binding does not apply to the current request. However, a different
	// role binding might grant the same role to one or more of the members
	// in this binding. To learn which resources support conditions in their
	// IAM policies, see the [IAM
	// documentation](https://cloud.google.com/iam/help/conditions/resource-p
	// olicies).
	Condition *GoogleTypeExpr `json:"condition,omitempty"`

	// Members: Specifies the identities requesting access for a Cloud
	// Platform resource. `members` can have the following values: *
	// `allUsers`: A special identifier that represents anyone who is on the
	// internet; with or without a Google account. *
	// `allAuthenticatedUsers`: A special identifier that represents anyone
	// who is authenticated with a Google account or a service account. *
	// `user:{emailid}`: An email address that represents a specific Google
	// account. For example, `alice@example.com` . *
	// `serviceAccount:{emailid}`: An email address that represents a
	// service account. For example,
	// `my-other-app@appspot.gserviceaccount.com`. * `group:{emailid}`: An
	// email address that represents a Google group. For example,
	// `admins@example.com`. * `deleted:user:{emailid}?uid={uniqueid}`: An
	// email address (plus unique identifier) representing a user that has
	// been recently deleted. For example,
	// `alice@example.com?uid=123456789012345678901`. If the user is
	// recovered, this value reverts to `user:{emailid}` and the recovered
	// user retains the role in the binding. *
	// `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address
	// (plus unique identifier) representing a service account that has been
	// recently deleted. For example,
	// `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`.
	// If the service account is undeleted, this value reverts to
	// `serviceAccount:{emailid}` and the undeleted service account retains
	// the role in the binding. * `deleted:group:{emailid}?uid={uniqueid}`:
	// An email address (plus unique identifier) representing a Google group
	// that has been recently deleted. For example,
	// `admins@example.com?uid=123456789012345678901`. If the group is
	// recovered, this value reverts to `group:{emailid}` and the recovered
	// group retains the role in the binding. * `domain:{domain}`: The G
	// Suite domain (primary) that represents all the users of that domain.
	// For example, `google.com` or `example.com`.
	Members []string `json:"members,omitempty"`

	// Role: Role that is assigned to `members`. For example,
	// `roles/viewer`, `roles/editor`, or `roles/owner`.
	Role string `json:"role,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Condition") 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. "Condition") 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 *GoogleIamV1Binding) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleIamV1Binding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleIamV1Policy: An Identity and Access Management (IAM) policy,
// which specifies access controls for Google Cloud resources. A
// `Policy` is a collection of `bindings`. A `binding` binds one or more
// `members` to a single `role`. Members can be user accounts, service
// accounts, Google groups, and domains (such as G Suite). A `role` is a
// named list of permissions; each `role` can be an IAM predefined role
// or a user-created custom role. For some types of Google Cloud
// resources, a `binding` can also specify a `condition`, which is a
// logical expression that allows access to a resource only if the
// expression evaluates to `true`. A condition can add constraints based
// on attributes of the request, the resource, or both. To learn which
// resources support conditions in their IAM policies, see the [IAM
// documentation](https://cloud.google.com/iam/help/conditions/resource-p
// olicies). **JSON example:** { "bindings": [ { "role":
// "roles/resourcemanager.organizationAdmin", "members": [
// "user:mike@example.com", "group:admins@example.com",
// "domain:google.com",
// "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, {
// "role": "roles/resourcemanager.organizationViewer", "members": [
// "user:eve@example.com" ], "condition": { "title": "expirable access",
// "description": "Does not grant access after Sep 2020", "expression":
// "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ],
// "etag": "BwWWja0YfJA=", "version": 3 } **YAML example:** bindings: -
// members: - user:mike@example.com - group:admins@example.com -
// domain:google.com -
// serviceAccount:my-project-id@appspot.gserviceaccount.com role:
// roles/resourcemanager.organizationAdmin - members: -
// user:eve@example.com role: roles/resourcemanager.organizationViewer
// condition: title: expirable access description: Does not grant access
// after Sep 2020 expression: request.time <
// timestamp('2020-10-01T00:00:00.000Z') - etag: BwWWja0YfJA= - version:
// 3 For a description of IAM and its features, see the [IAM
// documentation](https://cloud.google.com/iam/docs/).
type GoogleIamV1Policy struct {
	// AuditConfigs: Specifies cloud audit logging configuration for this
	// policy.
	AuditConfigs []*GoogleIamV1AuditConfig `json:"auditConfigs,omitempty"`

	// Bindings: Associates a list of `members` to a `role`. Optionally, may
	// specify a `condition` that determines how and when the `bindings` are
	// applied. Each of the `bindings` must contain at least one member.
	Bindings []*GoogleIamV1Binding `json:"bindings,omitempty"`

	// Etag: `etag` is used for optimistic concurrency control as a way to
	// help prevent simultaneous updates of a policy from overwriting each
	// other. It is strongly suggested that systems make use of the `etag`
	// in the read-modify-write cycle to perform policy updates in order to
	// avoid race conditions: An `etag` is returned in the response to
	// `getIamPolicy`, and systems are expected to put that etag in the
	// request to `setIamPolicy` to ensure that their change will be applied
	// to the same version of the policy. **Important:** If you use IAM
	// Conditions, you must include the `etag` field whenever you call
	// `setIamPolicy`. If you omit this field, then IAM allows you to
	// overwrite a version `3` policy with a version `1` policy, and all of
	// the conditions in the version `3` policy are lost.
	Etag string `json:"etag,omitempty"`

	// Version: Specifies the format of the policy. Valid values are `0`,
	// `1`, and `3`. Requests that specify an invalid value are rejected.
	// Any operation that affects conditional role bindings must specify
	// version `3`. This requirement applies to the following operations: *
	// Getting a policy that includes a conditional role binding * Adding a
	// conditional role binding to a policy * Changing a conditional role
	// binding in a policy * Removing any role binding, with or without a
	// condition, from a policy that includes conditions **Important:** If
	// you use IAM Conditions, you must include the `etag` field whenever
	// you call `setIamPolicy`. If you omit this field, then IAM allows you
	// to overwrite a version `3` policy with a version `1` policy, and all
	// of the conditions in the version `3` policy are lost. If a policy
	// does not include any conditions, operations on that policy may
	// specify any valid version or leave the field unset. To learn which
	// resources support conditions in their IAM policies, see the [IAM
	// documentation](https://cloud.google.com/iam/help/conditions/resource-p
	// olicies).
	Version int64 `json:"version,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AuditConfigs") 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. "AuditConfigs") 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 *GoogleIamV1Policy) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleIamV1Policy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleIamV1SetIamPolicyRequest: Request message for `SetIamPolicy`
// method.
type GoogleIamV1SetIamPolicyRequest struct {
	// Policy: REQUIRED: The complete policy to be applied to the
	// `resource`. The size of the policy is limited to a few 10s of KB. An
	// empty policy is a valid policy but certain Cloud Platform services
	// (such as Projects) might reject them.
	Policy *GoogleIamV1Policy `json:"policy,omitempty"`

	// UpdateMask: OPTIONAL: A FieldMask specifying which fields of the
	// policy to modify. Only the fields in the mask will be modified. If no
	// mask is provided, the following default mask is used: `paths:
	// "bindings, etag"
	UpdateMask string `json:"updateMask,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Policy") 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. "Policy") 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 *GoogleIamV1SetIamPolicyRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleIamV1SetIamPolicyRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleIamV1TestIamPermissionsRequest: Request message for
// `TestIamPermissions` method.
type GoogleIamV1TestIamPermissionsRequest struct {
	// Permissions: The set of permissions to check for the `resource`.
	// Permissions with wildcards (such as '*' or 'storage.*') are not
	// allowed. For more information see [IAM
	// Overview](https://cloud.google.com/iam/docs/overview#permissions).
	Permissions []string `json:"permissions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Permissions") 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. "Permissions") 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 *GoogleIamV1TestIamPermissionsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleIamV1TestIamPermissionsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleIamV1TestIamPermissionsResponse: Response message for
// `TestIamPermissions` method.
type GoogleIamV1TestIamPermissionsResponse struct {
	// Permissions: A subset of `TestPermissionsRequest.permissions` that
	// the caller is allowed.
	Permissions []string `json:"permissions,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Permissions") 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. "Permissions") 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 *GoogleIamV1TestIamPermissionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleIamV1TestIamPermissionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleLongrunningListOperationsResponse: The response message for
// Operations.ListOperations.
type GoogleLongrunningListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Operations: A list of operations that matches the specified filter in
	// the request.
	Operations []*GoogleLongrunningOperation `json:"operations,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 *GoogleLongrunningListOperationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleLongrunningListOperationsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleLongrunningOperation: This resource represents a long-running
// operation that is the result of a network API call.
type GoogleLongrunningOperation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress. If `true`, the operation is completed, and either `error`
	// or `response` is available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation. It
	// typically contains progress information and common metadata such as
	// create time. Some services might not provide such metadata. Any
	// method that returns a long-running operation should document the
	// metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that originally returns it. If you use the default HTTP
	// mapping, the `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success. If
	// the original method returns no data on success, such as `Delete`, the
	// response is `google.protobuf.Empty`. If the original method is
	// standard `Get`/`Create`/`Update`, the response should be the
	// resource. For other methods, the response should have the type
	// `XxxResponse`, where `Xxx` is the original method name. For example,
	// if the original method name is `TakeSnapshot()`, the inferred
	// response type is `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Done") 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. "Done") 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 *GoogleLongrunningOperation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleLongrunningOperation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleProtobufEmpty: A generic empty message that you can re-use to
// avoid defining duplicated empty messages in your APIs. A typical
// example is to use it as the request or the response type of an API
// method. For instance: service Foo { rpc Bar(google.protobuf.Empty)
// returns (google.protobuf.Empty); } The JSON representation for
// `Empty` is empty JSON object `{}`.
type GoogleProtobufEmpty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// GoogleRpcPreconditionFailure: Describes what preconditions have
// failed. For example, if an RPC failed because it required the Terms
// of Service to be acknowledged, it could list the terms of service
// violation in the PreconditionFailure message.
type GoogleRpcPreconditionFailure struct {
	// Violations: Describes all precondition violations.
	Violations []*GoogleRpcPreconditionFailureViolation `json:"violations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Violations") 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. "Violations") 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 *GoogleRpcPreconditionFailure) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleRpcPreconditionFailure
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleRpcPreconditionFailureViolation: A message type used to
// describe a single precondition failure.
type GoogleRpcPreconditionFailureViolation struct {
	// Description: A description of how the precondition failed. Developers
	// can use this description to understand how to fix the failure. For
	// example: "Terms of service not accepted".
	Description string `json:"description,omitempty"`

	// Subject: The subject, relative to the type, that failed. For example,
	// "google.com/cloud" relative to the "TOS" type would indicate which
	// terms of service is being referenced.
	Subject string `json:"subject,omitempty"`

	// Type: The type of PreconditionFailure. We recommend using a
	// service-specific enum type to define the supported precondition
	// violation subjects. For example, "TOS" for "Terms of Service
	// violation".
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *GoogleRpcPreconditionFailureViolation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleRpcPreconditionFailureViolation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleRpcStatus: The `Status` type defines a logical error model that
// is suitable for different programming environments, including REST
// APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc).
// Each `Status` message contains three pieces of data: error code,
// error message, and error details. You can find out more about this
// error model and how to work with it in the [API Design
// Guide](https://cloud.google.com/apis/design/errors).
type GoogleRpcStatus struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details. There is a
	// common set of message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any user-facing error message should be localized and sent
	// in the google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") 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. "Code") 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 *GoogleRpcStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleRpcStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleTypeExpr: Represents a textual expression in the Common
// Expression Language (CEL) syntax. CEL is a C-like expression
// language. The syntax and semantics of CEL are documented at
// https://github.com/google/cel-spec. Example (Comparison): title:
// "Summary size limit" description: "Determines if a summary is less
// than 100 chars" expression: "document.summary.size() < 100" Example
// (Equality): title: "Requestor is owner" description: "Determines if
// requestor is the document owner" expression: "document.owner ==
// request.auth.claims.email" Example (Logic): title: "Public documents"
// description: "Determine whether the document should be publicly
// visible" expression: "document.type != 'private' && document.type !=
// 'internal'" Example (Data Manipulation): title: "Notification string"
// description: "Create a notification string with a timestamp."
// expression: "'New message received at ' +
// string(document.create_time)" The exact variables and functions that
// may be referenced within an expression are determined by the service
// that evaluates it. See the service documentation for additional
// information.
type GoogleTypeExpr struct {
	// Description: Optional. Description of the expression. This is a
	// longer text which describes the expression, e.g. when hovered over it
	// in a UI.
	Description string `json:"description,omitempty"`

	// Expression: Textual representation of an expression in Common
	// Expression Language syntax.
	Expression string `json:"expression,omitempty"`

	// Location: Optional. String indicating the location of the expression
	// for error reporting, e.g. a file name and a position in the file.
	Location string `json:"location,omitempty"`

	// Title: Optional. Title for the expression, i.e. a short string
	// describing its purpose. This can be used e.g. in UIs which allow to
	// enter the expression.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") 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. "Description") 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 *GoogleTypeExpr) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeExpr
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "apigee.hybrid.issuers.list":

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

// List: Lists hybrid services and its trusted issuers service account
// ids. This api is authenticated and unauthorized(allow all the users)
// and used by runtime authn-authz service to query control plane's
// issuer service account ids.
func (r *HybridIssuersService) List(name string) *HybridIssuersListCall {
	c := &HybridIssuersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *HybridIssuersListCall) Fields(s ...googleapi.Field) *HybridIssuersListCall {
	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 *HybridIssuersListCall) IfNoneMatch(entityTag string) *HybridIssuersListCall {
	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 *HybridIssuersListCall) Context(ctx context.Context) *HybridIssuersListCall {
	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 *HybridIssuersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *HybridIssuersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.hybrid.issuers.list" call.
// Exactly one of *GoogleCloudApigeeV1ListHybridIssuersResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListHybridIssuersResponse.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 *HybridIssuersListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListHybridIssuersResponse, 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 := &GoogleCloudApigeeV1ListHybridIssuersResponse{
		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": "Lists hybrid services and its trusted issuers service account ids. This api is authenticated and unauthorized(allow all the users) and used by runtime authn-authz service to query control plane's issuer service account ids.",
	//   "flatPath": "v1/hybrid/issuers",
	//   "httpMethod": "GET",
	//   "id": "apigee.hybrid.issuers.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Must be of the form `hybrid/issuers`.",
	//       "location": "path",
	//       "pattern": "^hybrid/issuers$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListHybridIssuersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.create":

type OrganizationsCreateCall struct {
	s                               *Service
	googlecloudapigeev1organization *GoogleCloudApigeeV1Organization
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Create: Creates an Apigee organization. See [Create an
// organization](https://docs.apigee.com/hybrid/latest/precog-provision).
func (r *OrganizationsService) Create(googlecloudapigeev1organization *GoogleCloudApigeeV1Organization) *OrganizationsCreateCall {
	c := &OrganizationsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.googlecloudapigeev1organization = googlecloudapigeev1organization
	return c
}

// Parent sets the optional parameter "parent": Required. Name of the
// GCP project in which to associate the Apigee organization. Pass the
// information as a query parameter using the following structure in
// your request: `projects/`
func (c *OrganizationsCreateCall) Parent(parent string) *OrganizationsCreateCall {
	c.urlParams_.Set("parent", parent)
	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 *OrganizationsCreateCall) Fields(s ...googleapi.Field) *OrganizationsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsCreateCall) Context(ctx context.Context) *OrganizationsCreateCall {
	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 *OrganizationsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1organization)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/organizations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.create" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Creates an Apigee organization. See [Create an organization](https://docs.apigee.com/hybrid/latest/precog-provision).",
	//   "flatPath": "v1/organizations",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.create",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the GCP project in which to associate the Apigee organization. Pass the information as a query parameter using the following structure in your request: `projects/`",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/organizations",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Organization"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.get":

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

// Get: Gets the profile for an Apigee organization. See
// [Organizations](https://docs.apigee.com/hybrid/latest/terminology#orga
// nizations).
func (r *OrganizationsService) Get(name string) *OrganizationsGetCall {
	c := &OrganizationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsGetCall) Fields(s ...googleapi.Field) *OrganizationsGetCall {
	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 *OrganizationsGetCall) IfNoneMatch(entityTag string) *OrganizationsGetCall {
	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 *OrganizationsGetCall) Context(ctx context.Context) *OrganizationsGetCall {
	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 *OrganizationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.get" call.
// Exactly one of *GoogleCloudApigeeV1Organization or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Organization.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 *OrganizationsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Organization, 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 := &GoogleCloudApigeeV1Organization{
		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": "Gets the profile for an Apigee organization. See [Organizations](https://docs.apigee.com/hybrid/latest/terminology#organizations).",
	//   "flatPath": "v1/organizations/{organizationsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Apigee organization name in the following format: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Organization"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.getDeployedIngressConfig":

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

// GetDeployedIngressConfig: Gets the deployed ingress configuration for
// an organization.
func (r *OrganizationsService) GetDeployedIngressConfig(name string) *OrganizationsGetDeployedIngressConfigCall {
	c := &OrganizationsGetDeployedIngressConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsGetDeployedIngressConfigCall) Fields(s ...googleapi.Field) *OrganizationsGetDeployedIngressConfigCall {
	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 *OrganizationsGetDeployedIngressConfigCall) IfNoneMatch(entityTag string) *OrganizationsGetDeployedIngressConfigCall {
	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 *OrganizationsGetDeployedIngressConfigCall) Context(ctx context.Context) *OrganizationsGetDeployedIngressConfigCall {
	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 *OrganizationsGetDeployedIngressConfigCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsGetDeployedIngressConfigCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.getDeployedIngressConfig" call.
// Exactly one of *GoogleCloudApigeeV1IngressConfig or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1IngressConfig.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 *OrganizationsGetDeployedIngressConfigCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1IngressConfig, 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 := &GoogleCloudApigeeV1IngressConfig{
		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": "Gets the deployed ingress configuration for an organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/deployedIngressConfig",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.getDeployedIngressConfig",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the deployed configuration for the organization in the following format: 'organizations/{org}/deployedIngressConfig'.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/deployedIngressConfig$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1IngressConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.getSyncAuthorization":

type OrganizationsGetSyncAuthorizationCall struct {
	s                                              *Service
	name                                           string
	googlecloudapigeev1getsyncauthorizationrequest *GoogleCloudApigeeV1GetSyncAuthorizationRequest
	urlParams_                                     gensupport.URLParams
	ctx_                                           context.Context
	header_                                        http.Header
}

// GetSyncAuthorization: Lists the service accounts with the permissions
// required to allow the Synchronizer to download environment data from
// the control plane. An ETag is returned in the response to
// `getSyncAuthorization`. Pass that ETag when calling
// [setSyncAuthorization](setSyncAuthorization) to ensure that you are
// updating the correct version. If you don't pass the ETag in the call
// to `setSyncAuthorization`, then the existing authorization is
// overwritten indiscriminately. For more information, see [Enable
// Synchronizer
// access](https://docs.apigee.com/hybrid/latest/synchronizer-access#enab
// le-synchronizer-access). **Note**: Available to Apigee hybrid only.
func (r *OrganizationsService) GetSyncAuthorization(name string, googlecloudapigeev1getsyncauthorizationrequest *GoogleCloudApigeeV1GetSyncAuthorizationRequest) *OrganizationsGetSyncAuthorizationCall {
	c := &OrganizationsGetSyncAuthorizationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1getsyncauthorizationrequest = googlecloudapigeev1getsyncauthorizationrequest
	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 *OrganizationsGetSyncAuthorizationCall) Fields(s ...googleapi.Field) *OrganizationsGetSyncAuthorizationCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsGetSyncAuthorizationCall) Context(ctx context.Context) *OrganizationsGetSyncAuthorizationCall {
	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 *OrganizationsGetSyncAuthorizationCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsGetSyncAuthorizationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1getsyncauthorizationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:getSyncAuthorization")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.getSyncAuthorization" call.
// Exactly one of *GoogleCloudApigeeV1SyncAuthorization or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1SyncAuthorization.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 *OrganizationsGetSyncAuthorizationCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1SyncAuthorization, 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 := &GoogleCloudApigeeV1SyncAuthorization{
		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": "Lists the service accounts with the permissions required to allow the Synchronizer to download environment data from the control plane. An ETag is returned in the response to `getSyncAuthorization`. Pass that ETag when calling [setSyncAuthorization](setSyncAuthorization) to ensure that you are updating the correct version. If you don't pass the ETag in the call to `setSyncAuthorization`, then the existing authorization is overwritten indiscriminately. For more information, see [Enable Synchronizer access](https://docs.apigee.com/hybrid/latest/synchronizer-access#enable-synchronizer-access). **Note**: Available to Apigee hybrid only.",
	//   "flatPath": "v1/organizations/{organizationsId}:getSyncAuthorization",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.getSyncAuthorization",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the Apigee organization. Use the following structure in your request: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:getSyncAuthorization",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1GetSyncAuthorizationRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1SyncAuthorization"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.list":

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

// List: Lists the Apigee organizations and associated GCP projects that
// you have permission to access. See
// [Organizations](https://docs.apigee.com/hybrid/latest/terminology#orga
// nizations).
func (r *OrganizationsService) List(parent string) *OrganizationsListCall {
	c := &OrganizationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsListCall) Fields(s ...googleapi.Field) *OrganizationsListCall {
	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 *OrganizationsListCall) IfNoneMatch(entityTag string) *OrganizationsListCall {
	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 *OrganizationsListCall) Context(ctx context.Context) *OrganizationsListCall {
	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 *OrganizationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.list" call.
// Exactly one of *GoogleCloudApigeeV1ListOrganizationsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListOrganizationsResponse.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 *OrganizationsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListOrganizationsResponse, 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 := &GoogleCloudApigeeV1ListOrganizationsResponse{
		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": "Lists the Apigee organizations and associated GCP projects that you have permission to access. See [Organizations](https://docs.apigee.com/hybrid/latest/terminology#organizations).",
	//   "flatPath": "v1/organizations",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Use the following structure in your request: `organizations`",
	//       "location": "path",
	//       "pattern": "^organizations$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListOrganizationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.setSyncAuthorization":

type OrganizationsSetSyncAuthorizationCall struct {
	s                                    *Service
	name                                 string
	googlecloudapigeev1syncauthorization *GoogleCloudApigeeV1SyncAuthorization
	urlParams_                           gensupport.URLParams
	ctx_                                 context.Context
	header_                              http.Header
}

// SetSyncAuthorization: Sets the permissions required to allow the
// Synchronizer to download environment data from the control plane. You
// must call this API to enable proper functioning of hybrid. Pass the
// ETag when calling `setSyncAuthorization` to ensure that you are
// updating the correct version. To get an ETag, call
// [getSyncAuthorization](getSyncAuthorization). If you don't pass the
// ETag in the call to `setSyncAuthorization`, then the existing
// authorization is overwritten indiscriminately. For more information,
// see [Enable Synchronizer
// access](https://docs.apigee.com/hybrid/latest/synchronizer-access#enab
// le-synchronizer-access). **Note**: Available to Apigee hybrid only.
func (r *OrganizationsService) SetSyncAuthorization(name string, googlecloudapigeev1syncauthorization *GoogleCloudApigeeV1SyncAuthorization) *OrganizationsSetSyncAuthorizationCall {
	c := &OrganizationsSetSyncAuthorizationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1syncauthorization = googlecloudapigeev1syncauthorization
	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 *OrganizationsSetSyncAuthorizationCall) Fields(s ...googleapi.Field) *OrganizationsSetSyncAuthorizationCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsSetSyncAuthorizationCall) Context(ctx context.Context) *OrganizationsSetSyncAuthorizationCall {
	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 *OrganizationsSetSyncAuthorizationCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSetSyncAuthorizationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1syncauthorization)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:setSyncAuthorization")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.setSyncAuthorization" call.
// Exactly one of *GoogleCloudApigeeV1SyncAuthorization or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1SyncAuthorization.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 *OrganizationsSetSyncAuthorizationCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1SyncAuthorization, 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 := &GoogleCloudApigeeV1SyncAuthorization{
		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": "Sets the permissions required to allow the Synchronizer to download environment data from the control plane. You must call this API to enable proper functioning of hybrid. Pass the ETag when calling `setSyncAuthorization` to ensure that you are updating the correct version. To get an ETag, call [getSyncAuthorization](getSyncAuthorization). If you don't pass the ETag in the call to `setSyncAuthorization`, then the existing authorization is overwritten indiscriminately. For more information, see [Enable Synchronizer access](https://docs.apigee.com/hybrid/latest/synchronizer-access#enable-synchronizer-access). **Note**: Available to Apigee hybrid only.",
	//   "flatPath": "v1/organizations/{organizationsId}:setSyncAuthorization",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.setSyncAuthorization",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the Apigee organization. Use the following structure in your request: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:setSyncAuthorization",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1SyncAuthorization"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1SyncAuthorization"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.update":

type OrganizationsUpdateCall struct {
	s                               *Service
	name                            string
	googlecloudapigeev1organization *GoogleCloudApigeeV1Organization
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Update: Updates the properties for an Apigee organization. No other
// fields in the organization profile will be updated.
func (r *OrganizationsService) Update(name string, googlecloudapigeev1organization *GoogleCloudApigeeV1Organization) *OrganizationsUpdateCall {
	c := &OrganizationsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1organization = googlecloudapigeev1organization
	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 *OrganizationsUpdateCall) Fields(s ...googleapi.Field) *OrganizationsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsUpdateCall) Context(ctx context.Context) *OrganizationsUpdateCall {
	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 *OrganizationsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1organization)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.update" call.
// Exactly one of *GoogleCloudApigeeV1Organization or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Organization.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 *OrganizationsUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Organization, 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 := &GoogleCloudApigeeV1Organization{
		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": "Updates the properties for an Apigee organization. No other fields in the organization profile will be updated.",
	//   "flatPath": "v1/organizations/{organizationsId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Apigee organization name in the following format: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Organization"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Organization"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.analytics.datastores.create":

type OrganizationsAnalyticsDatastoresCreateCall struct {
	s                            *Service
	parent                       string
	googlecloudapigeev1datastore *GoogleCloudApigeeV1Datastore
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Create: Create a Datastore for an org
func (r *OrganizationsAnalyticsDatastoresService) Create(parent string, googlecloudapigeev1datastore *GoogleCloudApigeeV1Datastore) *OrganizationsAnalyticsDatastoresCreateCall {
	c := &OrganizationsAnalyticsDatastoresCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1datastore = googlecloudapigeev1datastore
	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 *OrganizationsAnalyticsDatastoresCreateCall) Fields(s ...googleapi.Field) *OrganizationsAnalyticsDatastoresCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsAnalyticsDatastoresCreateCall) Context(ctx context.Context) *OrganizationsAnalyticsDatastoresCreateCall {
	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 *OrganizationsAnalyticsDatastoresCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAnalyticsDatastoresCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1datastore)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/analytics/datastores")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.analytics.datastores.create" call.
// Exactly one of *GoogleCloudApigeeV1Datastore or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Datastore.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 *OrganizationsAnalyticsDatastoresCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Datastore, 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 := &GoogleCloudApigeeV1Datastore{
		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": "Create a Datastore for an org",
	//   "flatPath": "v1/organizations/{organizationsId}/analytics/datastores",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.analytics.datastores.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent organization name. Must be of the form `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/analytics/datastores",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Datastore"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Datastore"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.analytics.datastores.delete":

type OrganizationsAnalyticsDatastoresDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Delete a Datastore from an org.
func (r *OrganizationsAnalyticsDatastoresService) Delete(name string) *OrganizationsAnalyticsDatastoresDeleteCall {
	c := &OrganizationsAnalyticsDatastoresDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsAnalyticsDatastoresDeleteCall) Fields(s ...googleapi.Field) *OrganizationsAnalyticsDatastoresDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsAnalyticsDatastoresDeleteCall) Context(ctx context.Context) *OrganizationsAnalyticsDatastoresDeleteCall {
	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 *OrganizationsAnalyticsDatastoresDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAnalyticsDatastoresDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.analytics.datastores.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsAnalyticsDatastoresDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Delete a Datastore from an org.",
	//   "flatPath": "v1/organizations/{organizationsId}/analytics/datastores/{datastoresId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.analytics.datastores.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Resource name of the Datastore to be deleted. Must be of the form `organizations/{org}/analytics/datastores/{datastoreId}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/analytics/datastores/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.analytics.datastores.get":

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

// Get: Get a Datastore
func (r *OrganizationsAnalyticsDatastoresService) Get(name string) *OrganizationsAnalyticsDatastoresGetCall {
	c := &OrganizationsAnalyticsDatastoresGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsAnalyticsDatastoresGetCall) Fields(s ...googleapi.Field) *OrganizationsAnalyticsDatastoresGetCall {
	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 *OrganizationsAnalyticsDatastoresGetCall) IfNoneMatch(entityTag string) *OrganizationsAnalyticsDatastoresGetCall {
	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 *OrganizationsAnalyticsDatastoresGetCall) Context(ctx context.Context) *OrganizationsAnalyticsDatastoresGetCall {
	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 *OrganizationsAnalyticsDatastoresGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAnalyticsDatastoresGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.analytics.datastores.get" call.
// Exactly one of *GoogleCloudApigeeV1Datastore or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Datastore.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 *OrganizationsAnalyticsDatastoresGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Datastore, 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 := &GoogleCloudApigeeV1Datastore{
		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": "Get a Datastore",
	//   "flatPath": "v1/organizations/{organizationsId}/analytics/datastores/{datastoresId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.analytics.datastores.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Resource name of the Datastore to be get. Must be of the form `organizations/{org}/analytics/datastores/{datastoreId}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/analytics/datastores/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Datastore"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.analytics.datastores.list":

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

// List: List Datastores
func (r *OrganizationsAnalyticsDatastoresService) List(parent string) *OrganizationsAnalyticsDatastoresListCall {
	c := &OrganizationsAnalyticsDatastoresListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// TargetType sets the optional parameter "targetType": TargetType is
// used to fetch all Datastores that match the type
func (c *OrganizationsAnalyticsDatastoresListCall) TargetType(targetType string) *OrganizationsAnalyticsDatastoresListCall {
	c.urlParams_.Set("targetType", targetType)
	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 *OrganizationsAnalyticsDatastoresListCall) Fields(s ...googleapi.Field) *OrganizationsAnalyticsDatastoresListCall {
	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 *OrganizationsAnalyticsDatastoresListCall) IfNoneMatch(entityTag string) *OrganizationsAnalyticsDatastoresListCall {
	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 *OrganizationsAnalyticsDatastoresListCall) Context(ctx context.Context) *OrganizationsAnalyticsDatastoresListCall {
	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 *OrganizationsAnalyticsDatastoresListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAnalyticsDatastoresListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/analytics/datastores")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.analytics.datastores.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDatastoresResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDatastoresResponse.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 *OrganizationsAnalyticsDatastoresListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDatastoresResponse, 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 := &GoogleCloudApigeeV1ListDatastoresResponse{
		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": "List Datastores",
	//   "flatPath": "v1/organizations/{organizationsId}/analytics/datastores",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.analytics.datastores.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent organization name. Must be of the form `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetType": {
	//       "description": "Optional. TargetType is used to fetch all Datastores that match the type",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/analytics/datastores",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDatastoresResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.analytics.datastores.test":

type OrganizationsAnalyticsDatastoresTestCall struct {
	s                            *Service
	parent                       string
	googlecloudapigeev1datastore *GoogleCloudApigeeV1Datastore
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Test: Test if Datastore configuration is correct. This includes
// checking if credentials provided by customer have required
// permissions in target destination storage
func (r *OrganizationsAnalyticsDatastoresService) Test(parent string, googlecloudapigeev1datastore *GoogleCloudApigeeV1Datastore) *OrganizationsAnalyticsDatastoresTestCall {
	c := &OrganizationsAnalyticsDatastoresTestCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1datastore = googlecloudapigeev1datastore
	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 *OrganizationsAnalyticsDatastoresTestCall) Fields(s ...googleapi.Field) *OrganizationsAnalyticsDatastoresTestCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsAnalyticsDatastoresTestCall) Context(ctx context.Context) *OrganizationsAnalyticsDatastoresTestCall {
	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 *OrganizationsAnalyticsDatastoresTestCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAnalyticsDatastoresTestCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1datastore)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/analytics/datastores:test")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.analytics.datastores.test" call.
// Exactly one of *GoogleCloudApigeeV1TestDatastoreResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1TestDatastoreResponse.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 *OrganizationsAnalyticsDatastoresTestCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1TestDatastoreResponse, 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 := &GoogleCloudApigeeV1TestDatastoreResponse{
		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": "Test if Datastore configuration is correct. This includes checking if credentials provided by customer have required permissions in target destination storage",
	//   "flatPath": "v1/organizations/{organizationsId}/analytics/datastores:test",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.analytics.datastores.test",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent organization name Must be of the form `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/analytics/datastores:test",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Datastore"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1TestDatastoreResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.analytics.datastores.update":

type OrganizationsAnalyticsDatastoresUpdateCall struct {
	s                            *Service
	name                         string
	googlecloudapigeev1datastore *GoogleCloudApigeeV1Datastore
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Update: Update a Datastore
func (r *OrganizationsAnalyticsDatastoresService) Update(name string, googlecloudapigeev1datastore *GoogleCloudApigeeV1Datastore) *OrganizationsAnalyticsDatastoresUpdateCall {
	c := &OrganizationsAnalyticsDatastoresUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1datastore = googlecloudapigeev1datastore
	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 *OrganizationsAnalyticsDatastoresUpdateCall) Fields(s ...googleapi.Field) *OrganizationsAnalyticsDatastoresUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsAnalyticsDatastoresUpdateCall) Context(ctx context.Context) *OrganizationsAnalyticsDatastoresUpdateCall {
	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 *OrganizationsAnalyticsDatastoresUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAnalyticsDatastoresUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1datastore)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.analytics.datastores.update" call.
// Exactly one of *GoogleCloudApigeeV1Datastore or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Datastore.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 *OrganizationsAnalyticsDatastoresUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Datastore, 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 := &GoogleCloudApigeeV1Datastore{
		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": "Update a Datastore",
	//   "flatPath": "v1/organizations/{organizationsId}/analytics/datastores/{datastoresId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.analytics.datastores.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of datastore to be updated. Must be of the form `organizations/{org}/analytics/datastores/{datastoreId}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/analytics/datastores/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Datastore"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Datastore"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.attributes":

type OrganizationsApiproductsAttributesCall struct {
	s                             *Service
	name                          string
	googlecloudapigeev1attributes *GoogleCloudApigeeV1Attributes
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Attributes: Updates or creates API product attributes. This API
// **replaces** the current list of attributes with the attributes
// specified in the request body. In this way, you can update existing
// attributes, add new attributes, or delete existing attributes by
// omitting them from the request body. OAuth access tokens and Key
// Management Service (KMS) entities (apps, developers, and API
// products) are cached for 180 seconds (current default). Any custom
// attributes associated with entities also get cached for at least 180
// seconds after entity is accessed during runtime. In this case, the
// `ExpiresIn` element on the OAuthV2 policy won't be able to expire an
// access token in less than 180 seconds.
func (r *OrganizationsApiproductsService) Attributes(name string, googlecloudapigeev1attributes *GoogleCloudApigeeV1Attributes) *OrganizationsApiproductsAttributesCall {
	c := &OrganizationsApiproductsAttributesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1attributes = googlecloudapigeev1attributes
	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 *OrganizationsApiproductsAttributesCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsAttributesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApiproductsAttributesCall) Context(ctx context.Context) *OrganizationsApiproductsAttributesCall {
	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 *OrganizationsApiproductsAttributesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsAttributesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1attributes)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/attributes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.attributes" call.
// Exactly one of *GoogleCloudApigeeV1Attributes or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attributes.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 *OrganizationsApiproductsAttributesCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attributes, 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 := &GoogleCloudApigeeV1Attributes{
		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": "Updates or creates API product attributes. This API **replaces** the current list of attributes with the attributes specified in the request body. In this way, you can update existing attributes, add new attributes, or delete existing attributes by omitting them from the request body. OAuth access tokens and Key Management Service (KMS) entities (apps, developers, and API products) are cached for 180 seconds (current default). Any custom attributes associated with entities also get cached for at least 180 seconds after entity is accessed during runtime. In this case, the `ExpiresIn` element on the OAuthV2 policy won't be able to expire an access token in less than 180 seconds.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}/attributes",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.apiproducts.attributes",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "**Required.** API product name in the following form: organizations/organization_ID/apiproducts/api_product_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/attributes",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.create":

type OrganizationsApiproductsCreateCall struct {
	s                             *Service
	parent                        string
	googlecloudapigeev1apiproduct *GoogleCloudApigeeV1ApiProduct
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Create: Creates an API product in an organization. You create API
// products after you have proxied backend services using API proxies.
// An API product is a collection of API resources combined with quota
// settings and metadata that you can use to deliver customized and
// productized API bundles to your developer community. This metadata
// can include: - Scope - Environments - API proxies - Extensible
// profile API products enable you repackage APIs on-the-fly, without
// having to do any additional coding or configuration. Apigee
// recommends that you start with a simple API product including only
// required elements. You then provision credentials to apps to enable
// them to start testing your APIs. After you have authentication and
// authorization working against a simple API product, you can iterate
// to create finer grained API products, defining different sets of API
// resources for each API product. *WARNING:* - If you don't specify an
// API proxy in the request body, *any* app associated with the product
// can make calls to *any* API in your entire organization. - If you
// don't specify an environment in the request body, the product allows
// access to all environments. For more information, see
// {{what_api_product}}
func (r *OrganizationsApiproductsService) Create(parent string, googlecloudapigeev1apiproduct *GoogleCloudApigeeV1ApiProduct) *OrganizationsApiproductsCreateCall {
	c := &OrganizationsApiproductsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1apiproduct = googlecloudapigeev1apiproduct
	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 *OrganizationsApiproductsCreateCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApiproductsCreateCall) Context(ctx context.Context) *OrganizationsApiproductsCreateCall {
	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 *OrganizationsApiproductsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1apiproduct)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/apiproducts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.create" call.
// Exactly one of *GoogleCloudApigeeV1ApiProduct or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ApiProduct.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 *OrganizationsApiproductsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProduct, 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 := &GoogleCloudApigeeV1ApiProduct{
		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": "Creates an API product in an organization. You create API products after you have proxied backend services using API proxies. An API product is a collection of API resources combined with quota settings and metadata that you can use to deliver customized and productized API bundles to your developer community. This metadata can include: - Scope - Environments - API proxies - Extensible profile API products enable you repackage APIs on-the-fly, without having to do any additional coding or configuration. Apigee recommends that you start with a simple API product including only required elements. You then provision credentials to apps to enable them to start testing your APIs. After you have authentication and authorization working against a simple API product, you can iterate to create finer grained API products, defining different sets of API resources for each API product. *WARNING:* - If you don't specify an API proxy in the request body, *any* app associated with the product can make calls to *any* API in your entire organization. - If you don't specify an environment in the request body, the product allows access to all environments. For more information, see {{what_api_product}}",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.apiproducts.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent organization name under which the API product will be created. Must be in the following form: organizations/organization_ID ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/apiproducts",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1ApiProduct"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProduct"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.delete":

type OrganizationsApiproductsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an API product from an organization. Deleting an API
// product causes app requests to the resource URIs defined in the API
// product to fail. Ensure that you create a new API product to serve
// existing apps, unless your intention is to disable access to the
// resources defined in the API product. The API product name required
// in the request URL is the internal name of the product, not the
// display name. While they may be the same, it depends on whether the
// API product was created via the UI or the API. View the list of API
// products to verify the internal name.
func (r *OrganizationsApiproductsService) Delete(name string) *OrganizationsApiproductsDeleteCall {
	c := &OrganizationsApiproductsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApiproductsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApiproductsDeleteCall) Context(ctx context.Context) *OrganizationsApiproductsDeleteCall {
	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 *OrganizationsApiproductsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.delete" call.
// Exactly one of *GoogleCloudApigeeV1ApiProduct or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ApiProduct.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 *OrganizationsApiproductsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProduct, 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 := &GoogleCloudApigeeV1ApiProduct{
		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": "Deletes an API product from an organization. Deleting an API product causes app requests to the resource URIs defined in the API product to fail. Ensure that you create a new API product to serve existing apps, unless your intention is to disable access to the resources defined in the API product. The API product name required in the request URL is the internal name of the product, not the display name. While they may be the same, it depends on whether the API product was created via the UI or the API. View the list of API products to verify the internal name.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.apiproducts.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. API product name in the following form: organizations/organization_ID/apiproducts/api_product_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProduct"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.get":

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

// Get: Gets configuration details for an API product. The API product
// name required in the request URL is the internal name of the product,
// not the display name. While they may be the same, it depends on
// whether the API product was created via the UI or the API. View the
// list of API products to verify the internal name.
func (r *OrganizationsApiproductsService) Get(name string) *OrganizationsApiproductsGetCall {
	c := &OrganizationsApiproductsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApiproductsGetCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsGetCall {
	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 *OrganizationsApiproductsGetCall) IfNoneMatch(entityTag string) *OrganizationsApiproductsGetCall {
	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 *OrganizationsApiproductsGetCall) Context(ctx context.Context) *OrganizationsApiproductsGetCall {
	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 *OrganizationsApiproductsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.get" call.
// Exactly one of *GoogleCloudApigeeV1ApiProduct or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ApiProduct.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 *OrganizationsApiproductsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProduct, 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 := &GoogleCloudApigeeV1ApiProduct{
		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": "Gets configuration details for an API product. The API product name required in the request URL is the internal name of the product, not the display name. While they may be the same, it depends on whether the API product was created via the UI or the API. View the list of API products to verify the internal name.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apiproducts.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "**Required.** API product name in the following form: organizations/organization_ID/apiproducts/api_product_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProduct"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.list":

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

// List: Lists all API product names for an organization. Filter the
// list by passing an `attributename` and `attibutevalue`. The limit on
// the number of API products returned by the API is 1000. You can
// paginate the list of API products returned using the `startKey` and
// `count` query parameters.
func (r *OrganizationsApiproductsService) List(parent string) *OrganizationsApiproductsListCall {
	c := &OrganizationsApiproductsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Attributename sets the optional parameter "attributename": The name
// of the attribute to search.
func (c *OrganizationsApiproductsListCall) Attributename(attributename string) *OrganizationsApiproductsListCall {
	c.urlParams_.Set("attributename", attributename)
	return c
}

// Attributevalue sets the optional parameter "attributevalue": The
// value of the attribute.
func (c *OrganizationsApiproductsListCall) Attributevalue(attributevalue string) *OrganizationsApiproductsListCall {
	c.urlParams_.Set("attributevalue", attributevalue)
	return c
}

// Count sets the optional parameter "count": Enter the number of API
// products you want returned in the API call. The limit is 1000.
func (c *OrganizationsApiproductsListCall) Count(count int64) *OrganizationsApiproductsListCall {
	c.urlParams_.Set("count", fmt.Sprint(count))
	return c
}

// Expand sets the optional parameter "expand": Set to `true` to get
// expanded details about each API.
func (c *OrganizationsApiproductsListCall) Expand(expand bool) *OrganizationsApiproductsListCall {
	c.urlParams_.Set("expand", fmt.Sprint(expand))
	return c
}

// StartKey sets the optional parameter "startKey": Gets a list of API
// products starting with a specific API product in the list. For
// example, if you're returning 50 API products at a time (using the
// `count` query parameter), you can view products 50-99 by entering the
// name of the 50th API product in the first API (without using
// `startKey`). Product name is case sensitive.
func (c *OrganizationsApiproductsListCall) StartKey(startKey string) *OrganizationsApiproductsListCall {
	c.urlParams_.Set("startKey", startKey)
	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 *OrganizationsApiproductsListCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsListCall {
	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 *OrganizationsApiproductsListCall) IfNoneMatch(entityTag string) *OrganizationsApiproductsListCall {
	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 *OrganizationsApiproductsListCall) Context(ctx context.Context) *OrganizationsApiproductsListCall {
	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 *OrganizationsApiproductsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/apiproducts")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.list" call.
// Exactly one of *GoogleCloudApigeeV1ListApiProductsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListApiProductsResponse.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 *OrganizationsApiproductsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListApiProductsResponse, 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 := &GoogleCloudApigeeV1ListApiProductsResponse{
		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": "Lists all API product names for an organization. Filter the list by passing an `attributename` and `attibutevalue`. The limit on the number of API products returned by the API is 1000. You can paginate the list of API products returned using the `startKey` and `count` query parameters.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apiproducts.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "attributename": {
	//       "description": "The name of the attribute to search.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "attributevalue": {
	//       "description": "The value of the attribute.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "count": {
	//       "description": "Enter the number of API products you want returned in the API call. The limit is 1000.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "expand": {
	//       "description": "Set to `true` to get expanded details about each API.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "**Required.** The parent organization name in the following form: organizations/organization_ID ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "startKey": {
	//       "description": "Gets a list of API products starting with a specific API product in the list. For example, if you're returning 50 API products at a time (using the `count` query parameter), you can view products 50-99 by entering the name of the 50th API product in the first API (without using `startKey`). Product name is case sensitive.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/apiproducts",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListApiProductsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.update":

type OrganizationsApiproductsUpdateCall struct {
	s                             *Service
	name                          string
	googlecloudapigeev1apiproduct *GoogleCloudApigeeV1ApiProduct
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Update: Updates an existing API product. You must include all
// required values, whether or not you are updating them, as well as any
// optional values that you are updating. The API product name required
// in the request URL is the internal name of the product, not the
// Display Name. While they may be the same, it depends on whether the
// API product was created via UI or API. View the list of API products
// to identify their internal names.
func (r *OrganizationsApiproductsService) Update(name string, googlecloudapigeev1apiproduct *GoogleCloudApigeeV1ApiProduct) *OrganizationsApiproductsUpdateCall {
	c := &OrganizationsApiproductsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1apiproduct = googlecloudapigeev1apiproduct
	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 *OrganizationsApiproductsUpdateCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApiproductsUpdateCall) Context(ctx context.Context) *OrganizationsApiproductsUpdateCall {
	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 *OrganizationsApiproductsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1apiproduct)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.update" call.
// Exactly one of *GoogleCloudApigeeV1ApiProduct or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ApiProduct.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 *OrganizationsApiproductsUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProduct, 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 := &GoogleCloudApigeeV1ApiProduct{
		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": "Updates an existing API product. You must include all required values, whether or not you are updating them, as well as any optional values that you are updating. The API product name required in the request URL is the internal name of the product, not the Display Name. While they may be the same, it depends on whether the API product was created via UI or API. View the list of API products to identify their internal names.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.apiproducts.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "**Required.** API product name in the following form: organizations/organization_ID/apiproducts/api_product_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1ApiProduct"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProduct"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.attributes.delete":

type OrganizationsApiproductsAttributesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an API product attribute.
func (r *OrganizationsApiproductsAttributesService) Delete(name string) *OrganizationsApiproductsAttributesDeleteCall {
	c := &OrganizationsApiproductsAttributesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApiproductsAttributesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsAttributesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApiproductsAttributesDeleteCall) Context(ctx context.Context) *OrganizationsApiproductsAttributesDeleteCall {
	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 *OrganizationsApiproductsAttributesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsAttributesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.attributes.delete" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsApiproductsAttributesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Deletes an API product attribute.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}/attributes/{attributesId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.apiproducts.attributes.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "**Required.** API product name in the following form: organizations/organization_ID/apiproducts/api_product_name/attributes/attribute_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.attributes.get":

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

// Get: Returns the value of an API product attribute.
func (r *OrganizationsApiproductsAttributesService) Get(name string) *OrganizationsApiproductsAttributesGetCall {
	c := &OrganizationsApiproductsAttributesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApiproductsAttributesGetCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsAttributesGetCall {
	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 *OrganizationsApiproductsAttributesGetCall) IfNoneMatch(entityTag string) *OrganizationsApiproductsAttributesGetCall {
	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 *OrganizationsApiproductsAttributesGetCall) Context(ctx context.Context) *OrganizationsApiproductsAttributesGetCall {
	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 *OrganizationsApiproductsAttributesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsAttributesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.attributes.get" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsApiproductsAttributesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Returns the value of an API product attribute.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}/attributes/{attributesId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apiproducts.attributes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "**Required.** API product name in the following form: organizations/organization_ID/apiproducts/api_product_name/attributes/attribute_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.attributes.list":

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

// List: Returns a list of all API product attributes.
func (r *OrganizationsApiproductsAttributesService) List(parent string) *OrganizationsApiproductsAttributesListCall {
	c := &OrganizationsApiproductsAttributesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsApiproductsAttributesListCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsAttributesListCall {
	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 *OrganizationsApiproductsAttributesListCall) IfNoneMatch(entityTag string) *OrganizationsApiproductsAttributesListCall {
	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 *OrganizationsApiproductsAttributesListCall) Context(ctx context.Context) *OrganizationsApiproductsAttributesListCall {
	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 *OrganizationsApiproductsAttributesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsAttributesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/attributes")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.attributes.list" call.
// Exactly one of *GoogleCloudApigeeV1Attributes or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attributes.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 *OrganizationsApiproductsAttributesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attributes, 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 := &GoogleCloudApigeeV1Attributes{
		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": "Returns a list of all API product attributes.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}/attributes",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apiproducts.attributes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent organization name. Must be in the following form: organizations/organization_ID/apiproducts/api_product_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attributes",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apiproducts.attributes.updateApiProductAttribute":

type OrganizationsApiproductsAttributesUpdateApiProductAttributeCall struct {
	s                            *Service
	name                         string
	googlecloudapigeev1attribute *GoogleCloudApigeeV1Attribute
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// UpdateApiProductAttribute: Updates the value of an API product
// attribute. Limitations are: OAuth access tokens and Key Management
// Service (KMS) entities (apps, developers, and API products) are
// cached for 180 seconds (current default). Any custom attributes
// associated with entities also get cached for at least 180 seconds
// after entity is accessed during runtime. In this case, the
// `ExpiresIn` element on the OAuthV2 policy won't be able to expire an
// access token in less than 180 seconds.
func (r *OrganizationsApiproductsAttributesService) UpdateApiProductAttribute(name string, googlecloudapigeev1attribute *GoogleCloudApigeeV1Attribute) *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall {
	c := &OrganizationsApiproductsAttributesUpdateApiProductAttributeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1attribute = googlecloudapigeev1attribute
	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 *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall) Fields(s ...googleapi.Field) *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall) Context(ctx context.Context) *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall {
	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 *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1attribute)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apiproducts.attributes.updateApiProductAttribute" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsApiproductsAttributesUpdateApiProductAttributeCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Updates the value of an API product attribute. Limitations are: OAuth access tokens and Key Management Service (KMS) entities (apps, developers, and API products) are cached for 180 seconds (current default). Any custom attributes associated with entities also get cached for at least 180 seconds after entity is accessed during runtime. In this case, the `ExpiresIn` element on the OAuthV2 policy won't be able to expire an access token in less than 180 seconds.",
	//   "flatPath": "v1/organizations/{organizationsId}/apiproducts/{apiproductsId}/attributes/{attributesId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.apiproducts.attributes.updateApiProductAttribute",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "**Required.** API product name in the following form: organizations/organization_ID/apiproducts/api_product_name ",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apiproducts/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.create":

type OrganizationsApisCreateCall struct {
	s                 *Service
	parent            string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates an API proxy. The API proxy created will not be
// accessible at runtime until it is deployed to an environment. Create
// a new API proxy by setting the `name` query parameter to the name of
// the API proxy. Import an API proxy configuration bundle stored in zip
// format on your local machine to your organization by doing the
// following: * Set the `name` query parameter to the name of the API
// proxy. * Set the `action` query parameter to `import`. * Set the
// `Content-Type` header to `multipart/form-data`. * Pass as a file the
// name of API proxy configuration bundle stored in zip format on your
// local machine using the `file` form field. **Note**: To validate the
// API proxy configuration bundle only without importing it, set the
// `action` query parameter to `validate`. When importing an API proxy
// configuration bundle, if the API proxy does not exist, it will be
// created. If the API proxy exists, then a new revision is created.
// Invalid API proxy configurations are rejected, and a list of
// validation errors is returned to the client.
func (r *OrganizationsApisService) Create(parent string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsApisCreateCall {
	c := &OrganizationsApisCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleapihttpbody = googleapihttpbody
	return c
}

// Action sets the optional parameter "action": Action to perform when
// importing an API proxy configuration bundle. Set this parameter to
// one of the following values: * `import` to import the API proxy
// configuration bundle. * `validate` to validate the API proxy
// configuration bundle without importing it.
func (c *OrganizationsApisCreateCall) Action(action string) *OrganizationsApisCreateCall {
	c.urlParams_.Set("action", action)
	return c
}

// Name sets the optional parameter "name": Name of the API proxy.
// Restrict the characters used to: A-Za-z0-9._-
func (c *OrganizationsApisCreateCall) Name(name string) *OrganizationsApisCreateCall {
	c.urlParams_.Set("name", name)
	return c
}

// Validate sets the optional parameter "validate": Ignored. All uploads
// are validated regardless of the value of this field. Maintained for
// compatibility with Apigee Edge API.
func (c *OrganizationsApisCreateCall) Validate(validate bool) *OrganizationsApisCreateCall {
	c.urlParams_.Set("validate", fmt.Sprint(validate))
	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 *OrganizationsApisCreateCall) Fields(s ...googleapi.Field) *OrganizationsApisCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApisCreateCall) Context(ctx context.Context) *OrganizationsApisCreateCall {
	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 *OrganizationsApisCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/apis")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.create" call.
// Exactly one of *GoogleCloudApigeeV1ApiProxyRevision or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ApiProxyRevision.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 *OrganizationsApisCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProxyRevision, 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 := &GoogleCloudApigeeV1ApiProxyRevision{
		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": "Creates an API proxy. The API proxy created will not be accessible at runtime until it is deployed to an environment. Create a new API proxy by setting the `name` query parameter to the name of the API proxy. Import an API proxy configuration bundle stored in zip format on your local machine to your organization by doing the following: * Set the `name` query parameter to the name of the API proxy. * Set the `action` query parameter to `import`. * Set the `Content-Type` header to `multipart/form-data`. * Pass as a file the name of API proxy configuration bundle stored in zip format on your local machine using the `file` form field. **Note**: To validate the API proxy configuration bundle only without importing it, set the `action` query parameter to `validate`. When importing an API proxy configuration bundle, if the API proxy does not exist, it will be created. If the API proxy exists, then a new revision is created. Invalid API proxy configurations are rejected, and a list of validation errors is returned to the client.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.apis.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Action to perform when importing an API proxy configuration bundle. Set this parameter to one of the following values: * `import` to import the API proxy configuration bundle. * `validate` to validate the API proxy configuration bundle without importing it.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Name of the API proxy. Restrict the characters used to: A-Za-z0-9._-",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization in the following format: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "validate": {
	//       "description": "Ignored. All uploads are validated regardless of the value of this field. Maintained for compatibility with Apigee Edge API.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+parent}/apis",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProxyRevision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.delete":

type OrganizationsApisDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an API proxy and all associated endpoints, policies,
// resources, and revisions. The API proxy must be undeployed before you
// can delete it.
func (r *OrganizationsApisService) Delete(name string) *OrganizationsApisDeleteCall {
	c := &OrganizationsApisDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApisDeleteCall) Fields(s ...googleapi.Field) *OrganizationsApisDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApisDeleteCall) Context(ctx context.Context) *OrganizationsApisDeleteCall {
	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 *OrganizationsApisDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.delete" call.
// Exactly one of *GoogleCloudApigeeV1ApiProxy or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1ApiProxy.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 *OrganizationsApisDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProxy, 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 := &GoogleCloudApigeeV1ApiProxy{
		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": "Deletes an API proxy and all associated endpoints, policies, resources, and revisions. The API proxy must be undeployed before you can delete it.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.apis.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the API proxy in the following format: `organizations/{org}/apis/{api}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.get":

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

// Get: Gets an API proxy including a list of existing revisions.
func (r *OrganizationsApisService) Get(name string) *OrganizationsApisGetCall {
	c := &OrganizationsApisGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApisGetCall) Fields(s ...googleapi.Field) *OrganizationsApisGetCall {
	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 *OrganizationsApisGetCall) IfNoneMatch(entityTag string) *OrganizationsApisGetCall {
	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 *OrganizationsApisGetCall) Context(ctx context.Context) *OrganizationsApisGetCall {
	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 *OrganizationsApisGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.get" call.
// Exactly one of *GoogleCloudApigeeV1ApiProxy or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1ApiProxy.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 *OrganizationsApisGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProxy, 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 := &GoogleCloudApigeeV1ApiProxy{
		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": "Gets an API proxy including a list of existing revisions.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apis.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the API proxy in the following format: `organizations/{org}/apis/{api}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProxy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.list":

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

// List: Lists the names of all API proxies in an organization. The
// names returned correspond to the names defined in the configuration
// files for each API proxy.
func (r *OrganizationsApisService) List(parent string) *OrganizationsApisListCall {
	c := &OrganizationsApisListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// IncludeMetaData sets the optional parameter "includeMetaData": Flag
// that specifies whether to include API proxy metadata in the response.
func (c *OrganizationsApisListCall) IncludeMetaData(includeMetaData bool) *OrganizationsApisListCall {
	c.urlParams_.Set("includeMetaData", fmt.Sprint(includeMetaData))
	return c
}

// IncludeRevisions sets the optional parameter "includeRevisions": Flag
// that specifies whether to include a list of revisions in the
// response.
func (c *OrganizationsApisListCall) IncludeRevisions(includeRevisions bool) *OrganizationsApisListCall {
	c.urlParams_.Set("includeRevisions", fmt.Sprint(includeRevisions))
	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 *OrganizationsApisListCall) Fields(s ...googleapi.Field) *OrganizationsApisListCall {
	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 *OrganizationsApisListCall) IfNoneMatch(entityTag string) *OrganizationsApisListCall {
	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 *OrganizationsApisListCall) Context(ctx context.Context) *OrganizationsApisListCall {
	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 *OrganizationsApisListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/apis")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.list" call.
// Exactly one of *GoogleCloudApigeeV1ListApiProxiesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListApiProxiesResponse.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 *OrganizationsApisListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListApiProxiesResponse, 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 := &GoogleCloudApigeeV1ListApiProxiesResponse{
		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": "Lists the names of all API proxies in an organization. The names returned correspond to the names defined in the configuration files for each API proxy.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apis.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "includeMetaData": {
	//       "description": "Flag that specifies whether to include API proxy metadata in the response.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "includeRevisions": {
	//       "description": "Flag that specifies whether to include a list of revisions in the response.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization in the following format: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/apis",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListApiProxiesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.deployments.list":

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

// List: Lists all deployments of an API proxy.
func (r *OrganizationsApisDeploymentsService) List(parent string) *OrganizationsApisDeploymentsListCall {
	c := &OrganizationsApisDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsApisDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsApisDeploymentsListCall {
	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 *OrganizationsApisDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsApisDeploymentsListCall {
	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 *OrganizationsApisDeploymentsListCall) Context(ctx context.Context) *OrganizationsApisDeploymentsListCall {
	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 *OrganizationsApisDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsApisDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of an API proxy.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apis.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the API proxy for which to return deployment information in the following format: `organizations/{org}/apis/{api}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.keyvaluemaps.create":

type OrganizationsApisKeyvaluemapsCreateCall struct {
	s                              *Service
	parent                         string
	googlecloudapigeev1keyvaluemap *GoogleCloudApigeeV1KeyValueMap
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Create: Creates a key value map in an api proxy.
func (r *OrganizationsApisKeyvaluemapsService) Create(parent string, googlecloudapigeev1keyvaluemap *GoogleCloudApigeeV1KeyValueMap) *OrganizationsApisKeyvaluemapsCreateCall {
	c := &OrganizationsApisKeyvaluemapsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1keyvaluemap = googlecloudapigeev1keyvaluemap
	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 *OrganizationsApisKeyvaluemapsCreateCall) Fields(s ...googleapi.Field) *OrganizationsApisKeyvaluemapsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApisKeyvaluemapsCreateCall) Context(ctx context.Context) *OrganizationsApisKeyvaluemapsCreateCall {
	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 *OrganizationsApisKeyvaluemapsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisKeyvaluemapsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1keyvaluemap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/keyvaluemaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.keyvaluemaps.create" call.
// Exactly one of *GoogleCloudApigeeV1KeyValueMap or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1KeyValueMap.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 *OrganizationsApisKeyvaluemapsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1KeyValueMap, 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 := &GoogleCloudApigeeV1KeyValueMap{
		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": "Creates a key value map in an api proxy.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}/keyvaluemaps",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.apis.keyvaluemaps.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the environment in which to create the key value map. Must be of the form `organizations/{organization}/apis/{api}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/keyvaluemaps",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.keyvaluemaps.delete":

type OrganizationsApisKeyvaluemapsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Delete a key value map in an api proxy.
func (r *OrganizationsApisKeyvaluemapsService) Delete(name string) *OrganizationsApisKeyvaluemapsDeleteCall {
	c := &OrganizationsApisKeyvaluemapsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApisKeyvaluemapsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsApisKeyvaluemapsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApisKeyvaluemapsDeleteCall) Context(ctx context.Context) *OrganizationsApisKeyvaluemapsDeleteCall {
	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 *OrganizationsApisKeyvaluemapsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisKeyvaluemapsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.keyvaluemaps.delete" call.
// Exactly one of *GoogleCloudApigeeV1KeyValueMap or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1KeyValueMap.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 *OrganizationsApisKeyvaluemapsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1KeyValueMap, 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 := &GoogleCloudApigeeV1KeyValueMap{
		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": "Delete a key value map in an api proxy.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}/keyvaluemaps/{keyvaluemapsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.apis.keyvaluemaps.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the key value map. Must be of the form `organizations/{organization}/apis/{api}/keyvaluemaps/{keyvaluemap}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+/keyvaluemaps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.revisions.delete":

type OrganizationsApisRevisionsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an API proxy revision and all policies, resources,
// endpoints, and revisions associated with it. The API proxy revision
// must be undeployed before you can delete it.
func (r *OrganizationsApisRevisionsService) Delete(name string) *OrganizationsApisRevisionsDeleteCall {
	c := &OrganizationsApisRevisionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsApisRevisionsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsApisRevisionsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApisRevisionsDeleteCall) Context(ctx context.Context) *OrganizationsApisRevisionsDeleteCall {
	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 *OrganizationsApisRevisionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisRevisionsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.revisions.delete" call.
// Exactly one of *GoogleCloudApigeeV1ApiProxyRevision or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ApiProxyRevision.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 *OrganizationsApisRevisionsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProxyRevision, 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 := &GoogleCloudApigeeV1ApiProxyRevision{
		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": "Deletes an API proxy revision and all policies, resources, endpoints, and revisions associated with it. The API proxy revision must be undeployed before you can delete it.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}/revisions/{revisionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.apis.revisions.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. API proxy revision in the following format: `organizations/{org}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProxyRevision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.revisions.get":

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

// Get: Gets an API proxy revision. To download the API proxy
// configuration bundle for the specified revision as a zip file, do the
// following: * Set the `format` query parameter to `bundle`. * Set the
// `Accept` header to `application/zip`. If you are using curl, specify
// `-o filename.zip` to save the output to a file; otherwise, it
// displays to `stdout`. Then, develop the API proxy configuration
// locally and upload the updated API proxy configuration revision, as
// described in [updateApiProxyRevision](updateApiProxyRevision).
func (r *OrganizationsApisRevisionsService) Get(name string) *OrganizationsApisRevisionsGetCall {
	c := &OrganizationsApisRevisionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Format sets the optional parameter "format": Format used when
// downloading the API proxy configuration revision. Set to `bundle` to
// download the API proxy configuration revision as a zip file.
func (c *OrganizationsApisRevisionsGetCall) Format(format string) *OrganizationsApisRevisionsGetCall {
	c.urlParams_.Set("format", format)
	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 *OrganizationsApisRevisionsGetCall) Fields(s ...googleapi.Field) *OrganizationsApisRevisionsGetCall {
	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 *OrganizationsApisRevisionsGetCall) IfNoneMatch(entityTag string) *OrganizationsApisRevisionsGetCall {
	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 *OrganizationsApisRevisionsGetCall) Context(ctx context.Context) *OrganizationsApisRevisionsGetCall {
	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 *OrganizationsApisRevisionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisRevisionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.revisions.get" call.
// Exactly one of *GoogleApiHttpBody or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleApiHttpBody.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 *OrganizationsApisRevisionsGetCall) Do(opts ...googleapi.CallOption) (*GoogleApiHttpBody, 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 := &GoogleApiHttpBody{
		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": "Gets an API proxy revision. To download the API proxy configuration bundle for the specified revision as a zip file, do the following: * Set the `format` query parameter to `bundle`. * Set the `Accept` header to `application/zip`. If you are using curl, specify `-o filename.zip` to save the output to a file; otherwise, it displays to `stdout`. Then, develop the API proxy configuration locally and upload the updated API proxy configuration revision, as described in [updateApiProxyRevision](updateApiProxyRevision).",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}/revisions/{revisionsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apis.revisions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "format": {
	//       "description": "Format used when downloading the API proxy configuration revision. Set to `bundle` to download the API proxy configuration revision as a zip file.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. API proxy revision in the following format: `organizations/{org}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.revisions.updateApiProxyRevision":

type OrganizationsApisRevisionsUpdateApiProxyRevisionCall struct {
	s                 *Service
	name              string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// UpdateApiProxyRevision: Updates an existing API proxy revision by
// uploading the API proxy configuration bundle as a zip file from your
// local machine. You can update only API proxy revisions that have
// never been deployed. After deployment, an API proxy revision becomes
// immutable, even if it is undeployed. Set the `Content-Type` header to
// either `multipart/form-data` or `application/octet-stream`.
func (r *OrganizationsApisRevisionsService) UpdateApiProxyRevision(name string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsApisRevisionsUpdateApiProxyRevisionCall {
	c := &OrganizationsApisRevisionsUpdateApiProxyRevisionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googleapihttpbody = googleapihttpbody
	return c
}

// Validate sets the optional parameter "validate": Ignored. All uploads
// are validated regardless of the value of this field. Maintained for
// compatibility with Apigee Edge API.
func (c *OrganizationsApisRevisionsUpdateApiProxyRevisionCall) Validate(validate bool) *OrganizationsApisRevisionsUpdateApiProxyRevisionCall {
	c.urlParams_.Set("validate", fmt.Sprint(validate))
	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 *OrganizationsApisRevisionsUpdateApiProxyRevisionCall) Fields(s ...googleapi.Field) *OrganizationsApisRevisionsUpdateApiProxyRevisionCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsApisRevisionsUpdateApiProxyRevisionCall) Context(ctx context.Context) *OrganizationsApisRevisionsUpdateApiProxyRevisionCall {
	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 *OrganizationsApisRevisionsUpdateApiProxyRevisionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisRevisionsUpdateApiProxyRevisionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.revisions.updateApiProxyRevision" call.
// Exactly one of *GoogleCloudApigeeV1ApiProxyRevision or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ApiProxyRevision.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 *OrganizationsApisRevisionsUpdateApiProxyRevisionCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ApiProxyRevision, 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 := &GoogleCloudApigeeV1ApiProxyRevision{
		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": "Updates an existing API proxy revision by uploading the API proxy configuration bundle as a zip file from your local machine. You can update only API proxy revisions that have never been deployed. After deployment, an API proxy revision becomes immutable, even if it is undeployed. Set the `Content-Type` header to either `multipart/form-data` or `application/octet-stream`.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}/revisions/{revisionsId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.apis.revisions.updateApiProxyRevision",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. API proxy revision to update in the following format: `organizations/{org}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "validate": {
	//       "description": "Ignored. All uploads are validated regardless of the value of this field. Maintained for compatibility with Apigee Edge API.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ApiProxyRevision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apis.revisions.deployments.list":

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

// List: Lists all deployments of an API proxy revision.
func (r *OrganizationsApisRevisionsDeploymentsService) List(parent string) *OrganizationsApisRevisionsDeploymentsListCall {
	c := &OrganizationsApisRevisionsDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsApisRevisionsDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsApisRevisionsDeploymentsListCall {
	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 *OrganizationsApisRevisionsDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsApisRevisionsDeploymentsListCall {
	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 *OrganizationsApisRevisionsDeploymentsListCall) Context(ctx context.Context) *OrganizationsApisRevisionsDeploymentsListCall {
	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 *OrganizationsApisRevisionsDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsApisRevisionsDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apis.revisions.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsApisRevisionsDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of an API proxy revision.",
	//   "flatPath": "v1/organizations/{organizationsId}/apis/{apisId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apis.revisions.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the API proxy revision for which to return deployment information in the following format: `organizations/{org}/apis/{api}/revisions/{rev}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apps.get":

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

// Get: Gets the app profile for the specified app ID.
func (r *OrganizationsAppsService) Get(name string) *OrganizationsAppsGetCall {
	c := &OrganizationsAppsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsAppsGetCall) Fields(s ...googleapi.Field) *OrganizationsAppsGetCall {
	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 *OrganizationsAppsGetCall) IfNoneMatch(entityTag string) *OrganizationsAppsGetCall {
	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 *OrganizationsAppsGetCall) Context(ctx context.Context) *OrganizationsAppsGetCall {
	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 *OrganizationsAppsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAppsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apps.get" call.
// Exactly one of *GoogleCloudApigeeV1App or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1App.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 *OrganizationsAppsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1App, 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 := &GoogleCloudApigeeV1App{
		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": "Gets the app profile for the specified app ID.",
	//   "flatPath": "v1/organizations/{organizationsId}/apps/{appsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apps.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. App ID in the following format: `organizations/{org}/apps/{app}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1App"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.apps.list":

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

// List: Lists IDs of apps within an organization that have the
// specified app status (approved or revoked) or are of the specified
// app type (developer or company).
func (r *OrganizationsAppsService) List(parent string) *OrganizationsAppsListCall {
	c := &OrganizationsAppsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// ApiProduct sets the optional parameter "apiProduct": API product.
func (c *OrganizationsAppsListCall) ApiProduct(apiProduct string) *OrganizationsAppsListCall {
	c.urlParams_.Set("apiProduct", apiProduct)
	return c
}

// Apptype sets the optional parameter "apptype": Filter by the type of
// the app. Valid values are `company` or `developer`. Defaults to
// `developer`.
func (c *OrganizationsAppsListCall) Apptype(apptype string) *OrganizationsAppsListCall {
	c.urlParams_.Set("apptype", apptype)
	return c
}

// Expand sets the optional parameter "expand": Flag that specifies
// whether to return an expanded list of apps for the organization.
// Defaults to `false`.
func (c *OrganizationsAppsListCall) Expand(expand bool) *OrganizationsAppsListCall {
	c.urlParams_.Set("expand", fmt.Sprint(expand))
	return c
}

// Ids sets the optional parameter "ids": Comma-separated list of app
// IDs on which to filter.
func (c *OrganizationsAppsListCall) Ids(ids string) *OrganizationsAppsListCall {
	c.urlParams_.Set("ids", ids)
	return c
}

// IncludeCred sets the optional parameter "includeCred": Flag that
// specifies whether to include credentials in the response.
func (c *OrganizationsAppsListCall) IncludeCred(includeCred bool) *OrganizationsAppsListCall {
	c.urlParams_.Set("includeCred", fmt.Sprint(includeCred))
	return c
}

// KeyStatus sets the optional parameter "keyStatus": Key status of the
// app. Valid values include `approved` or `revoked`. Defaults to
// `approved`.
func (c *OrganizationsAppsListCall) KeyStatus(keyStatus string) *OrganizationsAppsListCall {
	c.urlParams_.Set("keyStatus", keyStatus)
	return c
}

// Rows sets the optional parameter "rows": Maximum number of app IDs to
// return. Defaults to 10000.
func (c *OrganizationsAppsListCall) Rows(rows int64) *OrganizationsAppsListCall {
	c.urlParams_.Set("rows", fmt.Sprint(rows))
	return c
}

// StartKey sets the optional parameter "startKey": Returns the list of
// apps starting from the specified app ID.
func (c *OrganizationsAppsListCall) StartKey(startKey string) *OrganizationsAppsListCall {
	c.urlParams_.Set("startKey", startKey)
	return c
}

// Status sets the optional parameter "status": Filter by the status of
// the app. Valid values are `approved` or `revoked`. Defaults to
// `approved`.
func (c *OrganizationsAppsListCall) Status(status string) *OrganizationsAppsListCall {
	c.urlParams_.Set("status", status)
	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 *OrganizationsAppsListCall) Fields(s ...googleapi.Field) *OrganizationsAppsListCall {
	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 *OrganizationsAppsListCall) IfNoneMatch(entityTag string) *OrganizationsAppsListCall {
	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 *OrganizationsAppsListCall) Context(ctx context.Context) *OrganizationsAppsListCall {
	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 *OrganizationsAppsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsAppsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/apps")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.apps.list" call.
// Exactly one of *GoogleCloudApigeeV1ListAppsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ListAppsResponse.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 *OrganizationsAppsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListAppsResponse, 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 := &GoogleCloudApigeeV1ListAppsResponse{
		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": "Lists IDs of apps within an organization that have the specified app status (approved or revoked) or are of the specified app type (developer or company).",
	//   "flatPath": "v1/organizations/{organizationsId}/apps",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.apps.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "apiProduct": {
	//       "description": "API product.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "apptype": {
	//       "description": "Optional. Filter by the type of the app. Valid values are `company` or `developer`. Defaults to `developer`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "expand": {
	//       "description": "Optional. Flag that specifies whether to return an expanded list of apps for the organization. Defaults to `false`.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Optional. Comma-separated list of app IDs on which to filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeCred": {
	//       "description": "Optional. Flag that specifies whether to include credentials in the response.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "keyStatus": {
	//       "description": "Optional. Key status of the app. Valid values include `approved` or `revoked`. Defaults to `approved`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Resource path of the parent in the following format: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "rows": {
	//       "description": "Optional. Maximum number of app IDs to return. Defaults to 10000.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "startKey": {
	//       "description": "Returns the list of apps starting from the specified app ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "status": {
	//       "description": "Optional. Filter by the status of the app. Valid values are `approved` or `revoked`. Defaults to `approved`.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/apps",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListAppsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.deployments.list":

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

// List: Lists all deployments of API proxies or shared flows.
func (r *OrganizationsDeploymentsService) List(parent string) *OrganizationsDeploymentsListCall {
	c := &OrganizationsDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// SharedFlows sets the optional parameter "sharedFlows": Flag that
// specifies whether to return shared flow or API proxy deployments. Set
// to `true` to return shared flow deployments; set to `false` to return
// API proxy deployments. Defaults to `false`.
func (c *OrganizationsDeploymentsListCall) SharedFlows(sharedFlows bool) *OrganizationsDeploymentsListCall {
	c.urlParams_.Set("sharedFlows", fmt.Sprint(sharedFlows))
	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 *OrganizationsDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsDeploymentsListCall {
	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 *OrganizationsDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsDeploymentsListCall {
	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 *OrganizationsDeploymentsListCall) Context(ctx context.Context) *OrganizationsDeploymentsListCall {
	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 *OrganizationsDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of API proxies or shared flows.",
	//   "flatPath": "v1/organizations/{organizationsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the organization for which to return deployment information in the following format: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sharedFlows": {
	//       "description": "Optional. Flag that specifies whether to return shared flow or API proxy deployments. Set to `true` to return shared flow deployments; set to `false` to return API proxy deployments. Defaults to `false`.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.attributes":

type OrganizationsDevelopersAttributesCall struct {
	s                             *Service
	parent                        string
	googlecloudapigeev1attributes *GoogleCloudApigeeV1Attributes
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Attributes: Updates developer attributes. This API replaces the
// existing attributes with those specified in the request. Add new
// attributes, and include or exclude any existing attributes that you
// want to retain or remove, respectively. The custom attribute limit is
// 18. **Note**: OAuth access tokens and Key Management Service (KMS)
// entities (apps, developers, and API products) are cached for 180
// seconds (default). Any custom attributes associated with these
// entities are cached for at least 180 seconds after the entity is
// accessed at runtime. Therefore, an `ExpiresIn` element on the OAuthV2
// policy won't be able to expire an access token in less than 180
// seconds.
func (r *OrganizationsDevelopersService) Attributes(parent string, googlecloudapigeev1attributes *GoogleCloudApigeeV1Attributes) *OrganizationsDevelopersAttributesCall {
	c := &OrganizationsDevelopersAttributesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1attributes = googlecloudapigeev1attributes
	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 *OrganizationsDevelopersAttributesCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAttributesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAttributesCall) Context(ctx context.Context) *OrganizationsDevelopersAttributesCall {
	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 *OrganizationsDevelopersAttributesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAttributesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1attributes)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/attributes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.attributes" call.
// Exactly one of *GoogleCloudApigeeV1Attributes or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attributes.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 *OrganizationsDevelopersAttributesCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attributes, 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 := &GoogleCloudApigeeV1Attributes{
		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": "Updates developer attributes. This API replaces the existing attributes with those specified in the request. Add new attributes, and include or exclude any existing attributes that you want to retain or remove, respectively. The custom attribute limit is 18. **Note**: OAuth access tokens and Key Management Service (KMS) entities (apps, developers, and API products) are cached for 180 seconds (default). Any custom attributes associated with these entities are cached for at least 180 seconds after the entity is accessed at runtime. Therefore, an `ExpiresIn` element on the OAuthV2 policy won't be able to expire an access token in less than 180 seconds.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/attributes",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.attributes",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Email address of the developer for which attributes are being updated in the following format: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attributes",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.create":

type OrganizationsDevelopersCreateCall struct {
	s                            *Service
	parent                       string
	googlecloudapigeev1developer *GoogleCloudApigeeV1Developer
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Create: Creates a developer. Once created, the developer can register
// an app and obtain an API key. At creation time, a developer is set as
// `active`. To change the developer status, use the SetDeveloperStatus
// API.
func (r *OrganizationsDevelopersService) Create(parent string, googlecloudapigeev1developer *GoogleCloudApigeeV1Developer) *OrganizationsDevelopersCreateCall {
	c := &OrganizationsDevelopersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1developer = googlecloudapigeev1developer
	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 *OrganizationsDevelopersCreateCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersCreateCall) Context(ctx context.Context) *OrganizationsDevelopersCreateCall {
	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 *OrganizationsDevelopersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developer)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/developers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.create" call.
// Exactly one of *GoogleCloudApigeeV1Developer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Developer.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 *OrganizationsDevelopersCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Developer, 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 := &GoogleCloudApigeeV1Developer{
		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": "Creates a developer. Once created, the developer can register an app and obtain an API key. At creation time, a developer is set as `active`. To change the developer status, use the SetDeveloperStatus API.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the Apigee organization in which the developer is created. Use the following structure in your request: `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/developers",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Developer"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Developer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.delete":

type OrganizationsDevelopersDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a developer. All apps and API keys associated with
// the developer are also removed. **Warning**: This API will
// permanently delete the developer and related artifacts. To avoid
// permanently deleting developers and their artifacts, set the
// developer status to `inactive` using the SetDeveloperStatus API.
// **Note**: The delete operation is asynchronous. The developer app is
// deleted immediately, but its associated resources, such as apps and
// API keys, may take anywhere from a few seconds to a few minutes to be
// deleted.
func (r *OrganizationsDevelopersService) Delete(name string) *OrganizationsDevelopersDeleteCall {
	c := &OrganizationsDevelopersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersDeleteCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersDeleteCall) Context(ctx context.Context) *OrganizationsDevelopersDeleteCall {
	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 *OrganizationsDevelopersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.delete" call.
// Exactly one of *GoogleCloudApigeeV1Developer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Developer.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 *OrganizationsDevelopersDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Developer, 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 := &GoogleCloudApigeeV1Developer{
		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": "Deletes a developer. All apps and API keys associated with the developer are also removed. **Warning**: This API will permanently delete the developer and related artifacts. To avoid permanently deleting developers and their artifacts, set the developer status to `inactive` using the SetDeveloperStatus API. **Note**: The delete operation is asynchronous. The developer app is deleted immediately, but its associated resources, such as apps and API keys, may take anywhere from a few seconds to a few minutes to be deleted.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.developers.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Email address of the developer. Use the following structure in your request: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Developer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.get":

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

// Get: Returns the developer details, including the developer's name,
// email address, apps, and other information. **Note**: The response
// includes only the first 100 developer apps.
func (r *OrganizationsDevelopersService) Get(name string) *OrganizationsDevelopersGetCall {
	c := &OrganizationsDevelopersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Action sets the optional parameter "action": Status of the developer.
// Valid values are `active` or `inactive`.
func (c *OrganizationsDevelopersGetCall) Action(action string) *OrganizationsDevelopersGetCall {
	c.urlParams_.Set("action", action)
	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 *OrganizationsDevelopersGetCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersGetCall {
	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 *OrganizationsDevelopersGetCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersGetCall {
	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 *OrganizationsDevelopersGetCall) Context(ctx context.Context) *OrganizationsDevelopersGetCall {
	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 *OrganizationsDevelopersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.get" call.
// Exactly one of *GoogleCloudApigeeV1Developer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Developer.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 *OrganizationsDevelopersGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Developer, 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 := &GoogleCloudApigeeV1Developer{
		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": "Returns the developer details, including the developer's name, email address, apps, and other information. **Note**: The response includes only the first 100 developer apps.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Status of the developer. Valid values are `active` or `inactive`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Email address of the developer. Use the following structure in your request: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Developer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.list":

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

// List: Lists all developers in an organization by email address. By
// default, the response does not include company developers. Set the
// `includeCompany` query parameter to `true` to include company
// developers. **Note**: A maximum of 1000 developers are returned in
// the response. You paginate the list of developers returned using the
// `startKey` and `count` query parameters.
func (r *OrganizationsDevelopersService) List(parent string) *OrganizationsDevelopersListCall {
	c := &OrganizationsDevelopersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Count sets the optional parameter "count": Number of developers to
// return in the API call. Use with the `startKey` parameter to provide
// more targeted filtering. The limit is 1000.
func (c *OrganizationsDevelopersListCall) Count(count int64) *OrganizationsDevelopersListCall {
	c.urlParams_.Set("count", fmt.Sprint(count))
	return c
}

// Expand sets the optional parameter "expand": Specifies whether to
// expand the results. Set to `true` to expand the results. This query
// parameter is not valid if you use the `count` or `startKey` query
// parameters.
func (c *OrganizationsDevelopersListCall) Expand(expand bool) *OrganizationsDevelopersListCall {
	c.urlParams_.Set("expand", fmt.Sprint(expand))
	return c
}

// Ids sets the optional parameter "ids": List of IDs to include,
// separated by commas.
func (c *OrganizationsDevelopersListCall) Ids(ids string) *OrganizationsDevelopersListCall {
	c.urlParams_.Set("ids", ids)
	return c
}

// IncludeCompany sets the optional parameter "includeCompany": Flag
// that specifies whether to include company details in the response.
func (c *OrganizationsDevelopersListCall) IncludeCompany(includeCompany bool) *OrganizationsDevelopersListCall {
	c.urlParams_.Set("includeCompany", fmt.Sprint(includeCompany))
	return c
}

// StartKey sets the optional parameter "startKey": **Note**: Must be
// used in conjunction with the `count` parameter. Email address of the
// developer from which to start displaying the list of developers. For
// example, if the an unfiltered list returns: ``` westley@example.com
// fezzik@example.com buttercup@example.com ``` and your `startKey` is
// `fezzik@example.com`, the list returned will be ```
// fezzik@example.com buttercup@example.com ```
func (c *OrganizationsDevelopersListCall) StartKey(startKey string) *OrganizationsDevelopersListCall {
	c.urlParams_.Set("startKey", startKey)
	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 *OrganizationsDevelopersListCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersListCall {
	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 *OrganizationsDevelopersListCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersListCall {
	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 *OrganizationsDevelopersListCall) Context(ctx context.Context) *OrganizationsDevelopersListCall {
	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 *OrganizationsDevelopersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/developers")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.list" call.
// Exactly one of *GoogleCloudApigeeV1ListOfDevelopersResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListOfDevelopersResponse.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 *OrganizationsDevelopersListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListOfDevelopersResponse, 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 := &GoogleCloudApigeeV1ListOfDevelopersResponse{
		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": "Lists all developers in an organization by email address. By default, the response does not include company developers. Set the `includeCompany` query parameter to `true` to include company developers. **Note**: A maximum of 1000 developers are returned in the response. You paginate the list of developers returned using the `startKey` and `count` query parameters.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "count": {
	//       "description": "Optional. Number of developers to return in the API call. Use with the `startKey` parameter to provide more targeted filtering. The limit is 1000.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "expand": {
	//       "description": "Specifies whether to expand the results. Set to `true` to expand the results. This query parameter is not valid if you use the `count` or `startKey` query parameters.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Optional. List of IDs to include, separated by commas.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeCompany": {
	//       "description": "Flag that specifies whether to include company details in the response.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the Apigee organization. Use the following structure in your request: `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "startKey": {
	//       "description": "**Note**: Must be used in conjunction with the `count` parameter. Email address of the developer from which to start displaying the list of developers. For example, if the an unfiltered list returns: ``` westley@example.com fezzik@example.com buttercup@example.com ``` and your `startKey` is `fezzik@example.com`, the list returned will be ``` fezzik@example.com buttercup@example.com ```",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/developers",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListOfDevelopersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.setDeveloperStatus":

type OrganizationsDevelopersSetDeveloperStatusCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// SetDeveloperStatus: Sets the status of a developer. Valid values are
// `active` or `inactive`. A developer is `active` by default. If you
// set a developer's status to `inactive`, the API keys assigned to the
// developer apps are no longer valid even though the API keys are set
// to `approved`. Inactive developers can still sign in to the developer
// portal and create apps; however, any new API keys generated during
// app creation won't work. If successful, the API call returns the
// following HTTP status code: `204 No Content`
func (r *OrganizationsDevelopersService) SetDeveloperStatus(name string) *OrganizationsDevelopersSetDeveloperStatusCall {
	c := &OrganizationsDevelopersSetDeveloperStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Action sets the optional parameter "action": Status of the developer.
// Valid values are `active` and `inactive`.
func (c *OrganizationsDevelopersSetDeveloperStatusCall) Action(action string) *OrganizationsDevelopersSetDeveloperStatusCall {
	c.urlParams_.Set("action", action)
	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 *OrganizationsDevelopersSetDeveloperStatusCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersSetDeveloperStatusCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersSetDeveloperStatusCall) Context(ctx context.Context) *OrganizationsDevelopersSetDeveloperStatusCall {
	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 *OrganizationsDevelopersSetDeveloperStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersSetDeveloperStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.setDeveloperStatus" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsDevelopersSetDeveloperStatusCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Sets the status of a developer. Valid values are `active` or `inactive`. A developer is `active` by default. If you set a developer's status to `inactive`, the API keys assigned to the developer apps are no longer valid even though the API keys are set to `approved`. Inactive developers can still sign in to the developer portal and create apps; however, any new API keys generated during app creation won't work. If successful, the API call returns the following HTTP status code: `204 No Content`",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.setDeveloperStatus",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Status of the developer. Valid values are `active` and `inactive`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Email address of the developer. Use the following structure in your request: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.update":

type OrganizationsDevelopersUpdateCall struct {
	s                            *Service
	name                         string
	googlecloudapigeev1developer *GoogleCloudApigeeV1Developer
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Update: Updates a developer. This API replaces the existing developer
// details with those specified in the request. Include or exclude any
// existing details that you want to retain or delete, respectively. The
// custom attribute limit is 18. **Note**: OAuth access tokens and Key
// Management Service (KMS) entities (apps, developers, and API
// products) are cached for 180 seconds (current default). Any custom
// attributes associated with these entities are cached for at least 180
// seconds after the entity is accessed at runtime. Therefore, an
// `ExpiresIn` element on the OAuthV2 policy won't be able to expire an
// access token in less than 180 seconds.
func (r *OrganizationsDevelopersService) Update(name string, googlecloudapigeev1developer *GoogleCloudApigeeV1Developer) *OrganizationsDevelopersUpdateCall {
	c := &OrganizationsDevelopersUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1developer = googlecloudapigeev1developer
	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 *OrganizationsDevelopersUpdateCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersUpdateCall) Context(ctx context.Context) *OrganizationsDevelopersUpdateCall {
	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 *OrganizationsDevelopersUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developer)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.update" call.
// Exactly one of *GoogleCloudApigeeV1Developer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Developer.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 *OrganizationsDevelopersUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Developer, 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 := &GoogleCloudApigeeV1Developer{
		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": "Updates a developer. This API replaces the existing developer details with those specified in the request. Include or exclude any existing details that you want to retain or delete, respectively. The custom attribute limit is 18. **Note**: OAuth access tokens and Key Management Service (KMS) entities (apps, developers, and API products) are cached for 180 seconds (current default). Any custom attributes associated with these entities are cached for at least 180 seconds after the entity is accessed at runtime. Therefore, an `ExpiresIn` element on the OAuthV2 policy won't be able to expire an access token in less than 180 seconds.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.developers.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Email address of the developer. Use the following structure in your request: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Developer"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Developer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.attributes":

type OrganizationsDevelopersAppsAttributesCall struct {
	s                             *Service
	name                          string
	googlecloudapigeev1attributes *GoogleCloudApigeeV1Attributes
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Attributes: Updates attributes for a developer app. This API replaces
// the current attributes with those specified in the request.
func (r *OrganizationsDevelopersAppsService) Attributes(name string, googlecloudapigeev1attributes *GoogleCloudApigeeV1Attributes) *OrganizationsDevelopersAppsAttributesCall {
	c := &OrganizationsDevelopersAppsAttributesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1attributes = googlecloudapigeev1attributes
	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 *OrganizationsDevelopersAppsAttributesCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsAttributesCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsAttributesCall) Context(ctx context.Context) *OrganizationsDevelopersAppsAttributesCall {
	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 *OrganizationsDevelopersAppsAttributesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsAttributesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1attributes)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/attributes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.attributes" call.
// Exactly one of *GoogleCloudApigeeV1Attributes or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attributes.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 *OrganizationsDevelopersAppsAttributesCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attributes, 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 := &GoogleCloudApigeeV1Attributes{
		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": "Updates attributes for a developer app. This API replaces the current attributes with those specified in the request.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/attributes",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.attributes",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer app. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/attributes",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.create":

type OrganizationsDevelopersAppsCreateCall struct {
	s                               *Service
	parent                          string
	googlecloudapigeev1developerapp *GoogleCloudApigeeV1DeveloperApp
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Create: Creates an app associated with a developer. This API
// associates the developer app with the specified API product and
// auto-generates an API key for the app to use in calls to API proxies
// inside that API product. The `name` is the unique ID of the app that
// you can use in API calls. The `DisplayName` (set as an attribute)
// appears in the UI. If you don't set the `DisplayName` attribute, the
// `name` appears in the UI.
func (r *OrganizationsDevelopersAppsService) Create(parent string, googlecloudapigeev1developerapp *GoogleCloudApigeeV1DeveloperApp) *OrganizationsDevelopersAppsCreateCall {
	c := &OrganizationsDevelopersAppsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1developerapp = googlecloudapigeev1developerapp
	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 *OrganizationsDevelopersAppsCreateCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsCreateCall) Context(ctx context.Context) *OrganizationsDevelopersAppsCreateCall {
	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 *OrganizationsDevelopersAppsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developerapp)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/apps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.create" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperApp or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperApp.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 *OrganizationsDevelopersAppsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperApp, 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 := &GoogleCloudApigeeV1DeveloperApp{
		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": "Creates an app associated with a developer. This API associates the developer app with the specified API product and auto-generates an API key for the app to use in calls to API proxies inside that API product. The `name` is the unique ID of the app that you can use in API calls. The `DisplayName` (set as an attribute) appears in the UI. If you don't set the `DisplayName` attribute, the `name` appears in the UI.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the developer. Use the following structure in your request: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/apps",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.delete":

type OrganizationsDevelopersAppsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a developer app. **Note**: The delete operation is
// asynchronous. The developer app is deleted immediately, but its
// associated resources, such as app keys or access tokens, may take
// anywhere from a few seconds to a few minutes to be deleted.
func (r *OrganizationsDevelopersAppsService) Delete(name string) *OrganizationsDevelopersAppsDeleteCall {
	c := &OrganizationsDevelopersAppsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAppsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsDeleteCall) Context(ctx context.Context) *OrganizationsDevelopersAppsDeleteCall {
	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 *OrganizationsDevelopersAppsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.delete" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperApp or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperApp.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 *OrganizationsDevelopersAppsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperApp, 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 := &GoogleCloudApigeeV1DeveloperApp{
		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": "Deletes a developer app. **Note**: The delete operation is asynchronous. The developer app is deleted immediately, but its associated resources, such as app keys or access tokens, may take anywhere from a few seconds to a few minutes to be deleted.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.developers.apps.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer app. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.generateKeyPairOrUpdateDeveloperAppStatus":

type OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall struct {
	s                               *Service
	name                            string
	googlecloudapigeev1developerapp *GoogleCloudApigeeV1DeveloperApp
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// GenerateKeyPairOrUpdateDeveloperAppStatus: Manages access to a
// developer app by enabling you to: * Approve or revoke a developer app
// * Generate a new consumer key and secret for a developer app To
// approve or revoke a developer app, set the `action` query parameter
// to `approved` or `revoked`, respectively, and the `Content-Type`
// header to `application/octet-stream`. If a developer app is revoked,
// none of its API keys are valid for API calls even though the keys are
// still `approved`. If successful, the API call returns the following
// HTTP status code: `204 No Content` To generate a new consumer key and
// secret for a developer app, pass the new key/secret details. Rather
// than replace an existing key, this API generates a new key. In this
// case, multiple key pairs may be associated with a single developer
// app. Each key pair has an independent status (`approved` or
// `revoked`) and expiration time. Any approved, non-expired key can be
// used in an API call. For example, if you're using API key rotation,
// you can generate new keys with expiration times that overlap keys
// that are going to expire. You might also generate a new consumer
// key/secret if the security of the original key/secret is compromised.
// The `keyExpiresIn` property defines the expiration time for the API
// key in milliseconds. If you don't set this property or set it to
// `-1`, the API key never expires. **Notes**: * When generating a new
// key/secret, this API replaces the existing attributes, notes, and
// callback URLs with those specified in the request. Include or exclude
// any existing information that you want to retain or delete,
// respectively. * To migrate existing consumer keys and secrets to
// hybrid from another system, see the CreateDeveloperAppKey API.
func (r *OrganizationsDevelopersAppsService) GenerateKeyPairOrUpdateDeveloperAppStatus(name string, googlecloudapigeev1developerapp *GoogleCloudApigeeV1DeveloperApp) *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall {
	c := &OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1developerapp = googlecloudapigeev1developerapp
	return c
}

// Action sets the optional parameter "action": Action. Valid values are
// `approve` or `revoke`.
func (c *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall) Action(action string) *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall {
	c.urlParams_.Set("action", action)
	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 *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall) Context(ctx context.Context) *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall {
	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 *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developerapp)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.generateKeyPairOrUpdateDeveloperAppStatus" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperApp or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperApp.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 *OrganizationsDevelopersAppsGenerateKeyPairOrUpdateDeveloperAppStatusCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperApp, 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 := &GoogleCloudApigeeV1DeveloperApp{
		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": "Manages access to a developer app by enabling you to: * Approve or revoke a developer app * Generate a new consumer key and secret for a developer app To approve or revoke a developer app, set the `action` query parameter to `approved` or `revoked`, respectively, and the `Content-Type` header to `application/octet-stream`. If a developer app is revoked, none of its API keys are valid for API calls even though the keys are still `approved`. If successful, the API call returns the following HTTP status code: `204 No Content` To generate a new consumer key and secret for a developer app, pass the new key/secret details. Rather than replace an existing key, this API generates a new key. In this case, multiple key pairs may be associated with a single developer app. Each key pair has an independent status (`approved` or `revoked`) and expiration time. Any approved, non-expired key can be used in an API call. For example, if you're using API key rotation, you can generate new keys with expiration times that overlap keys that are going to expire. You might also generate a new consumer key/secret if the security of the original key/secret is compromised. The `keyExpiresIn` property defines the expiration time for the API key in milliseconds. If you don't set this property or set it to `-1`, the API key never expires. **Notes**: * When generating a new key/secret, this API replaces the existing attributes, notes, and callback URLs with those specified in the request. Include or exclude any existing information that you want to retain or delete, respectively. * To migrate existing consumer keys and secrets to hybrid from another system, see the CreateDeveloperAppKey API.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.generateKeyPairOrUpdateDeveloperAppStatus",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Action. Valid values are `approve` or `revoke`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Name of the developer app. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.get":

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

// Get: Returns the details for a developer app.
func (r *OrganizationsDevelopersAppsService) Get(name string) *OrganizationsDevelopersAppsGetCall {
	c := &OrganizationsDevelopersAppsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Entity sets the optional parameter "entity": **Note**: Must be used
// in conjunction with the `query` parameter. Set to `apiresources` to
// return the number of API resources that have been approved for access
// by a developer app in the specified Apigee organization.
func (c *OrganizationsDevelopersAppsGetCall) Entity(entity string) *OrganizationsDevelopersAppsGetCall {
	c.urlParams_.Set("entity", entity)
	return c
}

// Query sets the optional parameter "query": **Note**: Must be used in
// conjunction with the `entity` parameter. Set to `count` to return the
// number of API resources that have been approved for access by a
// developer app in the specified Apigee organization.
func (c *OrganizationsDevelopersAppsGetCall) Query(query string) *OrganizationsDevelopersAppsGetCall {
	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 *OrganizationsDevelopersAppsGetCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsGetCall {
	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 *OrganizationsDevelopersAppsGetCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersAppsGetCall {
	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 *OrganizationsDevelopersAppsGetCall) Context(ctx context.Context) *OrganizationsDevelopersAppsGetCall {
	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 *OrganizationsDevelopersAppsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.get" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperApp or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperApp.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 *OrganizationsDevelopersAppsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperApp, 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 := &GoogleCloudApigeeV1DeveloperApp{
		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": "Returns the details for a developer app.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.apps.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "entity": {
	//       "description": "**Note**: Must be used in conjunction with the `query` parameter. Set to `apiresources` to return the number of API resources that have been approved for access by a developer app in the specified Apigee organization.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Name of the developer app. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "**Note**: Must be used in conjunction with the `entity` parameter. Set to `count` to return the number of API resources that have been approved for access by a developer app in the specified Apigee organization.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.list":

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

// List: Lists all apps created by a developer in an Apigee
// organization. Optionally, you can request an expanded view of the
// developer apps. A maximum of 100 developer apps are returned per API
// call. You can paginate the list of deveoper apps returned using the
// `startKey` and `count` query parameters.
func (r *OrganizationsDevelopersAppsService) List(parent string) *OrganizationsDevelopersAppsListCall {
	c := &OrganizationsDevelopersAppsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Count sets the optional parameter "count": Number of developer apps
// to return in the API call. Use with the `startKey` parameter to
// provide more targeted filtering. The limit is 1000.
func (c *OrganizationsDevelopersAppsListCall) Count(count int64) *OrganizationsDevelopersAppsListCall {
	c.urlParams_.Set("count", fmt.Sprint(count))
	return c
}

// Expand sets the optional parameter "expand": Specifies whether to
// expand the results. Set to `true` to expand the results. This query
// parameter is not valid if you use the `count` or `startKey` query
// parameters.
func (c *OrganizationsDevelopersAppsListCall) Expand(expand bool) *OrganizationsDevelopersAppsListCall {
	c.urlParams_.Set("expand", fmt.Sprint(expand))
	return c
}

// ShallowExpand sets the optional parameter "shallowExpand": Specifies
// whether to expand the results in shallow mode. Set to `true` to
// expand the results in shallow mode.
func (c *OrganizationsDevelopersAppsListCall) ShallowExpand(shallowExpand bool) *OrganizationsDevelopersAppsListCall {
	c.urlParams_.Set("shallowExpand", fmt.Sprint(shallowExpand))
	return c
}

// StartKey sets the optional parameter "startKey": **Note**: Must be
// used in conjunction with the `count` parameter. Name of the developer
// app from which to start displaying the list of developer apps. For
// example, if you're returning 50 developer apps at a time (using the
// `count` query parameter), you can view developer apps 50-99 by
// entering the name of the 50th developer app. The developer app name
// is case sensitive.
func (c *OrganizationsDevelopersAppsListCall) StartKey(startKey string) *OrganizationsDevelopersAppsListCall {
	c.urlParams_.Set("startKey", startKey)
	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 *OrganizationsDevelopersAppsListCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsListCall {
	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 *OrganizationsDevelopersAppsListCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersAppsListCall {
	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 *OrganizationsDevelopersAppsListCall) Context(ctx context.Context) *OrganizationsDevelopersAppsListCall {
	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 *OrganizationsDevelopersAppsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/apps")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeveloperAppsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeveloperAppsResponse.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 *OrganizationsDevelopersAppsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeveloperAppsResponse, 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 := &GoogleCloudApigeeV1ListDeveloperAppsResponse{
		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": "Lists all apps created by a developer in an Apigee organization. Optionally, you can request an expanded view of the developer apps. A maximum of 100 developer apps are returned per API call. You can paginate the list of deveoper apps returned using the `startKey` and `count` query parameters.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.apps.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "count": {
	//       "description": "Number of developer apps to return in the API call. Use with the `startKey` parameter to provide more targeted filtering. The limit is 1000.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "expand": {
	//       "description": "Optional. Specifies whether to expand the results. Set to `true` to expand the results. This query parameter is not valid if you use the `count` or `startKey` query parameters.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the developer. Use the following structure in your request: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "shallowExpand": {
	//       "description": "Optional. Specifies whether to expand the results in shallow mode. Set to `true` to expand the results in shallow mode.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "startKey": {
	//       "description": "**Note**: Must be used in conjunction with the `count` parameter. Name of the developer app from which to start displaying the list of developer apps. For example, if you're returning 50 developer apps at a time (using the `count` query parameter), you can view developer apps 50-99 by entering the name of the 50th developer app. The developer app name is case sensitive.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/apps",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeveloperAppsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.update":

type OrganizationsDevelopersAppsUpdateCall struct {
	s                               *Service
	name                            string
	googlecloudapigeev1developerapp *GoogleCloudApigeeV1DeveloperApp
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Update: Updates the details for a developer app. In addition, you can
// add an API product to a developer app and automatically generate an
// API key for the app to use when calling APIs in the API product. If
// you want to use an existing API key for the API product, add the API
// product to the API key using the UpdateDeveloperAppKey API. Using
// this API, you cannot update the following: * App name as it is the
// primary key used to identify the app and cannot be changed. * Scopes
// associated with the app. Instead, use the ReplaceDeveloperAppKey API.
// This API replaces the existing attributes with those specified in the
// request. Include or exclude any existing attributes that you want to
// retain or delete, respectively.
func (r *OrganizationsDevelopersAppsService) Update(name string, googlecloudapigeev1developerapp *GoogleCloudApigeeV1DeveloperApp) *OrganizationsDevelopersAppsUpdateCall {
	c := &OrganizationsDevelopersAppsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1developerapp = googlecloudapigeev1developerapp
	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 *OrganizationsDevelopersAppsUpdateCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsUpdateCall) Context(ctx context.Context) *OrganizationsDevelopersAppsUpdateCall {
	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 *OrganizationsDevelopersAppsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developerapp)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.update" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperApp or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperApp.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 *OrganizationsDevelopersAppsUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperApp, 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 := &GoogleCloudApigeeV1DeveloperApp{
		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": "Updates the details for a developer app. In addition, you can add an API product to a developer app and automatically generate an API key for the app to use when calling APIs in the API product. If you want to use an existing API key for the API product, add the API product to the API key using the UpdateDeveloperAppKey API. Using this API, you cannot update the following: * App name as it is the primary key used to identify the app and cannot be changed. * Scopes associated with the app. Instead, use the ReplaceDeveloperAppKey API. This API replaces the existing attributes with those specified in the request. Include or exclude any existing attributes that you want to retain or delete, respectively.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.developers.apps.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer app. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.attributes.delete":

type OrganizationsDevelopersAppsAttributesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a developer app attribute.
func (r *OrganizationsDevelopersAppsAttributesService) Delete(name string) *OrganizationsDevelopersAppsAttributesDeleteCall {
	c := &OrganizationsDevelopersAppsAttributesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAppsAttributesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsAttributesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsAttributesDeleteCall) Context(ctx context.Context) *OrganizationsDevelopersAppsAttributesDeleteCall {
	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 *OrganizationsDevelopersAppsAttributesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsAttributesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.attributes.delete" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsDevelopersAppsAttributesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Deletes a developer app attribute.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/attributes/{attributesId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.developers.apps.attributes.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer app attribute. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}/attributes/{attribute}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.attributes.get":

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

// Get: Returns a developer app attribute.
func (r *OrganizationsDevelopersAppsAttributesService) Get(name string) *OrganizationsDevelopersAppsAttributesGetCall {
	c := &OrganizationsDevelopersAppsAttributesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAppsAttributesGetCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsAttributesGetCall {
	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 *OrganizationsDevelopersAppsAttributesGetCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersAppsAttributesGetCall {
	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 *OrganizationsDevelopersAppsAttributesGetCall) Context(ctx context.Context) *OrganizationsDevelopersAppsAttributesGetCall {
	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 *OrganizationsDevelopersAppsAttributesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsAttributesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.attributes.get" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsDevelopersAppsAttributesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Returns a developer app attribute.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/attributes/{attributesId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.apps.attributes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer app attribute. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}/attributes/{attribute}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.attributes.list":

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

// List: Returns a list of all developer app attributes.
func (r *OrganizationsDevelopersAppsAttributesService) List(parent string) *OrganizationsDevelopersAppsAttributesListCall {
	c := &OrganizationsDevelopersAppsAttributesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsDevelopersAppsAttributesListCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsAttributesListCall {
	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 *OrganizationsDevelopersAppsAttributesListCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersAppsAttributesListCall {
	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 *OrganizationsDevelopersAppsAttributesListCall) Context(ctx context.Context) *OrganizationsDevelopersAppsAttributesListCall {
	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 *OrganizationsDevelopersAppsAttributesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsAttributesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/attributes")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.attributes.list" call.
// Exactly one of *GoogleCloudApigeeV1Attributes or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attributes.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 *OrganizationsDevelopersAppsAttributesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attributes, 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 := &GoogleCloudApigeeV1Attributes{
		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": "Returns a list of all developer app attributes.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/attributes",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.apps.attributes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the developer app. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attributes",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.attributes.updateDeveloperAppAttribute":

type OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall struct {
	s                            *Service
	name                         string
	googlecloudapigeev1attribute *GoogleCloudApigeeV1Attribute
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// UpdateDeveloperAppAttribute: Updates a developer app attribute.
// **Note**: OAuth access tokens and Key Management Service (KMS)
// entities (apps, developers, and API products) are cached for 180
// seconds (current default). Any custom attributes associated with
// these entities are cached for at least 180 seconds after the entity
// is accessed at runtime. Therefore, an `ExpiresIn` element on the
// OAuthV2 policy won't be able to expire an access token in less than
// 180 seconds.
func (r *OrganizationsDevelopersAppsAttributesService) UpdateDeveloperAppAttribute(name string, googlecloudapigeev1attribute *GoogleCloudApigeeV1Attribute) *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall {
	c := &OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1attribute = googlecloudapigeev1attribute
	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 *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall) Context(ctx context.Context) *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall {
	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 *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1attribute)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.attributes.updateDeveloperAppAttribute" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsDevelopersAppsAttributesUpdateDeveloperAppAttributeCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Updates a developer app attribute. **Note**: OAuth access tokens and Key Management Service (KMS) entities (apps, developers, and API products) are cached for 180 seconds (current default). Any custom attributes associated with these entities are cached for at least 180 seconds after the entity is accessed at runtime. Therefore, an `ExpiresIn` element on the OAuthV2 policy won't be able to expire an access token in less than 180 seconds.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/attributes/{attributesId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.attributes.updateDeveloperAppAttribute",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer app attribute. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}/attributes/{attribute}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.create":

type OrganizationsDevelopersAppsKeysCreateCall struct {
	s                                  *Service
	parent                             string
	googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// Create: Creates a custom consumer key and secret for a developer app.
// This is particularly useful if you want to migrate existing consumer
// keys and secrets to Apigee hybrid from another system. Consumer keys
// and secrets can contain letters, numbers, underscores, and hyphens.
// No other special characters are allowed. To avoid service
// disruptions, a consumer key and secret should not exceed 2 KBs each.
// **Note**: When creating the consumer key and secret, an association
// to API products will not be made. Therefore, you should not specify
// the associated API products in your request. Instead, use the
// UpdateDeveloperAppKey API to make the association after the consumer
// key and secret are created. If a consumer key and secret already
// exist, you can keep them or delete them using the
// DeleteDeveloperAppKey API.
func (r *OrganizationsDevelopersAppsKeysService) Create(parent string, googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey) *OrganizationsDevelopersAppsKeysCreateCall {
	c := &OrganizationsDevelopersAppsKeysCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1developerappkey = googlecloudapigeev1developerappkey
	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 *OrganizationsDevelopersAppsKeysCreateCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsKeysCreateCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysCreateCall {
	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 *OrganizationsDevelopersAppsKeysCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developerappkey)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/keys")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.create" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperAppKey or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperAppKey.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 *OrganizationsDevelopersAppsKeysCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperAppKey, 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 := &GoogleCloudApigeeV1DeveloperAppKey{
		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": "Creates a custom consumer key and secret for a developer app. This is particularly useful if you want to migrate existing consumer keys and secrets to Apigee hybrid from another system. Consumer keys and secrets can contain letters, numbers, underscores, and hyphens. No other special characters are allowed. To avoid service disruptions, a consumer key and secret should not exceed 2 KBs each. **Note**: When creating the consumer key and secret, an association to API products will not be made. Therefore, you should not specify the associated API products in your request. Instead, use the UpdateDeveloperAppKey API to make the association after the consumer key and secret are created. If a consumer key and secret already exist, you can keep them or delete them using the DeleteDeveloperAppKey API.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.keys.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Parent of the developer app key. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/keys",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.delete":

type OrganizationsDevelopersAppsKeysDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an app's consumer key and removes all API products
// associated with the app. After the consumer key is deleted, it cannot
// be used to access any APIs. **Note**: After you delete a consumer
// key, you may want to: 1. Create a new consumer key and secret for the
// developer app using the CreateDeveloperAppKey API, and subsequently
// add an API product to the key using the UpdateDeveloperAppKey API. 2.
// Delete the developer app, if it is no longer required.
func (r *OrganizationsDevelopersAppsKeysService) Delete(name string) *OrganizationsDevelopersAppsKeysDeleteCall {
	c := &OrganizationsDevelopersAppsKeysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAppsKeysDeleteCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsKeysDeleteCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysDeleteCall {
	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 *OrganizationsDevelopersAppsKeysDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.delete" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperAppKey or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperAppKey.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 *OrganizationsDevelopersAppsKeysDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperAppKey, 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 := &GoogleCloudApigeeV1DeveloperAppKey{
		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": "Deletes an app's consumer key and removes all API products associated with the app. After the consumer key is deleted, it cannot be used to access any APIs. **Note**: After you delete a consumer key, you may want to: 1. Create a new consumer key and secret for the developer app using the CreateDeveloperAppKey API, and subsequently add an API product to the key using the UpdateDeveloperAppKey API. 2. Delete the developer app, if it is no longer required.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys/{keysId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.developers.apps.keys.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the developer app key. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}/keys/{key}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/keys/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.get":

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

// Get: Returns details for a consumer key for a developer app,
// including the key and secret value, associated API products, and
// other information.
func (r *OrganizationsDevelopersAppsKeysService) Get(name string) *OrganizationsDevelopersAppsKeysGetCall {
	c := &OrganizationsDevelopersAppsKeysGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAppsKeysGetCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysGetCall {
	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 *OrganizationsDevelopersAppsKeysGetCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersAppsKeysGetCall {
	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 *OrganizationsDevelopersAppsKeysGetCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysGetCall {
	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 *OrganizationsDevelopersAppsKeysGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.get" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperAppKey or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperAppKey.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 *OrganizationsDevelopersAppsKeysGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperAppKey, 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 := &GoogleCloudApigeeV1DeveloperAppKey{
		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": "Returns details for a consumer key for a developer app, including the key and secret value, associated API products, and other information.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys/{keysId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.apps.keys.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the developer app key. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}/keys/{key}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/keys/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.replaceDeveloperAppKey":

type OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall struct {
	s                                  *Service
	name                               string
	googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// ReplaceDeveloperAppKey: Updates the scope of an app. This API
// replaces the existing scopes with those specified in the request.
// Include or exclude any existing scopes that you want to retain or
// delete, respectively. The specified scopes must already be defined
// for the API products associated with the app. This API sets the
// `scopes` element under the `apiProducts` element in the attributes of
// the app.
func (r *OrganizationsDevelopersAppsKeysService) ReplaceDeveloperAppKey(name string, googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey) *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall {
	c := &OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1developerappkey = googlecloudapigeev1developerappkey
	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 *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall {
	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 *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developerappkey)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.replaceDeveloperAppKey" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperAppKey or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperAppKey.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 *OrganizationsDevelopersAppsKeysReplaceDeveloperAppKeyCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperAppKey, 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 := &GoogleCloudApigeeV1DeveloperAppKey{
		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": "Updates the scope of an app. This API replaces the existing scopes with those specified in the request. Include or exclude any existing scopes that you want to retain or delete, respectively. The specified scopes must already be defined for the API products associated with the app. This API sets the `scopes` element under the `apiProducts` element in the attributes of the app.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys/{keysId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.developers.apps.keys.replaceDeveloperAppKey",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the developer app key. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}/keys/{key}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/keys/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.updateDeveloperAppKey":

type OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall struct {
	s                                  *Service
	name                               string
	googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// UpdateDeveloperAppKey: Adds an API product to a developer app key,
// enabling the app that holds the key to access the API resources
// bundled in the API product. In addition, you can add attributes to a
// developer app key. This API replaces the existing attributes with
// those specified in the request. Include or exclude any existing
// attributes that you want to retain or delete, respectively. You can
// use the same key to access all API products associated with the app.
func (r *OrganizationsDevelopersAppsKeysService) UpdateDeveloperAppKey(name string, googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey) *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall {
	c := &OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1developerappkey = googlecloudapigeev1developerappkey
	return c
}

// Action sets the optional parameter "action": Approve or revoke the
// consumer key by setting this value to `approve` or `revoke`,
// respectively.
func (c *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall) Action(action string) *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall {
	c.urlParams_.Set("action", action)
	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 *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall {
	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 *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developerappkey)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.updateDeveloperAppKey" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperAppKey or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperAppKey.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 *OrganizationsDevelopersAppsKeysUpdateDeveloperAppKeyCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperAppKey, 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 := &GoogleCloudApigeeV1DeveloperAppKey{
		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": "Adds an API product to a developer app key, enabling the app that holds the key to access the API resources bundled in the API product. In addition, you can add attributes to a developer app key. This API replaces the existing attributes with those specified in the request. Include or exclude any existing attributes that you want to retain or delete, respectively. You can use the same key to access all API products associated with the app.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys/{keysId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.keys.updateDeveloperAppKey",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Approve or revoke the consumer key by setting this value to `approve` or `revoke`, respectively.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Name of the developer app key. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps/{app}/keys/{key}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/keys/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.apiproducts.delete":

type OrganizationsDevelopersAppsKeysApiproductsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Removes an API product from an app's consumer key. After the
// API product is removed, the app cannot access the API resources
// defined in that API product. **Note**: The consumer key is not
// removed, only its association with the API product.
func (r *OrganizationsDevelopersAppsKeysApiproductsService) Delete(name string) *OrganizationsDevelopersAppsKeysApiproductsDeleteCall {
	c := &OrganizationsDevelopersAppsKeysApiproductsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAppsKeysApiproductsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysApiproductsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsKeysApiproductsDeleteCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysApiproductsDeleteCall {
	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 *OrganizationsDevelopersAppsKeysApiproductsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysApiproductsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.apiproducts.delete" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperAppKey or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperAppKey.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 *OrganizationsDevelopersAppsKeysApiproductsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperAppKey, 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 := &GoogleCloudApigeeV1DeveloperAppKey{
		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": "Removes an API product from an app's consumer key. After the API product is removed, the app cannot access the API resources defined in that API product. **Note**: The consumer key is not removed, only its association with the API product.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys/{keysId}/apiproducts/{apiproductsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.developers.apps.keys.apiproducts.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the API product in the developer app key in the following format: `organizations/{org}/developers/{developer_email}/apps/{app}/keys/{key}/apiproducts/{apiproduct}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/keys/[^/]+/apiproducts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.apiproducts.updateDeveloperAppKeyApiProduct":

type OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// UpdateDeveloperAppKeyApiProduct: Approve or revoke an app's consumer
// key. After a consumer key is approved, the app can use it to access
// APIs. A consumer key that is revoked or pending cannot be used to
// access an API. Any access tokens associated with a revoked consumer
// key will remain active. However, Apigee hybrid checks the status of
// the consumer key and if set to `revoked` will not allow access to the
// API.
func (r *OrganizationsDevelopersAppsKeysApiproductsService) UpdateDeveloperAppKeyApiProduct(name string) *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall {
	c := &OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Action sets the optional parameter "action": Approve or revoke the
// consumer key by setting this value to `approve` or `revoke`,
// respectively.
func (c *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall) Action(action string) *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall {
	c.urlParams_.Set("action", action)
	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 *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall {
	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 *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.apiproducts.updateDeveloperAppKeyApiProduct" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsDevelopersAppsKeysApiproductsUpdateDeveloperAppKeyApiProductCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Approve or revoke an app's consumer key. After a consumer key is approved, the app can use it to access APIs. A consumer key that is revoked or pending cannot be used to access an API. Any access tokens associated with a revoked consumer key will remain active. However, Apigee hybrid checks the status of the consumer key and if set to `revoked` will not allow access to the API.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys/{keysId}/apiproducts/{apiproductsId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.keys.apiproducts.updateDeveloperAppKeyApiProduct",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Approve or revoke the consumer key by setting this value to `approve` or `revoke`, respectively.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Name of the API product in the developer app key in the following format: `organizations/{org}/developers/{developer_email}/apps/{app}/keys/{key}/apiproducts/{apiproduct}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+/keys/[^/]+/apiproducts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.apps.keys.create.create":

type OrganizationsDevelopersAppsKeysCreateCreateCall struct {
	s                                  *Service
	parent                             string
	googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// Create: Creates a custom consumer key and secret for a developer app.
// This is particularly useful if you want to migrate existing consumer
// keys and secrets to Apigee hybrid from another system. Consumer keys
// and secrets can contain letters, numbers, underscores, and hyphens.
// No other special characters are allowed. To avoid service
// disruptions, a consumer key and secret should not exceed 2 KBs each.
// **Note**: When creating the consumer key and secret, an association
// to API products will not be made. Therefore, you should not specify
// the associated API products in your request. Instead, use the
// UpdateDeveloperAppKey API to make the association after the consumer
// key and secret are created. If a consumer key and secret already
// exist, you can keep them or delete them using the
// DeleteDeveloperAppKey API.
func (r *OrganizationsDevelopersAppsKeysCreateService) Create(parent string, googlecloudapigeev1developerappkey *GoogleCloudApigeeV1DeveloperAppKey) *OrganizationsDevelopersAppsKeysCreateCreateCall {
	c := &OrganizationsDevelopersAppsKeysCreateCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1developerappkey = googlecloudapigeev1developerappkey
	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 *OrganizationsDevelopersAppsKeysCreateCreateCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAppsKeysCreateCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAppsKeysCreateCreateCall) Context(ctx context.Context) *OrganizationsDevelopersAppsKeysCreateCreateCall {
	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 *OrganizationsDevelopersAppsKeysCreateCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAppsKeysCreateCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1developerappkey)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/keys/create")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.apps.keys.create.create" call.
// Exactly one of *GoogleCloudApigeeV1DeveloperAppKey or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DeveloperAppKey.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 *OrganizationsDevelopersAppsKeysCreateCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeveloperAppKey, 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 := &GoogleCloudApigeeV1DeveloperAppKey{
		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": "Creates a custom consumer key and secret for a developer app. This is particularly useful if you want to migrate existing consumer keys and secrets to Apigee hybrid from another system. Consumer keys and secrets can contain letters, numbers, underscores, and hyphens. No other special characters are allowed. To avoid service disruptions, a consumer key and secret should not exceed 2 KBs each. **Note**: When creating the consumer key and secret, an association to API products will not be made. Therefore, you should not specify the associated API products in your request. Instead, use the UpdateDeveloperAppKey API to make the association after the consumer key and secret are created. If a consumer key and secret already exist, you can keep them or delete them using the DeleteDeveloperAppKey API.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/apps/{appsId}/keys/create",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.apps.keys.create.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Parent of the developer app key. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/apps`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/apps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/keys/create",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeveloperAppKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.attributes.delete":

type OrganizationsDevelopersAttributesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a developer attribute.
func (r *OrganizationsDevelopersAttributesService) Delete(name string) *OrganizationsDevelopersAttributesDeleteCall {
	c := &OrganizationsDevelopersAttributesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAttributesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAttributesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAttributesDeleteCall) Context(ctx context.Context) *OrganizationsDevelopersAttributesDeleteCall {
	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 *OrganizationsDevelopersAttributesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAttributesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.attributes.delete" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsDevelopersAttributesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Deletes a developer attribute.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/attributes/{attributesId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.developers.attributes.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer attribute. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/attributes/{attribute}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.attributes.get":

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

// Get: Returns the value of the specified developer attribute.
func (r *OrganizationsDevelopersAttributesService) Get(name string) *OrganizationsDevelopersAttributesGetCall {
	c := &OrganizationsDevelopersAttributesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsDevelopersAttributesGetCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAttributesGetCall {
	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 *OrganizationsDevelopersAttributesGetCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersAttributesGetCall {
	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 *OrganizationsDevelopersAttributesGetCall) Context(ctx context.Context) *OrganizationsDevelopersAttributesGetCall {
	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 *OrganizationsDevelopersAttributesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAttributesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.attributes.get" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsDevelopersAttributesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Returns the value of the specified developer attribute.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/attributes/{attributesId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.attributes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer attribute. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/attributes/{attribute}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.attributes.list":

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

// List: Returns a list of all developer attributes.
func (r *OrganizationsDevelopersAttributesService) List(parent string) *OrganizationsDevelopersAttributesListCall {
	c := &OrganizationsDevelopersAttributesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsDevelopersAttributesListCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAttributesListCall {
	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 *OrganizationsDevelopersAttributesListCall) IfNoneMatch(entityTag string) *OrganizationsDevelopersAttributesListCall {
	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 *OrganizationsDevelopersAttributesListCall) Context(ctx context.Context) *OrganizationsDevelopersAttributesListCall {
	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 *OrganizationsDevelopersAttributesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAttributesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/attributes")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.attributes.list" call.
// Exactly one of *GoogleCloudApigeeV1Attributes or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attributes.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 *OrganizationsDevelopersAttributesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attributes, 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 := &GoogleCloudApigeeV1Attributes{
		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": "Returns a list of all developer attributes.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/attributes",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.developers.attributes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Email address of the developer for which attributes are being listed in the following format: `organizations/{org}/developers/{developer_email}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attributes",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attributes"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.developers.attributes.updateDeveloperAttribute":

type OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall struct {
	s                            *Service
	name                         string
	googlecloudapigeev1attribute *GoogleCloudApigeeV1Attribute
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// UpdateDeveloperAttribute: Updates a developer attribute. **Note**:
// OAuth access tokens and Key Management Service (KMS) entities (apps,
// developers, and API products) are cached for 180 seconds (default).
// Any custom attributes associated with these entities are cached for
// at least 180 seconds after the entity is accessed at runtime.
// Therefore, an `ExpiresIn` element on the OAuthV2 policy won't be able
// to expire an access token in less than 180 seconds.
func (r *OrganizationsDevelopersAttributesService) UpdateDeveloperAttribute(name string, googlecloudapigeev1attribute *GoogleCloudApigeeV1Attribute) *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall {
	c := &OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1attribute = googlecloudapigeev1attribute
	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 *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall) Fields(s ...googleapi.Field) *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall) Context(ctx context.Context) *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall {
	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 *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1attribute)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.developers.attributes.updateDeveloperAttribute" call.
// Exactly one of *GoogleCloudApigeeV1Attribute or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Attribute.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 *OrganizationsDevelopersAttributesUpdateDeveloperAttributeCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Attribute, 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 := &GoogleCloudApigeeV1Attribute{
		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": "Updates a developer attribute. **Note**: OAuth access tokens and Key Management Service (KMS) entities (apps, developers, and API products) are cached for 180 seconds (default). Any custom attributes associated with these entities are cached for at least 180 seconds after the entity is accessed at runtime. Therefore, an `ExpiresIn` element on the OAuthV2 policy won't be able to expire an access token in less than 180 seconds.",
	//   "flatPath": "v1/organizations/{organizationsId}/developers/{developersId}/attributes/{attributesId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.developers.attributes.updateDeveloperAttribute",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the developer attribute. Use the following structure in your request: `organizations/{org}/developers/{developer_email}/attributes/{attribute}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/developers/[^/]+/attributes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Attribute"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.create":

type OrganizationsEnvgroupsCreateCall struct {
	s                                   *Service
	parent                              string
	googlecloudapigeev1environmentgroup *GoogleCloudApigeeV1EnvironmentGroup
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// Create: Creates a new environment group.
func (r *OrganizationsEnvgroupsService) Create(parent string, googlecloudapigeev1environmentgroup *GoogleCloudApigeeV1EnvironmentGroup) *OrganizationsEnvgroupsCreateCall {
	c := &OrganizationsEnvgroupsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1environmentgroup = googlecloudapigeev1environmentgroup
	return c
}

// Name sets the optional parameter "name": ID of the environment group.
// Overrides any ID in the environment_group resource.
func (c *OrganizationsEnvgroupsCreateCall) Name(name string) *OrganizationsEnvgroupsCreateCall {
	c.urlParams_.Set("name", name)
	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 *OrganizationsEnvgroupsCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvgroupsCreateCall) Context(ctx context.Context) *OrganizationsEnvgroupsCreateCall {
	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 *OrganizationsEnvgroupsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1environmentgroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/envgroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.create" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsEnvgroupsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Creates a new environment group.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.envgroups.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "ID of the environment group. Overrides any ID in the environment_group resource.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization in which to create the environment group in the following format: `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/envgroups",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1EnvironmentGroup"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.delete":

type OrganizationsEnvgroupsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an environment group.
func (r *OrganizationsEnvgroupsService) Delete(name string) *OrganizationsEnvgroupsDeleteCall {
	c := &OrganizationsEnvgroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvgroupsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvgroupsDeleteCall) Context(ctx context.Context) *OrganizationsEnvgroupsDeleteCall {
	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 *OrganizationsEnvgroupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.delete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsEnvgroupsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes an environment group.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups/{envgroupsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.envgroups.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment group in the following format: `organizations/{org}/envgroups/{envgroup}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/envgroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.get":

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

// Get: Gets an environment group.
func (r *OrganizationsEnvgroupsService) Get(name string) *OrganizationsEnvgroupsGetCall {
	c := &OrganizationsEnvgroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvgroupsGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsGetCall {
	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 *OrganizationsEnvgroupsGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvgroupsGetCall {
	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 *OrganizationsEnvgroupsGetCall) Context(ctx context.Context) *OrganizationsEnvgroupsGetCall {
	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 *OrganizationsEnvgroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.get" call.
// Exactly one of *GoogleCloudApigeeV1EnvironmentGroup or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1EnvironmentGroup.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 *OrganizationsEnvgroupsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1EnvironmentGroup, 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 := &GoogleCloudApigeeV1EnvironmentGroup{
		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": "Gets an environment group.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups/{envgroupsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.envgroups.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment group in the following format: `organizations/{org}/envgroups/{envgroup}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/envgroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1EnvironmentGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.list":

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

// List: Lists all environment groups.
func (r *OrganizationsEnvgroupsService) List(parent string) *OrganizationsEnvgroupsListCall {
	c := &OrganizationsEnvgroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// environment groups to return. The page size defaults to 25.
func (c *OrganizationsEnvgroupsListCall) PageSize(pageSize int64) *OrganizationsEnvgroupsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned from a previous ListEnvironmentGroups call, that you can use
// to retrieve the next page.
func (c *OrganizationsEnvgroupsListCall) PageToken(pageToken string) *OrganizationsEnvgroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *OrganizationsEnvgroupsListCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsListCall {
	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 *OrganizationsEnvgroupsListCall) IfNoneMatch(entityTag string) *OrganizationsEnvgroupsListCall {
	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 *OrganizationsEnvgroupsListCall) Context(ctx context.Context) *OrganizationsEnvgroupsListCall {
	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 *OrganizationsEnvgroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/envgroups")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.list" call.
// Exactly one of *GoogleCloudApigeeV1ListEnvironmentGroupsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListEnvironmentGroupsResponse.ServerResponse.Heade
// r 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 *OrganizationsEnvgroupsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListEnvironmentGroupsResponse, 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 := &GoogleCloudApigeeV1ListEnvironmentGroupsResponse{
		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": "Lists all environment groups.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.envgroups.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum number of environment groups to return. The page size defaults to 25.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned from a previous ListEnvironmentGroups call, that you can use to retrieve the next page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization for which to list environment groups in the following format: `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/envgroups",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListEnvironmentGroupsResponse"
	//   },
	//   "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 *OrganizationsEnvgroupsListCall) Pages(ctx context.Context, f func(*GoogleCloudApigeeV1ListEnvironmentGroupsResponse) 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 "apigee.organizations.envgroups.patch":

type OrganizationsEnvgroupsPatchCall struct {
	s                                   *Service
	name                                string
	googlecloudapigeev1environmentgroup *GoogleCloudApigeeV1EnvironmentGroup
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// Patch: Updates an environment group.
func (r *OrganizationsEnvgroupsService) Patch(name string, googlecloudapigeev1environmentgroup *GoogleCloudApigeeV1EnvironmentGroup) *OrganizationsEnvgroupsPatchCall {
	c := &OrganizationsEnvgroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1environmentgroup = googlecloudapigeev1environmentgroup
	return c
}

// UpdateMask sets the optional parameter "updateMask": List of fields
// to be updated.
func (c *OrganizationsEnvgroupsPatchCall) UpdateMask(updateMask string) *OrganizationsEnvgroupsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsEnvgroupsPatchCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvgroupsPatchCall) Context(ctx context.Context) *OrganizationsEnvgroupsPatchCall {
	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 *OrganizationsEnvgroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1environmentgroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.patch" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsEnvgroupsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Updates an environment group.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups/{envgroupsId}",
	//   "httpMethod": "PATCH",
	//   "id": "apigee.organizations.envgroups.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment group to update in the format: `organizations/{org}/envgroups/{envgroup}.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/envgroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "List of fields to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1EnvironmentGroup"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.attachments.create":

type OrganizationsEnvgroupsAttachmentsCreateCall struct {
	s                                             *Service
	parent                                        string
	googlecloudapigeev1environmentgroupattachment *GoogleCloudApigeeV1EnvironmentGroupAttachment
	urlParams_                                    gensupport.URLParams
	ctx_                                          context.Context
	header_                                       http.Header
}

// Create: Creates a new attachment of an environment to an environment
// group.
func (r *OrganizationsEnvgroupsAttachmentsService) Create(parent string, googlecloudapigeev1environmentgroupattachment *GoogleCloudApigeeV1EnvironmentGroupAttachment) *OrganizationsEnvgroupsAttachmentsCreateCall {
	c := &OrganizationsEnvgroupsAttachmentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1environmentgroupattachment = googlecloudapigeev1environmentgroupattachment
	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 *OrganizationsEnvgroupsAttachmentsCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsAttachmentsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvgroupsAttachmentsCreateCall) Context(ctx context.Context) *OrganizationsEnvgroupsAttachmentsCreateCall {
	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 *OrganizationsEnvgroupsAttachmentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsAttachmentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1environmentgroupattachment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/attachments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.attachments.create" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsEnvgroupsAttachmentsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Creates a new attachment of an environment to an environment group.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups/{envgroupsId}/attachments",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.envgroups.attachments.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. EnvironmentGroup under which to create the attachment in the following format: `organizations/{org}/envgroups/{envgroup}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/envgroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attachments",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1EnvironmentGroupAttachment"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.attachments.delete":

type OrganizationsEnvgroupsAttachmentsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an environment group attachment.
func (r *OrganizationsEnvgroupsAttachmentsService) Delete(name string) *OrganizationsEnvgroupsAttachmentsDeleteCall {
	c := &OrganizationsEnvgroupsAttachmentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvgroupsAttachmentsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsAttachmentsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvgroupsAttachmentsDeleteCall) Context(ctx context.Context) *OrganizationsEnvgroupsAttachmentsDeleteCall {
	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 *OrganizationsEnvgroupsAttachmentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsAttachmentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.attachments.delete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsEnvgroupsAttachmentsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes an environment group attachment.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups/{envgroupsId}/attachments/{attachmentsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.envgroups.attachments.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment group attachment to delete in the following format: `organizations/{org}/envgroups/{envgroup}/attachments/{attachment}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/envgroups/[^/]+/attachments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.attachments.get":

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

// Get: Gets an environment group attachment.
func (r *OrganizationsEnvgroupsAttachmentsService) Get(name string) *OrganizationsEnvgroupsAttachmentsGetCall {
	c := &OrganizationsEnvgroupsAttachmentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvgroupsAttachmentsGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsAttachmentsGetCall {
	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 *OrganizationsEnvgroupsAttachmentsGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvgroupsAttachmentsGetCall {
	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 *OrganizationsEnvgroupsAttachmentsGetCall) Context(ctx context.Context) *OrganizationsEnvgroupsAttachmentsGetCall {
	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 *OrganizationsEnvgroupsAttachmentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsAttachmentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.attachments.get" call.
// Exactly one of *GoogleCloudApigeeV1EnvironmentGroupAttachment or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1EnvironmentGroupAttachment.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 *OrganizationsEnvgroupsAttachmentsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1EnvironmentGroupAttachment, 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 := &GoogleCloudApigeeV1EnvironmentGroupAttachment{
		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": "Gets an environment group attachment.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups/{envgroupsId}/attachments/{attachmentsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.envgroups.attachments.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment group attachment in the following format: `organizations/{org}/envgroups/{envgroup}/attachments/{attachment}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/envgroups/[^/]+/attachments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1EnvironmentGroupAttachment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.envgroups.attachments.list":

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

// List: Lists all attachments of an environment group.
func (r *OrganizationsEnvgroupsAttachmentsService) List(parent string) *OrganizationsEnvgroupsAttachmentsListCall {
	c := &OrganizationsEnvgroupsAttachmentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// environment group attachments to return. The page size defaults to
// 25.
func (c *OrganizationsEnvgroupsAttachmentsListCall) PageSize(pageSize int64) *OrganizationsEnvgroupsAttachmentsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous ListEnvironmentGroupAttachments call, that you
// can use to retrieve the next page.
func (c *OrganizationsEnvgroupsAttachmentsListCall) PageToken(pageToken string) *OrganizationsEnvgroupsAttachmentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *OrganizationsEnvgroupsAttachmentsListCall) Fields(s ...googleapi.Field) *OrganizationsEnvgroupsAttachmentsListCall {
	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 *OrganizationsEnvgroupsAttachmentsListCall) IfNoneMatch(entityTag string) *OrganizationsEnvgroupsAttachmentsListCall {
	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 *OrganizationsEnvgroupsAttachmentsListCall) Context(ctx context.Context) *OrganizationsEnvgroupsAttachmentsListCall {
	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 *OrganizationsEnvgroupsAttachmentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvgroupsAttachmentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/attachments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.envgroups.attachments.list" call.
// Exactly one of
// *GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse.ServerResp
// onse.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 *OrganizationsEnvgroupsAttachmentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse, 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 := &GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse{
		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": "Lists all attachments of an environment group.",
	//   "flatPath": "v1/organizations/{organizationsId}/envgroups/{envgroupsId}/attachments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.envgroups.attachments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum number of environment group attachments to return. The page size defaults to 25.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous ListEnvironmentGroupAttachments call, that you can use to retrieve the next page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization in the following format: `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/envgroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attachments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse"
	//   },
	//   "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 *OrganizationsEnvgroupsAttachmentsListCall) Pages(ctx context.Context, f func(*GoogleCloudApigeeV1ListEnvironmentGroupAttachmentsResponse) 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 "apigee.organizations.environments.create":

type OrganizationsEnvironmentsCreateCall struct {
	s                              *Service
	parent                         string
	googlecloudapigeev1environment *GoogleCloudApigeeV1Environment
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Create: Creates an environment in an organization.
func (r *OrganizationsEnvironmentsService) Create(parent string, googlecloudapigeev1environment *GoogleCloudApigeeV1Environment) *OrganizationsEnvironmentsCreateCall {
	c := &OrganizationsEnvironmentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1environment = googlecloudapigeev1environment
	return c
}

// Name sets the optional parameter "name": Name of the environment.
// Alternatively, the name may be specified in the request body in the
// name field.
func (c *OrganizationsEnvironmentsCreateCall) Name(name string) *OrganizationsEnvironmentsCreateCall {
	c.urlParams_.Set("name", name)
	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 *OrganizationsEnvironmentsCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsCreateCall {
	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 *OrganizationsEnvironmentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1environment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/environments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.create" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsEnvironmentsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Creates an environment in an organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Optional. Name of the environment. Alternatively, the name may be specified in the request body in the name field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization in which the environment will be created. Use the following structure in your request: `organizations/{org}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/environments",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Environment"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.delete":

type OrganizationsEnvironmentsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an environment from an organization.
func (r *OrganizationsEnvironmentsService) Delete(name string) *OrganizationsEnvironmentsDeleteCall {
	c := &OrganizationsEnvironmentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsDeleteCall {
	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 *OrganizationsEnvironmentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.delete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsEnvironmentsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes an environment from an organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment. Use the following structure in your request: `organizations/{org}/environments/{env}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.get":

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

// Get: Gets environment details.
func (r *OrganizationsEnvironmentsService) Get(name string) *OrganizationsEnvironmentsGetCall {
	c := &OrganizationsEnvironmentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsGetCall {
	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 *OrganizationsEnvironmentsGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsGetCall {
	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 *OrganizationsEnvironmentsGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsGetCall {
	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 *OrganizationsEnvironmentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.get" call.
// Exactly one of *GoogleCloudApigeeV1Environment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Environment.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 *OrganizationsEnvironmentsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Environment, 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 := &GoogleCloudApigeeV1Environment{
		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": "Gets environment details.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment. Use the following structure in your request: `organizations/{org}/environments/{env}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Environment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.getDebugmask":

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

// GetDebugmask: Gets the debug mask singleton resource for an
// environment.
func (r *OrganizationsEnvironmentsService) GetDebugmask(name string) *OrganizationsEnvironmentsGetDebugmaskCall {
	c := &OrganizationsEnvironmentsGetDebugmaskCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsGetDebugmaskCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsGetDebugmaskCall {
	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 *OrganizationsEnvironmentsGetDebugmaskCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsGetDebugmaskCall {
	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 *OrganizationsEnvironmentsGetDebugmaskCall) Context(ctx context.Context) *OrganizationsEnvironmentsGetDebugmaskCall {
	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 *OrganizationsEnvironmentsGetDebugmaskCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsGetDebugmaskCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.getDebugmask" call.
// Exactly one of *GoogleCloudApigeeV1DebugMask or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DebugMask.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 *OrganizationsEnvironmentsGetDebugmaskCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DebugMask, 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 := &GoogleCloudApigeeV1DebugMask{
		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": "Gets the debug mask singleton resource for an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/debugmask",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.getDebugmask",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the debug mask. Use the following structure in your request: `organizations/{org}/environments/{env}/debugmask`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/debugmask$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DebugMask"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.getDeployedConfig":

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

// GetDeployedConfig: Gets the deployed configuration for an
// environment.
func (r *OrganizationsEnvironmentsService) GetDeployedConfig(name string) *OrganizationsEnvironmentsGetDeployedConfigCall {
	c := &OrganizationsEnvironmentsGetDeployedConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsGetDeployedConfigCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsGetDeployedConfigCall {
	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 *OrganizationsEnvironmentsGetDeployedConfigCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsGetDeployedConfigCall {
	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 *OrganizationsEnvironmentsGetDeployedConfigCall) Context(ctx context.Context) *OrganizationsEnvironmentsGetDeployedConfigCall {
	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 *OrganizationsEnvironmentsGetDeployedConfigCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsGetDeployedConfigCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.getDeployedConfig" call.
// Exactly one of *GoogleCloudApigeeV1EnvironmentConfig or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1EnvironmentConfig.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 *OrganizationsEnvironmentsGetDeployedConfigCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1EnvironmentConfig, 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 := &GoogleCloudApigeeV1EnvironmentConfig{
		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": "Gets the deployed configuration for an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/deployedConfig",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.getDeployedConfig",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment deployed configuration resource. Use the following structure in your request: `organizations/{org}/environments/{env}/deployedConfig`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/deployedConfig$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1EnvironmentConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.getIamPolicy":

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

// GetIamPolicy: Gets the IAM policy on an environment. For more
// information, see [Manage users, roles, and permissions using the
// API](https://docs.apigee.com/hybrid/latest/manage-users-roles). You
// must have the `apigee.environments.getIamPolicy` permission to call
// this API.
func (r *OrganizationsEnvironmentsService) GetIamPolicy(resource string) *OrganizationsEnvironmentsGetIamPolicyCall {
	c := &OrganizationsEnvironmentsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// OptionsRequestedPolicyVersion sets the optional parameter
// "options.requestedPolicyVersion": The policy format version to be
// returned. Valid values are 0, 1, and 3. Requests specifying an
// invalid value will be rejected. Requests for policies with any
// conditional bindings must specify version 3. Policies without any
// conditional bindings may specify any valid value or leave the field
// unset. To learn which resources support conditions in their IAM
// policies, see the [IAM
// documentation](https://cloud.google.com/iam/help/conditions/resource-p
// olicies).
func (c *OrganizationsEnvironmentsGetIamPolicyCall) OptionsRequestedPolicyVersion(optionsRequestedPolicyVersion int64) *OrganizationsEnvironmentsGetIamPolicyCall {
	c.urlParams_.Set("options.requestedPolicyVersion", fmt.Sprint(optionsRequestedPolicyVersion))
	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 *OrganizationsEnvironmentsGetIamPolicyCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsGetIamPolicyCall {
	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 *OrganizationsEnvironmentsGetIamPolicyCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsGetIamPolicyCall {
	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 *OrganizationsEnvironmentsGetIamPolicyCall) Context(ctx context.Context) *OrganizationsEnvironmentsGetIamPolicyCall {
	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 *OrganizationsEnvironmentsGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+resource}:getIamPolicy")
	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 "apigee.organizations.environments.getIamPolicy" call.
// Exactly one of *GoogleIamV1Policy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleIamV1Policy.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 *OrganizationsEnvironmentsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*GoogleIamV1Policy, 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 := &GoogleIamV1Policy{
		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": "Gets the IAM policy on an environment. For more information, see [Manage users, roles, and permissions using the API](https://docs.apigee.com/hybrid/latest/manage-users-roles). You must have the `apigee.environments.getIamPolicy` permission to call this API.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}:getIamPolicy",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.getIamPolicy",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "options.requestedPolicyVersion": {
	//       "description": "Optional. The policy format version to be returned. Valid values are 0, 1, and 3. Requests specifying an invalid value will be rejected. Requests for policies with any conditional bindings must specify version 3. Policies without any conditional bindings may specify any valid value or leave the field unset. To learn which resources support conditions in their IAM policies, see the [IAM documentation](https://cloud.google.com/iam/help/conditions/resource-policies).",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy is being requested. See the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resource}:getIamPolicy",
	//   "response": {
	//     "$ref": "GoogleIamV1Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.setIamPolicy":

type OrganizationsEnvironmentsSetIamPolicyCall struct {
	s                              *Service
	resource                       string
	googleiamv1setiampolicyrequest *GoogleIamV1SetIamPolicyRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// SetIamPolicy: Sets the IAM policy on an environment, if the policy
// already exists it will be replaced. For more information, see [Manage
// users, roles, and permissions using the
// API](https://docs.apigee.com/hybrid/latest/manage-users-roles). You
// must have the `apigee.environments.setIamPolicy` permission to call
// this API.
func (r *OrganizationsEnvironmentsService) SetIamPolicy(resource string, googleiamv1setiampolicyrequest *GoogleIamV1SetIamPolicyRequest) *OrganizationsEnvironmentsSetIamPolicyCall {
	c := &OrganizationsEnvironmentsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.googleiamv1setiampolicyrequest = googleiamv1setiampolicyrequest
	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 *OrganizationsEnvironmentsSetIamPolicyCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsSetIamPolicyCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsSetIamPolicyCall) Context(ctx context.Context) *OrganizationsEnvironmentsSetIamPolicyCall {
	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 *OrganizationsEnvironmentsSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleiamv1setiampolicyrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "apigee.organizations.environments.setIamPolicy" call.
// Exactly one of *GoogleIamV1Policy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleIamV1Policy.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 *OrganizationsEnvironmentsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*GoogleIamV1Policy, 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 := &GoogleIamV1Policy{
		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": "Sets the IAM policy on an environment, if the policy already exists it will be replaced. For more information, see [Manage users, roles, and permissions using the API](https://docs.apigee.com/hybrid/latest/manage-users-roles). You must have the `apigee.environments.setIamPolicy` permission to call this API.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}:setIamPolicy",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.setIamPolicy",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy is being specified. See the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resource}:setIamPolicy",
	//   "request": {
	//     "$ref": "GoogleIamV1SetIamPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleIamV1Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.subscribe":

type OrganizationsEnvironmentsSubscribeCall struct {
	s          *Service
	parent     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Subscribe: Creates a subscription for the environment's Pub/Sub
// topic. The server will assign a random name for this subscription.
// The "name" and "push_config" must *not* be specified.
func (r *OrganizationsEnvironmentsService) Subscribe(parent string) *OrganizationsEnvironmentsSubscribeCall {
	c := &OrganizationsEnvironmentsSubscribeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsEnvironmentsSubscribeCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsSubscribeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsSubscribeCall) Context(ctx context.Context) *OrganizationsEnvironmentsSubscribeCall {
	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 *OrganizationsEnvironmentsSubscribeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsSubscribeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:subscribe")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.subscribe" call.
// Exactly one of *GoogleCloudApigeeV1Subscription or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Subscription.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 *OrganizationsEnvironmentsSubscribeCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Subscription, 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 := &GoogleCloudApigeeV1Subscription{
		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": "Creates a subscription for the environment's Pub/Sub topic. The server will assign a random name for this subscription. The \"name\" and \"push_config\" must *not* be specified.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}:subscribe",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.subscribe",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the environment. Use the following structure in your request: `organizations/{org}/environments/{env}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}:subscribe",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Subscription"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.testIamPermissions":

type OrganizationsEnvironmentsTestIamPermissionsCall struct {
	s                                    *Service
	resource                             string
	googleiamv1testiampermissionsrequest *GoogleIamV1TestIamPermissionsRequest
	urlParams_                           gensupport.URLParams
	ctx_                                 context.Context
	header_                              http.Header
}

// TestIamPermissions: Tests the permissions of a user on an
// environment, and returns a subset of permissions that the user has on
// the environment. If the environment does not exist, an empty
// permission set is returned (a NOT_FOUND error is not returned).
func (r *OrganizationsEnvironmentsService) TestIamPermissions(resource string, googleiamv1testiampermissionsrequest *GoogleIamV1TestIamPermissionsRequest) *OrganizationsEnvironmentsTestIamPermissionsCall {
	c := &OrganizationsEnvironmentsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.googleiamv1testiampermissionsrequest = googleiamv1testiampermissionsrequest
	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 *OrganizationsEnvironmentsTestIamPermissionsCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsTestIamPermissionsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsTestIamPermissionsCall) Context(ctx context.Context) *OrganizationsEnvironmentsTestIamPermissionsCall {
	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 *OrganizationsEnvironmentsTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleiamv1testiampermissionsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "apigee.organizations.environments.testIamPermissions" call.
// Exactly one of *GoogleIamV1TestIamPermissionsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleIamV1TestIamPermissionsResponse.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 *OrganizationsEnvironmentsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*GoogleIamV1TestIamPermissionsResponse, 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 := &GoogleIamV1TestIamPermissionsResponse{
		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": "Tests the permissions of a user on an environment, and returns a subset of permissions that the user has on the environment. If the environment does not exist, an empty permission set is returned (a NOT_FOUND error is not returned).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}:testIamPermissions",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.testIamPermissions",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy detail is being requested. See the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resource}:testIamPermissions",
	//   "request": {
	//     "$ref": "GoogleIamV1TestIamPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleIamV1TestIamPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.unsubscribe":

type OrganizationsEnvironmentsUnsubscribeCall struct {
	s                               *Service
	parent                          string
	googlecloudapigeev1subscription *GoogleCloudApigeeV1Subscription
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Unsubscribe: Deletes a subscription for the environment's Pub/Sub
// topic.
func (r *OrganizationsEnvironmentsService) Unsubscribe(parent string, googlecloudapigeev1subscription *GoogleCloudApigeeV1Subscription) *OrganizationsEnvironmentsUnsubscribeCall {
	c := &OrganizationsEnvironmentsUnsubscribeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1subscription = googlecloudapigeev1subscription
	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 *OrganizationsEnvironmentsUnsubscribeCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsUnsubscribeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsUnsubscribeCall) Context(ctx context.Context) *OrganizationsEnvironmentsUnsubscribeCall {
	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 *OrganizationsEnvironmentsUnsubscribeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsUnsubscribeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1subscription)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:unsubscribe")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.unsubscribe" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsEnvironmentsUnsubscribeCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes a subscription for the environment's Pub/Sub topic.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}:unsubscribe",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.unsubscribe",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the environment. Use the following structure in your request: `organizations/{org}/environments/{env}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}:unsubscribe",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Subscription"
	//   },
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.update":

type OrganizationsEnvironmentsUpdateCall struct {
	s                              *Service
	name                           string
	googlecloudapigeev1environment *GoogleCloudApigeeV1Environment
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Update: Updates an existing environment. When updating properties,
// you must pass all existing properties to the API, even if they are
// not being changed. If you omit properties from the payload, the
// properties are removed. To get the current list of properties for the
// environment, use the [Get Environment API](get).
func (r *OrganizationsEnvironmentsService) Update(name string, googlecloudapigeev1environment *GoogleCloudApigeeV1Environment) *OrganizationsEnvironmentsUpdateCall {
	c := &OrganizationsEnvironmentsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1environment = googlecloudapigeev1environment
	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 *OrganizationsEnvironmentsUpdateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsUpdateCall) Context(ctx context.Context) *OrganizationsEnvironmentsUpdateCall {
	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 *OrganizationsEnvironmentsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1environment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.update" call.
// Exactly one of *GoogleCloudApigeeV1Environment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Environment.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 *OrganizationsEnvironmentsUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Environment, 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 := &GoogleCloudApigeeV1Environment{
		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": "Updates an existing environment. When updating properties, you must pass all existing properties to the API, even if they are not being changed. If you omit properties from the payload, the properties are removed. To get the current list of properties for the environment, use the [Get Environment API](get).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.environments.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment. Use the following structure in your request: `organizations/{org}/environments/{env}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Environment"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Environment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.updateDebugmask":

type OrganizationsEnvironmentsUpdateDebugmaskCall struct {
	s                            *Service
	name                         string
	googlecloudapigeev1debugmask *GoogleCloudApigeeV1DebugMask
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// UpdateDebugmask: Updates the debug mask singleton resource for an
// environment.
func (r *OrganizationsEnvironmentsService) UpdateDebugmask(name string, googlecloudapigeev1debugmask *GoogleCloudApigeeV1DebugMask) *OrganizationsEnvironmentsUpdateDebugmaskCall {
	c := &OrganizationsEnvironmentsUpdateDebugmaskCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1debugmask = googlecloudapigeev1debugmask
	return c
}

// ReplaceRepeatedFields sets the optional parameter
// "replaceRepeatedFields": Boolean flag that specifies whether to
// replace existing values in the debug mask when doing an update. Set
// to true to replace existing values. The default behavior is to append
// the values (false).
func (c *OrganizationsEnvironmentsUpdateDebugmaskCall) ReplaceRepeatedFields(replaceRepeatedFields bool) *OrganizationsEnvironmentsUpdateDebugmaskCall {
	c.urlParams_.Set("replaceRepeatedFields", fmt.Sprint(replaceRepeatedFields))
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field debug mask
// to support partial updates.
func (c *OrganizationsEnvironmentsUpdateDebugmaskCall) UpdateMask(updateMask string) *OrganizationsEnvironmentsUpdateDebugmaskCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *OrganizationsEnvironmentsUpdateDebugmaskCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsUpdateDebugmaskCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsUpdateDebugmaskCall) Context(ctx context.Context) *OrganizationsEnvironmentsUpdateDebugmaskCall {
	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 *OrganizationsEnvironmentsUpdateDebugmaskCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsUpdateDebugmaskCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1debugmask)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.updateDebugmask" call.
// Exactly one of *GoogleCloudApigeeV1DebugMask or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DebugMask.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 *OrganizationsEnvironmentsUpdateDebugmaskCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DebugMask, 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 := &GoogleCloudApigeeV1DebugMask{
		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": "Updates the debug mask singleton resource for an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/debugmask",
	//   "httpMethod": "PATCH",
	//   "id": "apigee.organizations.environments.updateDebugmask",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the debug mask.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/debugmask$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "replaceRepeatedFields": {
	//       "description": "Boolean flag that specifies whether to replace existing values in the debug mask when doing an update. Set to true to replace existing values. The default behavior is to append the values (false).",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "updateMask": {
	//       "description": "Field debug mask to support partial updates.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DebugMask"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DebugMask"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.updateEnvironment":

type OrganizationsEnvironmentsUpdateEnvironmentCall struct {
	s                              *Service
	name                           string
	googlecloudapigeev1environment *GoogleCloudApigeeV1Environment
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// UpdateEnvironment: Updates an existing environment. When updating
// properties, you must pass all existing properties to the API, even if
// they are not being changed. If you omit properties from the payload,
// the properties are removed. To get the current list of properties for
// the environment, use the [Get Environment API](get).
func (r *OrganizationsEnvironmentsService) UpdateEnvironment(name string, googlecloudapigeev1environment *GoogleCloudApigeeV1Environment) *OrganizationsEnvironmentsUpdateEnvironmentCall {
	c := &OrganizationsEnvironmentsUpdateEnvironmentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1environment = googlecloudapigeev1environment
	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 *OrganizationsEnvironmentsUpdateEnvironmentCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsUpdateEnvironmentCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsUpdateEnvironmentCall) Context(ctx context.Context) *OrganizationsEnvironmentsUpdateEnvironmentCall {
	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 *OrganizationsEnvironmentsUpdateEnvironmentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsUpdateEnvironmentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1environment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.updateEnvironment" call.
// Exactly one of *GoogleCloudApigeeV1Environment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Environment.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 *OrganizationsEnvironmentsUpdateEnvironmentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Environment, 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 := &GoogleCloudApigeeV1Environment{
		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": "Updates an existing environment. When updating properties, you must pass all existing properties to the API, even if they are not being changed. If you omit properties from the payload, the properties are removed. To get the current list of properties for the environment, use the [Get Environment API](get).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.updateEnvironment",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the environment. Use the following structure in your request: `organizations/{org}/environments/{env}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Environment"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Environment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.analytics.admin.getSchemav2":

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

// GetSchemav2: Get a list of metrics and dimensions which can be used
// for creating analytics queries and reports. Each schema element
// contains the name of the field with its associated type and if it is
// either custom field or standard field.
func (r *OrganizationsEnvironmentsAnalyticsAdminService) GetSchemav2(name string) *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call {
	c := &OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Type sets the optional parameter "type": Required. Type refers to the
// dataset name whose schema needs to be retrieved E.g. type=fact or
// type=agg_cus1
func (c *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call) Type(type_ string) *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call {
	c.urlParams_.Set("type", type_)
	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 *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call {
	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 *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call {
	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 *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call) Context(ctx context.Context) *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call {
	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 *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.analytics.admin.getSchemav2" call.
// Exactly one of *GoogleCloudApigeeV1Schema or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Schema.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 *OrganizationsEnvironmentsAnalyticsAdminGetSchemav2Call) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Schema, 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 := &GoogleCloudApigeeV1Schema{
		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": "Get a list of metrics and dimensions which can be used for creating analytics queries and reports. Each schema element contains the name of the field with its associated type and if it is either custom field or standard field.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/analytics/admin/schemav2",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.analytics.admin.getSchemav2",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The parent organization and environment names. Must be of the form `organizations/{org}/environments/{env}/analytics/admin/schemav2`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/analytics/admin/schemav2$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Required. Type refers to the dataset name whose schema needs to be retrieved E.g. type=fact or type=agg_cus1",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Schema"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.analytics.exports.create":

type OrganizationsEnvironmentsAnalyticsExportsCreateCall struct {
	s                                *Service
	parent                           string
	googlecloudapigeev1exportrequest *GoogleCloudApigeeV1ExportRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// Create: Submit a data export job to be processed in the background.
// If the request is successful, the API returns a 201 status, a URI
// that can be used to retrieve the status of the export job, and the
// `state` value of "enqueued".
func (r *OrganizationsEnvironmentsAnalyticsExportsService) Create(parent string, googlecloudapigeev1exportrequest *GoogleCloudApigeeV1ExportRequest) *OrganizationsEnvironmentsAnalyticsExportsCreateCall {
	c := &OrganizationsEnvironmentsAnalyticsExportsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1exportrequest = googlecloudapigeev1exportrequest
	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 *OrganizationsEnvironmentsAnalyticsExportsCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsAnalyticsExportsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsAnalyticsExportsCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsAnalyticsExportsCreateCall {
	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 *OrganizationsEnvironmentsAnalyticsExportsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsAnalyticsExportsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1exportrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/analytics/exports")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.analytics.exports.create" call.
// Exactly one of *GoogleCloudApigeeV1Export or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Export.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 *OrganizationsEnvironmentsAnalyticsExportsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Export, 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 := &GoogleCloudApigeeV1Export{
		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": "Submit a data export job to be processed in the background. If the request is successful, the API returns a 201 status, a URI that can be used to retrieve the status of the export job, and the `state` value of \"enqueued\".",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/analytics/exports",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.analytics.exports.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Names of the parent organization and environment. Must be of the form `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/analytics/exports",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1ExportRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Export"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.analytics.exports.get":

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

// Get: Gets the details and status of an analytics export job. If the
// export job is still in progress, its `state` is set to "running".
// After the export job has completed successfully, its `state` is set
// to "completed". If the export job fails, its `state` is set to
// `failed`.
func (r *OrganizationsEnvironmentsAnalyticsExportsService) Get(name string) *OrganizationsEnvironmentsAnalyticsExportsGetCall {
	c := &OrganizationsEnvironmentsAnalyticsExportsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsAnalyticsExportsGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsAnalyticsExportsGetCall {
	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 *OrganizationsEnvironmentsAnalyticsExportsGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsAnalyticsExportsGetCall {
	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 *OrganizationsEnvironmentsAnalyticsExportsGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsAnalyticsExportsGetCall {
	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 *OrganizationsEnvironmentsAnalyticsExportsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsAnalyticsExportsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.analytics.exports.get" call.
// Exactly one of *GoogleCloudApigeeV1Export or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Export.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 *OrganizationsEnvironmentsAnalyticsExportsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Export, 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 := &GoogleCloudApigeeV1Export{
		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": "Gets the details and status of an analytics export job. If the export job is still in progress, its `state` is set to \"running\". After the export job has completed successfully, its `state` is set to \"completed\". If the export job fails, its `state` is set to `failed`.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/analytics/exports/{exportsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.analytics.exports.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Resource name of the export to get.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/analytics/exports/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Export"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.analytics.exports.list":

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

// List: Lists the details and status of all analytics export jobs
// belonging to the parent organization and environment.
func (r *OrganizationsEnvironmentsAnalyticsExportsService) List(parent string) *OrganizationsEnvironmentsAnalyticsExportsListCall {
	c := &OrganizationsEnvironmentsAnalyticsExportsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsEnvironmentsAnalyticsExportsListCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsAnalyticsExportsListCall {
	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 *OrganizationsEnvironmentsAnalyticsExportsListCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsAnalyticsExportsListCall {
	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 *OrganizationsEnvironmentsAnalyticsExportsListCall) Context(ctx context.Context) *OrganizationsEnvironmentsAnalyticsExportsListCall {
	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 *OrganizationsEnvironmentsAnalyticsExportsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsAnalyticsExportsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/analytics/exports")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.analytics.exports.list" call.
// Exactly one of *GoogleCloudApigeeV1ListExportsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudApigeeV1ListExportsResponse.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 *OrganizationsEnvironmentsAnalyticsExportsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListExportsResponse, 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 := &GoogleCloudApigeeV1ListExportsResponse{
		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": "Lists the details and status of all analytics export jobs belonging to the parent organization and environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/analytics/exports",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.analytics.exports.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Names of the parent organization and environment. Must be of the form `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/analytics/exports",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListExportsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.deployments.list":

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

// List: Lists all deployments of an API proxy in an environment.
func (r *OrganizationsEnvironmentsApisDeploymentsService) List(parent string) *OrganizationsEnvironmentsApisDeploymentsListCall {
	c := &OrganizationsEnvironmentsApisDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsEnvironmentsApisDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisDeploymentsListCall {
	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 *OrganizationsEnvironmentsApisDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsApisDeploymentsListCall {
	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 *OrganizationsEnvironmentsApisDeploymentsListCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisDeploymentsListCall {
	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 *OrganizationsEnvironmentsApisDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsEnvironmentsApisDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of an API proxy in an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.apis.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name representing an API proxy in an environment in the following format: `organizations/{org}/environments/{env}/apis/{api}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.deploy":

type OrganizationsEnvironmentsApisRevisionsDeployCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Deploy: Deploys a revision of an API proxy. If an API proxy revision
// is currently deployed, to ensure seamless deployment with zero
// downtime set the `override` parameter to `true`. In this case, hybrid
// attempts to deploy the new revision fully before undeploying the
// existing revision. You cannot invoke an API proxy until it has been
// deployed to an environment. After you deploy an API proxy revision,
// you cannot edit it. To edit the API proxy, you must create and deploy
// a new revision.
func (r *OrganizationsEnvironmentsApisRevisionsService) Deploy(name string) *OrganizationsEnvironmentsApisRevisionsDeployCall {
	c := &OrganizationsEnvironmentsApisRevisionsDeployCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Basepath sets the optional parameter "basepath": Base path where the
// API proxy revision should be deployed. Defaults to '/' if not
// provided.
func (c *OrganizationsEnvironmentsApisRevisionsDeployCall) Basepath(basepath string) *OrganizationsEnvironmentsApisRevisionsDeployCall {
	c.urlParams_.Set("basepath", basepath)
	return c
}

// Override sets the optional parameter "override": Flag that specifies
// whether the new deployment replaces other deployed revisions of the
// API proxy in the environment. Set override to true to replace other
// deployed revisions. By default, override is false and the deployment
// is rejected if other revisions of the API proxy are deployed in the
// environment.
func (c *OrganizationsEnvironmentsApisRevisionsDeployCall) Override(override bool) *OrganizationsEnvironmentsApisRevisionsDeployCall {
	c.urlParams_.Set("override", fmt.Sprint(override))
	return c
}

// SequencedRollout sets the optional parameter "sequencedRollout": If
// true, a best-effort attempt will be made to roll out the routing
// rules corresponding to this deployment and the environment changes to
// add this deployment in a safe order. This reduces the risk of
// downtime that could be caused by changing the environment group's
// routing before the new destination for the affected traffic is ready
// to receive it. This should only be necessary if the new deployment
// will be capturing traffic from another environment under a shared
// environment group or if traffic will be rerouted to a different
// environment due to a basepath removal. The GenerateDeployChangeReport
// API may be used to examine routing changes before issuing the
// deployment request, and its response will indicate if a sequenced
// rollout is recommended for the deployment.
func (c *OrganizationsEnvironmentsApisRevisionsDeployCall) SequencedRollout(sequencedRollout bool) *OrganizationsEnvironmentsApisRevisionsDeployCall {
	c.urlParams_.Set("sequencedRollout", fmt.Sprint(sequencedRollout))
	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 *OrganizationsEnvironmentsApisRevisionsDeployCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDeployCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsApisRevisionsDeployCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDeployCall {
	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 *OrganizationsEnvironmentsApisRevisionsDeployCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDeployCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/deployments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.deploy" call.
// Exactly one of *GoogleCloudApigeeV1Deployment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Deployment.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 *OrganizationsEnvironmentsApisRevisionsDeployCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Deployment, 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 := &GoogleCloudApigeeV1Deployment{
		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": "Deploys a revision of an API proxy. If an API proxy revision is currently deployed, to ensure seamless deployment with zero downtime set the `override` parameter to `true`. In this case, hybrid attempts to deploy the new revision fully before undeploying the existing revision. You cannot invoke an API proxy until it has been deployed to an environment. After you deploy an API proxy revision, you cannot edit it. To edit the API proxy, you must create and deploy a new revision. ",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.apis.revisions.deploy",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "basepath": {
	//       "description": "Base path where the API proxy revision should be deployed. Defaults to '/' if not provided.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Name of the API proxy revision deployment in the following format: `organizations/{org}/environments/{env}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "override": {
	//       "description": "Flag that specifies whether the new deployment replaces other deployed revisions of the API proxy in the environment. Set override to true to replace other deployed revisions. By default, override is false and the deployment is rejected if other revisions of the API proxy are deployed in the environment.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "sequencedRollout": {
	//       "description": "If true, a best-effort attempt will be made to roll out the routing rules corresponding to this deployment and the environment changes to add this deployment in a safe order. This reduces the risk of downtime that could be caused by changing the environment group's routing before the new destination for the affected traffic is ready to receive it. This should only be necessary if the new deployment will be capturing traffic from another environment under a shared environment group or if traffic will be rerouted to a different environment due to a basepath removal. The GenerateDeployChangeReport API may be used to examine routing changes before issuing the deployment request, and its response will indicate if a sequenced rollout is recommended for the deployment.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Deployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.getDeployments":

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

// GetDeployments: Gets the deployment of an API proxy revision and
// actual state reported by runtime pods.
func (r *OrganizationsEnvironmentsApisRevisionsService) GetDeployments(name string) *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall {
	c := &OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall {
	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 *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall {
	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 *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall {
	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 *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}/deployments")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.getDeployments" call.
// Exactly one of *GoogleCloudApigeeV1Deployment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Deployment.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 *OrganizationsEnvironmentsApisRevisionsGetDeploymentsCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Deployment, 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 := &GoogleCloudApigeeV1Deployment{
		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": "Gets the deployment of an API proxy revision and actual state reported by runtime pods.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.apis.revisions.getDeployments",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name representing an API proxy revision in an environment in the following format: `organizations/{org}/environments/{env}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Deployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.undeploy":

type OrganizationsEnvironmentsApisRevisionsUndeployCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Undeploy: Undeploys an API proxy revision from an environment.
// Because multiple revisions of the same API proxy can be deployed in
// the same environment if the base paths are different, you must
// specify the revision number of the API proxy.
func (r *OrganizationsEnvironmentsApisRevisionsService) Undeploy(name string) *OrganizationsEnvironmentsApisRevisionsUndeployCall {
	c := &OrganizationsEnvironmentsApisRevisionsUndeployCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// SequencedRollout sets the optional parameter "sequencedRollout": If
// true, a best-effort attempt will be made to remove the environment
// group routing rules corresponding to this deployment before removing
// the deployment from the runtime. This is likely to be a rare use
// case; it is only needed when the intended effect of undeploying this
// proxy is to cause the traffic it currently handles to be rerouted to
// some other existing proxy in the environment group. The
// GenerateUndeployChangeReport API may be used to examine routing
// changes before issuing the undeployment request, and its response
// will indicate if a sequenced rollout is recommended for the
// undeployment.
func (c *OrganizationsEnvironmentsApisRevisionsUndeployCall) SequencedRollout(sequencedRollout bool) *OrganizationsEnvironmentsApisRevisionsUndeployCall {
	c.urlParams_.Set("sequencedRollout", fmt.Sprint(sequencedRollout))
	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 *OrganizationsEnvironmentsApisRevisionsUndeployCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsUndeployCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsApisRevisionsUndeployCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsUndeployCall {
	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 *OrganizationsEnvironmentsApisRevisionsUndeployCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsUndeployCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/deployments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.undeploy" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsEnvironmentsApisRevisionsUndeployCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Undeploys an API proxy revision from an environment. Because multiple revisions of the same API proxy can be deployed in the same environment if the base paths are different, you must specify the revision number of the API proxy.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.apis.revisions.undeploy",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the API proxy revision deployment in the following format: `organizations/{org}/environments/{env}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sequencedRollout": {
	//       "description": "If true, a best-effort attempt will be made to remove the environment group routing rules corresponding to this deployment before removing the deployment from the runtime. This is likely to be a rare use case; it is only needed when the intended effect of undeploying this proxy is to cause the traffic it currently handles to be rerouted to some other existing proxy in the environment group. The GenerateUndeployChangeReport API may be used to examine routing changes before issuing the undeployment request, and its response will indicate if a sequenced rollout is recommended for the undeployment.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.debugsessions.create":

type OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall struct {
	s                               *Service
	parent                          string
	googlecloudapigeev1debugsession *GoogleCloudApigeeV1DebugSession
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Create: Creates a debug session for a deployed API Proxy revision.
func (r *OrganizationsEnvironmentsApisRevisionsDebugsessionsService) Create(parent string, googlecloudapigeev1debugsession *GoogleCloudApigeeV1DebugSession) *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall {
	c := &OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1debugsession = googlecloudapigeev1debugsession
	return c
}

// Timeout sets the optional parameter "timeout": The time in seconds
// after which this DebugSession should end. A timeout specified in
// DebugSession will overwrite this value.
func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall) Timeout(timeout int64) *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall {
	c.urlParams_.Set("timeout", fmt.Sprint(timeout))
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1debugsession)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/debugsessions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.debugsessions.create" call.
// Exactly one of *GoogleCloudApigeeV1DebugSession or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DebugSession.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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DebugSession, 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 := &GoogleCloudApigeeV1DebugSession{
		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": "Creates a debug session for a deployed API Proxy revision.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/debugsessions",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.apis.revisions.debugsessions.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The resource name of the API Proxy revision deployment for which to create the DebugSession. Must be of the form `organizations/{organization}/environments/{environment}/apis/{api}/revisions/{revision}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "timeout": {
	//       "description": "Optional. The time in seconds after which this DebugSession should end. A timeout specified in DebugSession will overwrite this value.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/debugsessions",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1DebugSession"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DebugSession"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.debugsessions.deleteData":

type OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DeleteData: Deletes the data from a debug session. This does not
// cancel the debug session or prevent further data from being collected
// if the session is still active in runtime pods.
func (r *OrganizationsEnvironmentsApisRevisionsDebugsessionsService) DeleteData(name string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall {
	c := &OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/data")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.debugsessions.deleteData" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDeleteDataCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the data from a debug session. This does not cancel the debug session or prevent further data from being collected if the session is still active in runtime pods.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/debugsessions/{debugsessionsId}/data",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.apis.revisions.debugsessions.deleteData",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the debug session to delete. Must be of the form: `organizations/{organization}/environments/{environment}/apis/{api}/revisions/{revision}/debugsessions/{debugsession}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+/debugsessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/data",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.debugsessions.get":

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

// Get: Retrieves a debug session.
func (r *OrganizationsEnvironmentsApisRevisionsDebugsessionsService) Get(name string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall {
	c := &OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.debugsessions.get" call.
// Exactly one of *GoogleCloudApigeeV1DebugSession or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1DebugSession.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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DebugSession, 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 := &GoogleCloudApigeeV1DebugSession{
		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": "Retrieves a debug session.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/debugsessions/{debugsessionsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.apis.revisions.debugsessions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the debug session to retrieve. Must be of the form: `organizations/{organization}/environments/{environment}/apis/{api}/revisions/{revision}/debugsessions/{session}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+/debugsessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DebugSession"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.debugsessions.list":

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

// List: Lists debug sessions that are currently active in the given API
// Proxy revision.
func (r *OrganizationsEnvironmentsApisRevisionsDebugsessionsService) List(parent string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall {
	c := &OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// debug sessions to return. The page size defaults to 25.
func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) PageSize(pageSize int64) *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned from a previous ListDebugSessions call, that you can use to
// retrieve the next page.
func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) PageToken(pageToken string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/debugsessions")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.debugsessions.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDebugSessionsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDebugSessionsResponse.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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDebugSessionsResponse, 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 := &GoogleCloudApigeeV1ListDebugSessionsResponse{
		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": "Lists debug sessions that are currently active in the given API Proxy revision.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/debugsessions",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.apis.revisions.debugsessions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum number of debug sessions to return. The page size defaults to 25.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned from a previous ListDebugSessions call, that you can use to retrieve the next page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The name of the API Proxy revision deployment for which to list debug sessions. Must be of the form: `organizations/{organization}/environments/{environment}/apis/{api}/revisions/{revision}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/debugsessions",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDebugSessionsResponse"
	//   },
	//   "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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsListCall) Pages(ctx context.Context, f func(*GoogleCloudApigeeV1ListDebugSessionsResponse) 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 "apigee.organizations.environments.apis.revisions.debugsessions.data.get":

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

// Get: Gets the debug data from a transaction.
func (r *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataService) Get(name string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall {
	c := &OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall {
	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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.debugsessions.data.get" call.
// Exactly one of *GoogleCloudApigeeV1DebugSessionTransaction or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1DebugSessionTransaction.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 *OrganizationsEnvironmentsApisRevisionsDebugsessionsDataGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DebugSessionTransaction, 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 := &GoogleCloudApigeeV1DebugSessionTransaction{
		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": "Gets the debug data from a transaction.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/debugsessions/{debugsessionsId}/data/{dataId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.apis.revisions.debugsessions.data.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the debug session transaction. Must be of the form: `organizations/{organization}/environments/{environment}/apis/{api}/revisions/{revision}/debugsessions/{session}/data/{transaction}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+/debugsessions/[^/]+/data/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DebugSessionTransaction"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.deployments.generateDeployChangeReport":

type OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// GenerateDeployChangeReport: Generates a report for a dry run analysis
// of a DeployApiProxy request without committing the deployment. In
// addition to the standard validations performed when adding
// deployments, additional analysis will be done to detect possible
// traffic routing changes that would result from this deployment being
// created. Any potential routing conflicts or unsafe changes will be
// reported in the response. This routing analysis is not performed for
// a non-dry-run DeployApiProxy request.
func (r *OrganizationsEnvironmentsApisRevisionsDeploymentsService) GenerateDeployChangeReport(name string) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall {
	c := &OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Basepath sets the optional parameter "basepath": Base path where the
// API proxy revision should be deployed. Defaults to '/' if not
// provided.
func (c *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall) Basepath(basepath string) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall {
	c.urlParams_.Set("basepath", basepath)
	return c
}

// Override sets the optional parameter "override": Flag that specifies
// whether to force the deployment of the new revision over the
// currently deployed revision by overriding conflict checks.
func (c *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall) Override(override bool) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall {
	c.urlParams_.Set("override", fmt.Sprint(override))
	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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall {
	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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/deployments:generateDeployChangeReport")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.deployments.generateDeployChangeReport" call.
// Exactly one of *GoogleCloudApigeeV1DeploymentChangeReport or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1DeploymentChangeReport.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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateDeployChangeReportCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeploymentChangeReport, 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 := &GoogleCloudApigeeV1DeploymentChangeReport{
		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": "Generates a report for a dry run analysis of a DeployApiProxy request without committing the deployment. In addition to the standard validations performed when adding deployments, additional analysis will be done to detect possible traffic routing changes that would result from this deployment being created. Any potential routing conflicts or unsafe changes will be reported in the response. This routing analysis is not performed for a non-dry-run DeployApiProxy request.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/deployments:generateDeployChangeReport",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.apis.revisions.deployments.generateDeployChangeReport",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "basepath": {
	//       "description": "Base path where the API proxy revision should be deployed. Defaults to '/' if not provided.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Name of the API proxy revision deployment in the following format: `organizations/{org}/environments/{env}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "override": {
	//       "description": "Flag that specifies whether to force the deployment of the new revision over the currently deployed revision by overriding conflict checks.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments:generateDeployChangeReport",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeploymentChangeReport"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.apis.revisions.deployments.generateUndeployChangeReport":

type OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// GenerateUndeployChangeReport: Generates a report for a dry run
// analysis of an UndeployApiProxy request without committing the
// undeploy. In addition to the standard validations performed when
// removing deployments, additional analysis will be done to detect
// possible traffic routing changes that would result from this
// deployment being removed. Any potential routing conflicts or unsafe
// changes will be reported in the response. This routing analysis is
// not performed for a non-dry-run UndeployApiProxy request.
func (r *OrganizationsEnvironmentsApisRevisionsDeploymentsService) GenerateUndeployChangeReport(name string) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall {
	c := &OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall) Context(ctx context.Context) *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall {
	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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/deployments:generateUndeployChangeReport")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.apis.revisions.deployments.generateUndeployChangeReport" call.
// Exactly one of *GoogleCloudApigeeV1DeploymentChangeReport or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1DeploymentChangeReport.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 *OrganizationsEnvironmentsApisRevisionsDeploymentsGenerateUndeployChangeReportCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeploymentChangeReport, 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 := &GoogleCloudApigeeV1DeploymentChangeReport{
		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": "Generates a report for a dry run analysis of an UndeployApiProxy request without committing the undeploy. In addition to the standard validations performed when removing deployments, additional analysis will be done to detect possible traffic routing changes that would result from this deployment being removed. Any potential routing conflicts or unsafe changes will be reported in the response. This routing analysis is not performed for a non-dry-run UndeployApiProxy request.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/apis/{apisId}/revisions/{revisionsId}/deployments:generateUndeployChangeReport",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.apis.revisions.deployments.generateUndeployChangeReport",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the API proxy revision deployment in the following format: `organizations/{org}/environments/{env}/apis/{api}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/apis/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments:generateUndeployChangeReport",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeploymentChangeReport"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.caches.delete":

type OrganizationsEnvironmentsCachesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a cache.
func (r *OrganizationsEnvironmentsCachesService) Delete(name string) *OrganizationsEnvironmentsCachesDeleteCall {
	c := &OrganizationsEnvironmentsCachesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsCachesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsCachesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsCachesDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsCachesDeleteCall {
	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 *OrganizationsEnvironmentsCachesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsCachesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.caches.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsEnvironmentsCachesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes a cache.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/caches/{cachesId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.caches.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Cache resource name of the form: `organizations/{organization_id}/environments/{environment_id}/caches/{cache_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/caches/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.deployments.list":

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

// List: Lists all deployments of API proxies or shared flows in an
// environment.
func (r *OrganizationsEnvironmentsDeploymentsService) List(parent string) *OrganizationsEnvironmentsDeploymentsListCall {
	c := &OrganizationsEnvironmentsDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// SharedFlows sets the optional parameter "sharedFlows": Flag that
// specifies whether to return shared flow or API proxy deployments. Set
// to `true` to return shared flow deployments; set to `false` to return
// API proxy deployments. Defaults to `false`.
func (c *OrganizationsEnvironmentsDeploymentsListCall) SharedFlows(sharedFlows bool) *OrganizationsEnvironmentsDeploymentsListCall {
	c.urlParams_.Set("sharedFlows", fmt.Sprint(sharedFlows))
	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 *OrganizationsEnvironmentsDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsDeploymentsListCall {
	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 *OrganizationsEnvironmentsDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsDeploymentsListCall {
	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 *OrganizationsEnvironmentsDeploymentsListCall) Context(ctx context.Context) *OrganizationsEnvironmentsDeploymentsListCall {
	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 *OrganizationsEnvironmentsDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsEnvironmentsDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of API proxies or shared flows in an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the environment for which to return deployment information in the following format: `organizations/{org}/environments/{env}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sharedFlows": {
	//       "description": "Optional. Flag that specifies whether to return shared flow or API proxy deployments. Set to `true` to return shared flow deployments; set to `false` to return API proxy deployments. Defaults to `false`.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.flowhooks.attachSharedFlowToFlowHook":

type OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall struct {
	s                           *Service
	name                        string
	googlecloudapigeev1flowhook *GoogleCloudApigeeV1FlowHook
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// AttachSharedFlowToFlowHook: Attaches a shared flow to a flow hook.
func (r *OrganizationsEnvironmentsFlowhooksService) AttachSharedFlowToFlowHook(name string, googlecloudapigeev1flowhook *GoogleCloudApigeeV1FlowHook) *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall {
	c := &OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1flowhook = googlecloudapigeev1flowhook
	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 *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall) Context(ctx context.Context) *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall {
	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 *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1flowhook)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.flowhooks.attachSharedFlowToFlowHook" call.
// Exactly one of *GoogleCloudApigeeV1FlowHook or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1FlowHook.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 *OrganizationsEnvironmentsFlowhooksAttachSharedFlowToFlowHookCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1FlowHook, 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 := &GoogleCloudApigeeV1FlowHook{
		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": "Attaches a shared flow to a flow hook.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/flowhooks/{flowhooksId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.environments.flowhooks.attachSharedFlowToFlowHook",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the flow hook to which the shared flow should be attached in the following format: `organizations/{org}/environments/{env}/flowhooks/{flowhook}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/flowhooks/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1FlowHook"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1FlowHook"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.flowhooks.detachSharedFlowFromFlowHook":

type OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DetachSharedFlowFromFlowHook: Detaches a shared flow from a flow
// hook.
func (r *OrganizationsEnvironmentsFlowhooksService) DetachSharedFlowFromFlowHook(name string) *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall {
	c := &OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall) Context(ctx context.Context) *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall {
	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 *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.flowhooks.detachSharedFlowFromFlowHook" call.
// Exactly one of *GoogleCloudApigeeV1FlowHook or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1FlowHook.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 *OrganizationsEnvironmentsFlowhooksDetachSharedFlowFromFlowHookCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1FlowHook, 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 := &GoogleCloudApigeeV1FlowHook{
		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": "Detaches a shared flow from a flow hook.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/flowhooks/{flowhooksId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.flowhooks.detachSharedFlowFromFlowHook",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the flow hook to detach in the following format: `organizations/{org}/environments/{env}/flowhooks/{flowhook}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/flowhooks/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1FlowHook"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.flowhooks.get":

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

// Get: Returns the name of the shared flow attached to the specified
// flow hook. If there's no shared flow attached to the flow hook, the
// API does not return an error; it simply does not return a name in the
// response.
func (r *OrganizationsEnvironmentsFlowhooksService) Get(name string) *OrganizationsEnvironmentsFlowhooksGetCall {
	c := &OrganizationsEnvironmentsFlowhooksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsFlowhooksGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsFlowhooksGetCall {
	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 *OrganizationsEnvironmentsFlowhooksGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsFlowhooksGetCall {
	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 *OrganizationsEnvironmentsFlowhooksGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsFlowhooksGetCall {
	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 *OrganizationsEnvironmentsFlowhooksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsFlowhooksGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.flowhooks.get" call.
// Exactly one of *GoogleCloudApigeeV1FlowHook or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1FlowHook.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 *OrganizationsEnvironmentsFlowhooksGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1FlowHook, 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 := &GoogleCloudApigeeV1FlowHook{
		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": "Returns the name of the shared flow attached to the specified flow hook. If there's no shared flow attached to the flow hook, the API does not return an error; it simply does not return a name in the response.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/flowhooks/{flowhooksId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.flowhooks.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the flow hook in the following format: `organizations/{org}/environments/{env}/flowhooks/{flowhook}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/flowhooks/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1FlowHook"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.create":

type OrganizationsEnvironmentsKeystoresCreateCall struct {
	s                           *Service
	parent                      string
	googlecloudapigeev1keystore *GoogleCloudApigeeV1Keystore
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// Create: Creates a keystore or truststore: * Keystore: Contains
// certificates and their associated keys. * Truststore: Contains
// trusted certificates used to validate a server's certificate. These
// certificates are typically self-signed certificates or certificates
// that are not signed by a trusted CA.
func (r *OrganizationsEnvironmentsKeystoresService) Create(parent string, googlecloudapigeev1keystore *GoogleCloudApigeeV1Keystore) *OrganizationsEnvironmentsKeystoresCreateCall {
	c := &OrganizationsEnvironmentsKeystoresCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1keystore = googlecloudapigeev1keystore
	return c
}

// Name sets the optional parameter "name": Overrides the value in
// Keystore.
func (c *OrganizationsEnvironmentsKeystoresCreateCall) Name(name string) *OrganizationsEnvironmentsKeystoresCreateCall {
	c.urlParams_.Set("name", name)
	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 *OrganizationsEnvironmentsKeystoresCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsKeystoresCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresCreateCall {
	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 *OrganizationsEnvironmentsKeystoresCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1keystore)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/keystores")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.create" call.
// Exactly one of *GoogleCloudApigeeV1Keystore or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Keystore.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 *OrganizationsEnvironmentsKeystoresCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Keystore, 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 := &GoogleCloudApigeeV1Keystore{
		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": "Creates a keystore or truststore: * Keystore: Contains certificates and their associated keys. * Truststore: Contains trusted certificates used to validate a server's certificate. These certificates are typically self-signed certificates or certificates that are not signed by a trusted CA.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.keystores.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Optional. Overrides the value in Keystore.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The name of the environment in which to create the keystore. Must be of the form `organizations/{organization}/environments/{environment}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/keystores",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Keystore"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Keystore"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.delete":

type OrganizationsEnvironmentsKeystoresDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a keystore or truststore.
func (r *OrganizationsEnvironmentsKeystoresService) Delete(name string) *OrganizationsEnvironmentsKeystoresDeleteCall {
	c := &OrganizationsEnvironmentsKeystoresDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsKeystoresDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsKeystoresDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresDeleteCall {
	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 *OrganizationsEnvironmentsKeystoresDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.delete" call.
// Exactly one of *GoogleCloudApigeeV1Keystore or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Keystore.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 *OrganizationsEnvironmentsKeystoresDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Keystore, 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 := &GoogleCloudApigeeV1Keystore{
		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": "Deletes a keystore or truststore.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.keystores.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of keystore to delete. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Keystore"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.get":

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

// Get: Gets a keystore or truststore.
func (r *OrganizationsEnvironmentsKeystoresService) Get(name string) *OrganizationsEnvironmentsKeystoresGetCall {
	c := &OrganizationsEnvironmentsKeystoresGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsKeystoresGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresGetCall {
	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 *OrganizationsEnvironmentsKeystoresGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsKeystoresGetCall {
	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 *OrganizationsEnvironmentsKeystoresGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresGetCall {
	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 *OrganizationsEnvironmentsKeystoresGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.get" call.
// Exactly one of *GoogleCloudApigeeV1Keystore or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Keystore.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 *OrganizationsEnvironmentsKeystoresGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Keystore, 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 := &GoogleCloudApigeeV1Keystore{
		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": "Gets a keystore or truststore.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.keystores.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of keystore. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Keystore"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.aliases.create":

type OrganizationsEnvironmentsKeystoresAliasesCreateCall struct {
	s                 *Service
	parent            string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates an alias from a key, certificate pair. The structure
// of the request is controlled by the `format` query parameter: *
// `keycertfile` - Separate PEM-encoded key and certificate files are
// uploaded. The request must have `Content-Type: multipart/form-data`
// and include fields `keyFile` and `certFile`. If uploading to a
// truststore, omit `keyFile`. * `pkcs12` - A PKCS12 file is uploaded.
// The request must have `Content-Type: multipart/form-data` with the
// file provided in the only field. * `selfsignedcert` - A new private
// key and certificate are generated. The request must have
// `Content-Type: application/json` and a body of
// CertificateGenerationSpec.
func (r *OrganizationsEnvironmentsKeystoresAliasesService) Create(parent string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	c := &OrganizationsEnvironmentsKeystoresAliasesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleapihttpbody = googleapihttpbody
	return c
}

// Password sets the optional parameter "_password": The password for
// the private key file, if it exists.
func (c *OrganizationsEnvironmentsKeystoresAliasesCreateCall) Password(Password string) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	c.urlParams_.Set("_password", Password)
	return c
}

// Alias sets the optional parameter "alias": The alias for the key,
// certificate pair. Values must match regular expression
// `[\w\s-.]{1,255}`. This must be provided for all formats except
// 'selfsignedcert'; self-signed certs may specify the alias in either
// this parameter or the JSON body.
func (c *OrganizationsEnvironmentsKeystoresAliasesCreateCall) Alias(alias string) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	c.urlParams_.Set("alias", alias)
	return c
}

// Format sets the optional parameter "format": Required. The format of
// the data. Must be either `selfsignedcert`, `keycertfile`, or
// `pkcs12`.
func (c *OrganizationsEnvironmentsKeystoresAliasesCreateCall) Format(format string) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	c.urlParams_.Set("format", format)
	return c
}

// IgnoreExpiryValidation sets the optional parameter
// "ignoreExpiryValidation": If `true`, no expiry validation will be
// performed.
func (c *OrganizationsEnvironmentsKeystoresAliasesCreateCall) IgnoreExpiryValidation(ignoreExpiryValidation bool) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	c.urlParams_.Set("ignoreExpiryValidation", fmt.Sprint(ignoreExpiryValidation))
	return c
}

// IgnoreNewlineValidation sets the optional parameter
// "ignoreNewlineValidation": If `true`, do not throw an error when the
// file contains a chain with no newline between each certificate. By
// default, a newline is needed between each certificate in a chain.
func (c *OrganizationsEnvironmentsKeystoresAliasesCreateCall) IgnoreNewlineValidation(ignoreNewlineValidation bool) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	c.urlParams_.Set("ignoreNewlineValidation", fmt.Sprint(ignoreNewlineValidation))
	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 *OrganizationsEnvironmentsKeystoresAliasesCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsKeystoresAliasesCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresAliasesCreateCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresAliasesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/aliases")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.aliases.create" call.
// Exactly one of *GoogleCloudApigeeV1Alias or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Alias.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 *OrganizationsEnvironmentsKeystoresAliasesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Alias, 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 := &GoogleCloudApigeeV1Alias{
		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": "Creates an alias from a key, certificate pair. The structure of the request is controlled by the `format` query parameter: * `keycertfile` - Separate PEM-encoded key and certificate files are uploaded. The request must have `Content-Type: multipart/form-data` and include fields `keyFile` and `certFile`. If uploading to a truststore, omit `keyFile`. * `pkcs12` - A PKCS12 file is uploaded. The request must have `Content-Type: multipart/form-data` with the file provided in the only field. * `selfsignedcert` - A new private key and certificate are generated. The request must have `Content-Type: application/json` and a body of CertificateGenerationSpec.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}/aliases",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.keystores.aliases.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "_password": {
	//       "description": "The password for the private key file, if it exists.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "alias": {
	//       "description": "The alias for the key, certificate pair. Values must match regular expression `[\\w\\s-.]{1,255}`. This must be provided for all formats except 'selfsignedcert'; self-signed certs may specify the alias in either this parameter or the JSON body.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "format": {
	//       "description": "Required. The format of the data. Must be either `selfsignedcert`, `keycertfile`, or `pkcs12`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ignoreExpiryValidation": {
	//       "description": "If `true`, no expiry validation will be performed.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ignoreNewlineValidation": {
	//       "description": "If `true`, do not throw an error when the file contains a chain with no newline between each certificate. By default, a newline is needed between each certificate in a chain.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. The name of the keystore. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/aliases",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Alias"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.aliases.csr":

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

// Csr: Generates a PKCS #10 Certificate Signing Request for the private
// key in an alias.
func (r *OrganizationsEnvironmentsKeystoresAliasesService) Csr(name string) *OrganizationsEnvironmentsKeystoresAliasesCsrCall {
	c := &OrganizationsEnvironmentsKeystoresAliasesCsrCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsKeystoresAliasesCsrCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresAliasesCsrCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesCsrCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsKeystoresAliasesCsrCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesCsrCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresAliasesCsrCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesCsrCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresAliasesCsrCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}/csr")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.aliases.csr" call.
// Exactly one of *GoogleApiHttpBody or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleApiHttpBody.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 *OrganizationsEnvironmentsKeystoresAliasesCsrCall) Do(opts ...googleapi.CallOption) (*GoogleApiHttpBody, 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 := &GoogleApiHttpBody{
		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": "Generates a PKCS #10 Certificate Signing Request for the private key in an alias.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}/aliases/{aliasesId}/csr",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.keystores.aliases.csr",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the alias. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}/aliases/{alias}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+/aliases/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/csr",
	//   "response": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.aliases.delete":

type OrganizationsEnvironmentsKeystoresAliasesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an alias.
func (r *OrganizationsEnvironmentsKeystoresAliasesService) Delete(name string) *OrganizationsEnvironmentsKeystoresAliasesDeleteCall {
	c := &OrganizationsEnvironmentsKeystoresAliasesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsKeystoresAliasesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresAliasesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsKeystoresAliasesDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresAliasesDeleteCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresAliasesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.aliases.delete" call.
// Exactly one of *GoogleCloudApigeeV1Alias or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Alias.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 *OrganizationsEnvironmentsKeystoresAliasesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Alias, 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 := &GoogleCloudApigeeV1Alias{
		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": "Deletes an alias.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}/aliases/{aliasesId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.keystores.aliases.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the alias. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}/aliases/{alias}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+/aliases/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Alias"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.aliases.get":

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

// Get: Gets an alias.
func (r *OrganizationsEnvironmentsKeystoresAliasesService) Get(name string) *OrganizationsEnvironmentsKeystoresAliasesGetCall {
	c := &OrganizationsEnvironmentsKeystoresAliasesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresAliasesGetCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsKeystoresAliasesGetCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresAliasesGetCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresAliasesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.aliases.get" call.
// Exactly one of *GoogleCloudApigeeV1Alias or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Alias.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 *OrganizationsEnvironmentsKeystoresAliasesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Alias, 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 := &GoogleCloudApigeeV1Alias{
		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": "Gets an alias.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}/aliases/{aliasesId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.keystores.aliases.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the alias. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}/aliases/{alias}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+/aliases/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Alias"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.aliases.getCertificate":

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

// GetCertificate: Gets the certificate from an alias in PEM-encoded
// form.
func (r *OrganizationsEnvironmentsKeystoresAliasesService) GetCertificate(name string) *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall {
	c := &OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}/certificate")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.aliases.getCertificate" call.
// Exactly one of *GoogleApiHttpBody or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleApiHttpBody.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 *OrganizationsEnvironmentsKeystoresAliasesGetCertificateCall) Do(opts ...googleapi.CallOption) (*GoogleApiHttpBody, 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 := &GoogleApiHttpBody{
		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": "Gets the certificate from an alias in PEM-encoded form.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}/aliases/{aliasesId}/certificate",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.keystores.aliases.getCertificate",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the alias. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}/aliases/{alias}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+/aliases/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/certificate",
	//   "response": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keystores.aliases.update":

type OrganizationsEnvironmentsKeystoresAliasesUpdateCall struct {
	s                 *Service
	name              string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Update: Updates the certificate in an alias.
func (r *OrganizationsEnvironmentsKeystoresAliasesService) Update(name string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsEnvironmentsKeystoresAliasesUpdateCall {
	c := &OrganizationsEnvironmentsKeystoresAliasesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googleapihttpbody = googleapihttpbody
	return c
}

// IgnoreExpiryValidation sets the optional parameter
// "ignoreExpiryValidation": Required. If `true`, no expiry validation
// will be performed.
func (c *OrganizationsEnvironmentsKeystoresAliasesUpdateCall) IgnoreExpiryValidation(ignoreExpiryValidation bool) *OrganizationsEnvironmentsKeystoresAliasesUpdateCall {
	c.urlParams_.Set("ignoreExpiryValidation", fmt.Sprint(ignoreExpiryValidation))
	return c
}

// IgnoreNewlineValidation sets the optional parameter
// "ignoreNewlineValidation": If `true`, do not throw an error when the
// file contains a chain with no newline between each certificate. By
// default, a newline is needed between each certificate in a chain.
func (c *OrganizationsEnvironmentsKeystoresAliasesUpdateCall) IgnoreNewlineValidation(ignoreNewlineValidation bool) *OrganizationsEnvironmentsKeystoresAliasesUpdateCall {
	c.urlParams_.Set("ignoreNewlineValidation", fmt.Sprint(ignoreNewlineValidation))
	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 *OrganizationsEnvironmentsKeystoresAliasesUpdateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeystoresAliasesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsKeystoresAliasesUpdateCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeystoresAliasesUpdateCall {
	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 *OrganizationsEnvironmentsKeystoresAliasesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeystoresAliasesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keystores.aliases.update" call.
// Exactly one of *GoogleCloudApigeeV1Alias or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Alias.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 *OrganizationsEnvironmentsKeystoresAliasesUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Alias, 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 := &GoogleCloudApigeeV1Alias{
		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": "Updates the certificate in an alias.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keystores/{keystoresId}/aliases/{aliasesId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.environments.keystores.aliases.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "ignoreExpiryValidation": {
	//       "description": "Required. If `true`, no expiry validation will be performed.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ignoreNewlineValidation": {
	//       "description": "If `true`, do not throw an error when the file contains a chain with no newline between each certificate. By default, a newline is needed between each certificate in a chain.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Required. The name of the alias. Must be of the form `organizations/{organization}/environments/{environment}/keystores/{keystore}/aliases/{alias}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keystores/[^/]+/aliases/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Alias"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keyvaluemaps.create":

type OrganizationsEnvironmentsKeyvaluemapsCreateCall struct {
	s                              *Service
	parent                         string
	googlecloudapigeev1keyvaluemap *GoogleCloudApigeeV1KeyValueMap
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Create: Creates a key value map in an environment.
func (r *OrganizationsEnvironmentsKeyvaluemapsService) Create(parent string, googlecloudapigeev1keyvaluemap *GoogleCloudApigeeV1KeyValueMap) *OrganizationsEnvironmentsKeyvaluemapsCreateCall {
	c := &OrganizationsEnvironmentsKeyvaluemapsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1keyvaluemap = googlecloudapigeev1keyvaluemap
	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 *OrganizationsEnvironmentsKeyvaluemapsCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeyvaluemapsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsKeyvaluemapsCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeyvaluemapsCreateCall {
	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 *OrganizationsEnvironmentsKeyvaluemapsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeyvaluemapsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1keyvaluemap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/keyvaluemaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keyvaluemaps.create" call.
// Exactly one of *GoogleCloudApigeeV1KeyValueMap or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1KeyValueMap.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 *OrganizationsEnvironmentsKeyvaluemapsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1KeyValueMap, 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 := &GoogleCloudApigeeV1KeyValueMap{
		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": "Creates a key value map in an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keyvaluemaps",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.keyvaluemaps.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the environment in which to create the key value map. Must be of the form `organizations/{organization}/environments/{environment}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/keyvaluemaps",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.keyvaluemaps.delete":

type OrganizationsEnvironmentsKeyvaluemapsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Delete a key value map in an environment.
func (r *OrganizationsEnvironmentsKeyvaluemapsService) Delete(name string) *OrganizationsEnvironmentsKeyvaluemapsDeleteCall {
	c := &OrganizationsEnvironmentsKeyvaluemapsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsKeyvaluemapsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsKeyvaluemapsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsKeyvaluemapsDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsKeyvaluemapsDeleteCall {
	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 *OrganizationsEnvironmentsKeyvaluemapsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsKeyvaluemapsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.keyvaluemaps.delete" call.
// Exactly one of *GoogleCloudApigeeV1KeyValueMap or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1KeyValueMap.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 *OrganizationsEnvironmentsKeyvaluemapsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1KeyValueMap, 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 := &GoogleCloudApigeeV1KeyValueMap{
		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": "Delete a key value map in an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/keyvaluemaps/{keyvaluemapsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.keyvaluemaps.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the key value map. Must be of the form `organizations/{organization}/environments/{environment}/keyvaluemaps/{keyvaluemap}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/keyvaluemaps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.optimizedStats.get":

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

// Get: This api is similar to GetStats except that the response is less
// verbose. In the current scheme, a query parameter _optimized
// instructs Edge Analytics to change the response but since this
// behavior is not possible with protocol buffer and since this
// parameter is predominantly used by Edge UI, we are introducing a
// separate api.
func (r *OrganizationsEnvironmentsOptimizedStatsService) Get(name string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c := &OrganizationsEnvironmentsOptimizedStatsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Accuracy sets the optional parameter "accuracy": Legacy field: not
// used anymore.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Accuracy(accuracy string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("accuracy", accuracy)
	return c
}

// AggTable sets the optional parameter "aggTable": If customers want to
// query custom aggregate tables, then this parameter can be used to
// specify the table name. If this parameter is skipped, then Edge Query
// will try to retrieve the data from fact tables which will be
// expensive.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) AggTable(aggTable string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("aggTable", aggTable)
	return c
}

// Filter sets the optional parameter "filter": Enables drill-down on
// specific dimension values.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Filter(filter string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// Limit sets the optional parameter "limit": This parameter is used to
// limit the number of result items. Default and the max value is 14400.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Limit(limit string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("limit", limit)
	return c
}

// Offset sets the optional parameter "offset": Use offset with limit to
// enable pagination of results. For example, to display results 11-20,
// set limit to '10' and offset to '10'.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Offset(offset string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("offset", offset)
	return c
}

// Realtime sets the optional parameter "realtime": Legacy field: not
// used anymore.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Realtime(realtime bool) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("realtime", fmt.Sprint(realtime))
	return c
}

// Select sets the optional parameter "select": Required. The select
// parameter contains a comma separated list of metrics. E.g.
// sum(message_count),sum(error_count)
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Select(select_ string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("select", select_)
	return c
}

// Sonar sets the optional parameter "sonar": This parameter routes the
// query to api monitoring service for last hour.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Sonar(sonar bool) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("sonar", fmt.Sprint(sonar))
	return c
}

// Sort sets the optional parameter "sort": This parameter specifies if
// the sort order should be ascending or descending Supported values are
// DESC and ASC.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Sort(sort string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("sort", sort)
	return c
}

// Sortby sets the optional parameter "sortby": Comma separated list of
// columns to sort the final result.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Sortby(sortby string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("sortby", sortby)
	return c
}

// TimeRange sets the optional parameter "timeRange": Required. Time
// interval for the interactive query. Time range is specified as
// start~end E.g. 04/15/2017 00:00~05/15/2017 23:59
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) TimeRange(timeRange string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("timeRange", timeRange)
	return c
}

// TimeUnit sets the optional parameter "timeUnit": A value of second,
// minute, hour, day, week, month. Time Unit specifies the granularity
// of metrics returned.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) TimeUnit(timeUnit string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("timeUnit", timeUnit)
	return c
}

// Topk sets the optional parameter "topk": Take 'top k' results from
// results, for example, to return the top 5 results 'topk=5'.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Topk(topk string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("topk", topk)
	return c
}

// TsAscending sets the optional parameter "tsAscending": Lists
// timestamps in ascending order if set to true. Recommend setting this
// value to true if you are using sortby with sort=DESC.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) TsAscending(tsAscending bool) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("tsAscending", fmt.Sprint(tsAscending))
	return c
}

// Tzo sets the optional parameter "tzo": This parameters contains the
// timezone offset value.
func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) Tzo(tzo string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	c.urlParams_.Set("tzo", tzo)
	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 *OrganizationsEnvironmentsOptimizedStatsGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	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 *OrganizationsEnvironmentsOptimizedStatsGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	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 *OrganizationsEnvironmentsOptimizedStatsGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsOptimizedStatsGetCall {
	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 *OrganizationsEnvironmentsOptimizedStatsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsOptimizedStatsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.optimizedStats.get" call.
// Exactly one of *GoogleCloudApigeeV1OptimizedStats or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1OptimizedStats.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 *OrganizationsEnvironmentsOptimizedStatsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1OptimizedStats, 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 := &GoogleCloudApigeeV1OptimizedStats{
		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": "This api is similar to GetStats except that the response is less verbose. In the current scheme, a query parameter _optimized instructs Edge Analytics to change the response but since this behavior is not possible with protocol buffer and since this parameter is predominantly used by Edge UI, we are introducing a separate api.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/optimizedStats/{optimizedStatsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.optimizedStats.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "accuracy": {
	//       "description": "Legacy field: not used anymore.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "aggTable": {
	//       "description": "If customers want to query custom aggregate tables, then this parameter can be used to specify the table name. If this parameter is skipped, then Edge Query will try to retrieve the data from fact tables which will be expensive.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Enables drill-down on specific dimension values.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "This parameter is used to limit the number of result items. Default and the max value is 14400.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The resource name for which the interactive query will be executed. Must be of the form `organizations/{organization_id}/environments/{environment_id/stats/{dimensions}` Dimensions let you view metrics in meaningful groupings. E.g. apiproxy, target_host. The value of dimensions should be comma separated list as shown below `organizations/{org}/environments/{env}/stats/apiproxy,request_verb`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/optimizedStats/.*$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "offset": {
	//       "description": "Use offset with limit to enable pagination of results. For example, to display results 11-20, set limit to '10' and offset to '10'.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "realtime": {
	//       "description": "Legacy field: not used anymore.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "select": {
	//       "description": "Required. The select parameter contains a comma separated list of metrics. E.g. sum(message_count),sum(error_count)",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sonar": {
	//       "description": "This parameter routes the query to api monitoring service for last hour.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "sort": {
	//       "description": "This parameter specifies if the sort order should be ascending or descending Supported values are DESC and ASC.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortby": {
	//       "description": "Comma separated list of columns to sort the final result.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timeRange": {
	//       "description": "Required. Time interval for the interactive query. Time range is specified as start~end E.g. 04/15/2017 00:00~05/15/2017 23:59",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timeUnit": {
	//       "description": "A value of second, minute, hour, day, week, month. Time Unit specifies the granularity of metrics returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "topk": {
	//       "description": "Take 'top k' results from results, for example, to return the top 5 results 'topk=5'.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tsAscending": {
	//       "description": "Lists timestamps in ascending order if set to true. Recommend setting this value to true if you are using sortby with sort=DESC.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "tzo": {
	//       "description": "This parameters contains the timezone offset value.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1OptimizedStats"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.queries.create":

type OrganizationsEnvironmentsQueriesCreateCall struct {
	s                        *Service
	parent                   string
	googlecloudapigeev1query *GoogleCloudApigeeV1Query
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// Create: Submit a query to be processed in the background. If the
// submission of the query succeeds, the API returns a 201 status and an
// ID that refer to the query. In addition to the HTTP status 201, the
// `state` of "enqueued" means that the request succeeded.
func (r *OrganizationsEnvironmentsQueriesService) Create(parent string, googlecloudapigeev1query *GoogleCloudApigeeV1Query) *OrganizationsEnvironmentsQueriesCreateCall {
	c := &OrganizationsEnvironmentsQueriesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1query = googlecloudapigeev1query
	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 *OrganizationsEnvironmentsQueriesCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsQueriesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsQueriesCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsQueriesCreateCall {
	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 *OrganizationsEnvironmentsQueriesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsQueriesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1query)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/queries")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.queries.create" call.
// Exactly one of *GoogleCloudApigeeV1AsyncQuery or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1AsyncQuery.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 *OrganizationsEnvironmentsQueriesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1AsyncQuery, 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 := &GoogleCloudApigeeV1AsyncQuery{
		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": "Submit a query to be processed in the background. If the submission of the query succeeds, the API returns a 201 status and an ID that refer to the query. In addition to the HTTP status 201, the `state` of \"enqueued\" means that the request succeeded.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/queries",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.queries.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent resource name. Must be of the form `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/queries",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Query"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1AsyncQuery"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.queries.get":

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

// Get: Get query status If the query is still in progress, the `state`
// is set to "running" After the query has completed successfully,
// `state` is set to "completed"
func (r *OrganizationsEnvironmentsQueriesService) Get(name string) *OrganizationsEnvironmentsQueriesGetCall {
	c := &OrganizationsEnvironmentsQueriesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsQueriesGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsQueriesGetCall {
	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 *OrganizationsEnvironmentsQueriesGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsQueriesGetCall {
	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 *OrganizationsEnvironmentsQueriesGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsQueriesGetCall {
	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 *OrganizationsEnvironmentsQueriesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsQueriesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.queries.get" call.
// Exactly one of *GoogleCloudApigeeV1AsyncQuery or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1AsyncQuery.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 *OrganizationsEnvironmentsQueriesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1AsyncQuery, 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 := &GoogleCloudApigeeV1AsyncQuery{
		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": "Get query status If the query is still in progress, the `state` is set to \"running\" After the query has completed successfully, `state` is set to \"completed\"",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/queries/{queriesId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.queries.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the asynchronous query to get. Must be of the form `organizations/{org}/environments/{env}/queries/{queryId}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/queries/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1AsyncQuery"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.queries.getResult":

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

// GetResult: After the query is completed, use this API to retrieve the
// results. If the request succeeds, and there is a non-zero result set,
// the result is downloaded to the client as a zipped JSON file. The
// name of the downloaded file will be: OfflineQueryResult-.zip Example:
// `OfflineQueryResult-9cfc0d85-0f30-46d6-ae6f-318d0cb961bd.zip`
func (r *OrganizationsEnvironmentsQueriesService) GetResult(name string) *OrganizationsEnvironmentsQueriesGetResultCall {
	c := &OrganizationsEnvironmentsQueriesGetResultCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsQueriesGetResultCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsQueriesGetResultCall {
	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 *OrganizationsEnvironmentsQueriesGetResultCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsQueriesGetResultCall {
	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 *OrganizationsEnvironmentsQueriesGetResultCall) Context(ctx context.Context) *OrganizationsEnvironmentsQueriesGetResultCall {
	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 *OrganizationsEnvironmentsQueriesGetResultCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsQueriesGetResultCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.queries.getResult" call.
// Exactly one of *GoogleApiHttpBody or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleApiHttpBody.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 *OrganizationsEnvironmentsQueriesGetResultCall) Do(opts ...googleapi.CallOption) (*GoogleApiHttpBody, 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 := &GoogleApiHttpBody{
		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": "After the query is completed, use this API to retrieve the results. If the request succeeds, and there is a non-zero result set, the result is downloaded to the client as a zipped JSON file. The name of the downloaded file will be: OfflineQueryResult-.zip Example: `OfflineQueryResult-9cfc0d85-0f30-46d6-ae6f-318d0cb961bd.zip`",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/queries/{queriesId}/result",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.queries.getResult",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the asynchronous query result to get. Must be of the form `organizations/{org}/environments/{env}/queries/{queryId}/result`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/queries/[^/]+/result$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.queries.list":

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

// List: Return a list of Asynchronous Queries
func (r *OrganizationsEnvironmentsQueriesService) List(parent string) *OrganizationsEnvironmentsQueriesListCall {
	c := &OrganizationsEnvironmentsQueriesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Dataset sets the optional parameter "dataset": Filter response list
// by dataset. Example: `api`, `mint`
func (c *OrganizationsEnvironmentsQueriesListCall) Dataset(dataset string) *OrganizationsEnvironmentsQueriesListCall {
	c.urlParams_.Set("dataset", dataset)
	return c
}

// From sets the optional parameter "from": Filter response list by
// returning asynchronous queries that created after this date time.
// Time must be in ISO date-time format like '2011-12-03T10:15:30Z'.
func (c *OrganizationsEnvironmentsQueriesListCall) From(from string) *OrganizationsEnvironmentsQueriesListCall {
	c.urlParams_.Set("from", from)
	return c
}

// InclQueriesWithoutReport sets the optional parameter
// "inclQueriesWithoutReport": Flag to include asynchronous queries that
// don't have a report denifition.
func (c *OrganizationsEnvironmentsQueriesListCall) InclQueriesWithoutReport(inclQueriesWithoutReport string) *OrganizationsEnvironmentsQueriesListCall {
	c.urlParams_.Set("inclQueriesWithoutReport", inclQueriesWithoutReport)
	return c
}

// Status sets the optional parameter "status": Filter response list by
// asynchronous query status.
func (c *OrganizationsEnvironmentsQueriesListCall) Status(status string) *OrganizationsEnvironmentsQueriesListCall {
	c.urlParams_.Set("status", status)
	return c
}

// SubmittedBy sets the optional parameter "submittedBy": Filter
// response list by user who submitted queries.
func (c *OrganizationsEnvironmentsQueriesListCall) SubmittedBy(submittedBy string) *OrganizationsEnvironmentsQueriesListCall {
	c.urlParams_.Set("submittedBy", submittedBy)
	return c
}

// To sets the optional parameter "to": Filter response list by
// returning asynchronous queries that created before this date time.
// Time must be in ISO date-time format like '2011-12-03T10:16:30Z'.
func (c *OrganizationsEnvironmentsQueriesListCall) To(to string) *OrganizationsEnvironmentsQueriesListCall {
	c.urlParams_.Set("to", to)
	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 *OrganizationsEnvironmentsQueriesListCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsQueriesListCall {
	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 *OrganizationsEnvironmentsQueriesListCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsQueriesListCall {
	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 *OrganizationsEnvironmentsQueriesListCall) Context(ctx context.Context) *OrganizationsEnvironmentsQueriesListCall {
	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 *OrganizationsEnvironmentsQueriesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsQueriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/queries")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.queries.list" call.
// Exactly one of *GoogleCloudApigeeV1ListAsyncQueriesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListAsyncQueriesResponse.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 *OrganizationsEnvironmentsQueriesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListAsyncQueriesResponse, 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 := &GoogleCloudApigeeV1ListAsyncQueriesResponse{
		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": "Return a list of Asynchronous Queries",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/queries",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.queries.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "dataset": {
	//       "description": "Filter response list by dataset. Example: `api`, `mint`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "from": {
	//       "description": "Filter response list by returning asynchronous queries that created after this date time. Time must be in ISO date-time format like '2011-12-03T10:15:30Z'.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "inclQueriesWithoutReport": {
	//       "description": "Flag to include asynchronous queries that don't have a report denifition.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource name. Must be of the form `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "status": {
	//       "description": "Filter response list by asynchronous query status.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "submittedBy": {
	//       "description": "Filter response list by user who submitted queries.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "to": {
	//       "description": "Filter response list by returning asynchronous queries that created before this date time. Time must be in ISO date-time format like '2011-12-03T10:16:30Z'.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/queries",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListAsyncQueriesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.references.create":

type OrganizationsEnvironmentsReferencesCreateCall struct {
	s                            *Service
	parent                       string
	googlecloudapigeev1reference *GoogleCloudApigeeV1Reference
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Create: Creates a Reference in the specified environment.
func (r *OrganizationsEnvironmentsReferencesService) Create(parent string, googlecloudapigeev1reference *GoogleCloudApigeeV1Reference) *OrganizationsEnvironmentsReferencesCreateCall {
	c := &OrganizationsEnvironmentsReferencesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1reference = googlecloudapigeev1reference
	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 *OrganizationsEnvironmentsReferencesCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsReferencesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsReferencesCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsReferencesCreateCall {
	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 *OrganizationsEnvironmentsReferencesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsReferencesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1reference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/references")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.references.create" call.
// Exactly one of *GoogleCloudApigeeV1Reference or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Reference.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 *OrganizationsEnvironmentsReferencesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Reference, 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 := &GoogleCloudApigeeV1Reference{
		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": "Creates a Reference in the specified environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/references",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.references.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent environment name under which the Reference will be created. Must be of the form `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/references",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Reference"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Reference"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.references.delete":

type OrganizationsEnvironmentsReferencesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a Reference from an environment. Returns the deleted
// Reference resource.
func (r *OrganizationsEnvironmentsReferencesService) Delete(name string) *OrganizationsEnvironmentsReferencesDeleteCall {
	c := &OrganizationsEnvironmentsReferencesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsReferencesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsReferencesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsReferencesDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsReferencesDeleteCall {
	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 *OrganizationsEnvironmentsReferencesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsReferencesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.references.delete" call.
// Exactly one of *GoogleCloudApigeeV1Reference or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Reference.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 *OrganizationsEnvironmentsReferencesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Reference, 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 := &GoogleCloudApigeeV1Reference{
		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": "Deletes a Reference from an environment. Returns the deleted Reference resource.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/references/{referencesId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.references.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the Reference to delete. Must be of the form `organizations/{org}/environments/{env}/references/{ref}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/references/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Reference"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.references.get":

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

// Get: Gets a Reference resource.
func (r *OrganizationsEnvironmentsReferencesService) Get(name string) *OrganizationsEnvironmentsReferencesGetCall {
	c := &OrganizationsEnvironmentsReferencesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsReferencesGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsReferencesGetCall {
	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 *OrganizationsEnvironmentsReferencesGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsReferencesGetCall {
	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 *OrganizationsEnvironmentsReferencesGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsReferencesGetCall {
	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 *OrganizationsEnvironmentsReferencesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsReferencesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.references.get" call.
// Exactly one of *GoogleCloudApigeeV1Reference or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Reference.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 *OrganizationsEnvironmentsReferencesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Reference, 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 := &GoogleCloudApigeeV1Reference{
		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": "Gets a Reference resource.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/references/{referencesId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.references.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the Reference to get. Must be of the form `organizations/{org}/environments/{env}/references/{ref}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/references/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Reference"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.references.update":

type OrganizationsEnvironmentsReferencesUpdateCall struct {
	s                            *Service
	name                         string
	googlecloudapigeev1reference *GoogleCloudApigeeV1Reference
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Update: Updates an existing Reference. Note that this operation has
// PUT semantics; it will replace the entirety of the existing Reference
// with the resource in the request body.
func (r *OrganizationsEnvironmentsReferencesService) Update(name string, googlecloudapigeev1reference *GoogleCloudApigeeV1Reference) *OrganizationsEnvironmentsReferencesUpdateCall {
	c := &OrganizationsEnvironmentsReferencesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1reference = googlecloudapigeev1reference
	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 *OrganizationsEnvironmentsReferencesUpdateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsReferencesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsReferencesUpdateCall) Context(ctx context.Context) *OrganizationsEnvironmentsReferencesUpdateCall {
	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 *OrganizationsEnvironmentsReferencesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsReferencesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1reference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.references.update" call.
// Exactly one of *GoogleCloudApigeeV1Reference or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Reference.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 *OrganizationsEnvironmentsReferencesUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Reference, 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 := &GoogleCloudApigeeV1Reference{
		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": "Updates an existing Reference. Note that this operation has PUT semantics; it will replace the entirety of the existing Reference with the resource in the request body.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/references/{referencesId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.environments.references.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the Reference to update. Must be of the form `organizations/{org}/environments/{env}/references/{ref}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/references/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Reference"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Reference"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.resourcefiles.create":

type OrganizationsEnvironmentsResourcefilesCreateCall struct {
	s                 *Service
	parent            string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates a resource file. Specify the `Content-Type` as
// `application/octet-stream` or `multipart/form-data`. For more
// information about resource files, see [Resource
// files](/api-platform/develop/resource-files).
func (r *OrganizationsEnvironmentsResourcefilesService) Create(parent string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsEnvironmentsResourcefilesCreateCall {
	c := &OrganizationsEnvironmentsResourcefilesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleapihttpbody = googleapihttpbody
	return c
}

// Name sets the optional parameter "name": Required. Name of the
// resource file. Must match the regular expression:
// [a-zA-Z0-9:/\\!@#$%^&{}\[\]()+\-=,.~'` ]{1,255}
func (c *OrganizationsEnvironmentsResourcefilesCreateCall) Name(name string) *OrganizationsEnvironmentsResourcefilesCreateCall {
	c.urlParams_.Set("name", name)
	return c
}

// Type sets the optional parameter "type": Required. Resource file
// type. {{ resource_file_type }}
func (c *OrganizationsEnvironmentsResourcefilesCreateCall) Type(type_ string) *OrganizationsEnvironmentsResourcefilesCreateCall {
	c.urlParams_.Set("type", type_)
	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 *OrganizationsEnvironmentsResourcefilesCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsResourcefilesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsResourcefilesCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsResourcefilesCreateCall {
	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 *OrganizationsEnvironmentsResourcefilesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsResourcefilesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/resourcefiles")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.resourcefiles.create" call.
// Exactly one of *GoogleCloudApigeeV1ResourceFile or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ResourceFile.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 *OrganizationsEnvironmentsResourcefilesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ResourceFile, 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 := &GoogleCloudApigeeV1ResourceFile{
		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": "Creates a resource file. Specify the `Content-Type` as `application/octet-stream` or `multipart/form-data`. For more information about resource files, see [Resource files](/api-platform/develop/resource-files).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/resourcefiles",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.resourcefiles.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the resource file. Must match the regular expression: [a-zA-Z0-9:/\\\\!@#$%^\u0026{}\\[\\]()+\\-=,.~'` ]{1,255}",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the environment in which to create the resource file in the following format: `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Required. Resource file type. {{ resource_file_type }}",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/resourcefiles",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ResourceFile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.resourcefiles.delete":

type OrganizationsEnvironmentsResourcefilesDeleteCall struct {
	s          *Service
	parent     string
	type_      string
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a resource file. For more information about resource
// files, see [Resource files](/api-platform/develop/resource-files).
func (r *OrganizationsEnvironmentsResourcefilesService) Delete(parent string, type_ string, name string) *OrganizationsEnvironmentsResourcefilesDeleteCall {
	c := &OrganizationsEnvironmentsResourcefilesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.type_ = type_
	c.name = name
	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 *OrganizationsEnvironmentsResourcefilesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsResourcefilesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsResourcefilesDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsResourcefilesDeleteCall {
	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 *OrganizationsEnvironmentsResourcefilesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsResourcefilesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/resourcefiles/{type}/{name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
		"type":   c.type_,
		"name":   c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.resourcefiles.delete" call.
// Exactly one of *GoogleCloudApigeeV1ResourceFile or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ResourceFile.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 *OrganizationsEnvironmentsResourcefilesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ResourceFile, 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 := &GoogleCloudApigeeV1ResourceFile{
		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": "Deletes a resource file. For more information about resource files, see [Resource files](/api-platform/develop/resource-files).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/resourcefiles/{type}/{name}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.resourcefiles.delete",
	//   "parameterOrder": [
	//     "parent",
	//     "type",
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. ID of the resource file to delete. Must match the regular expression: [a-zA-Z0-9:/\\\\!@#$%^\u0026{}\\[\\]()+\\-=,.~'` ]{1,255}",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the environment in the following format: `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Required. Resource file type. {{ resource_file_type }}",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/resourcefiles/{type}/{name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ResourceFile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.resourcefiles.get":

type OrganizationsEnvironmentsResourcefilesGetCall struct {
	s            *Service
	parent       string
	type_        string
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the contents of a resource file. For more information about
// resource files, see [Resource
// files](/api-platform/develop/resource-files).
func (r *OrganizationsEnvironmentsResourcefilesService) Get(parent string, type_ string, name string) *OrganizationsEnvironmentsResourcefilesGetCall {
	c := &OrganizationsEnvironmentsResourcefilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.type_ = type_
	c.name = name
	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 *OrganizationsEnvironmentsResourcefilesGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsResourcefilesGetCall {
	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 *OrganizationsEnvironmentsResourcefilesGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsResourcefilesGetCall {
	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 *OrganizationsEnvironmentsResourcefilesGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsResourcefilesGetCall {
	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 *OrganizationsEnvironmentsResourcefilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsResourcefilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/resourcefiles/{type}/{name}")
	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{
		"parent": c.parent,
		"type":   c.type_,
		"name":   c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.resourcefiles.get" call.
// Exactly one of *GoogleApiHttpBody or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleApiHttpBody.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 *OrganizationsEnvironmentsResourcefilesGetCall) Do(opts ...googleapi.CallOption) (*GoogleApiHttpBody, 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 := &GoogleApiHttpBody{
		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": "Gets the contents of a resource file. For more information about resource files, see [Resource files](/api-platform/develop/resource-files).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/resourcefiles/{type}/{name}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.resourcefiles.get",
	//   "parameterOrder": [
	//     "parent",
	//     "type",
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. ID of the resource file. Must match the regular expression: [a-zA-Z0-9:/\\\\!@#$%^\u0026{}\\[\\]()+\\-=,.~'` ]{1,255}",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the environment in the following format: `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Required. Resource file type. {{ resource_file_type }}",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/resourcefiles/{type}/{name}",
	//   "response": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.resourcefiles.list":

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

// List: Lists all resource files. For more information about resource
// files, see [Resource files](/api-platform/develop/resource-files).
func (r *OrganizationsEnvironmentsResourcefilesService) List(parent string) *OrganizationsEnvironmentsResourcefilesListCall {
	c := &OrganizationsEnvironmentsResourcefilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Type sets the optional parameter "type": Type of resource files to
// list. {{ resource_file_type }}
func (c *OrganizationsEnvironmentsResourcefilesListCall) Type(type_ string) *OrganizationsEnvironmentsResourcefilesListCall {
	c.urlParams_.Set("type", type_)
	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 *OrganizationsEnvironmentsResourcefilesListCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsResourcefilesListCall {
	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 *OrganizationsEnvironmentsResourcefilesListCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsResourcefilesListCall {
	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 *OrganizationsEnvironmentsResourcefilesListCall) Context(ctx context.Context) *OrganizationsEnvironmentsResourcefilesListCall {
	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 *OrganizationsEnvironmentsResourcefilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsResourcefilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/resourcefiles")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.resourcefiles.list" call.
// Exactly one of *GoogleCloudApigeeV1ListEnvironmentResourcesResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudApigeeV1ListEnvironmentResourcesResponse.ServerResponse.He
// ader 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 *OrganizationsEnvironmentsResourcefilesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListEnvironmentResourcesResponse, 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 := &GoogleCloudApigeeV1ListEnvironmentResourcesResponse{
		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": "Lists all resource files. For more information about resource files, see [Resource files](/api-platform/develop/resource-files).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/resourcefiles",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.resourcefiles.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the environment in which to list resource files in the following format: `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Optional. Type of resource files to list. {{ resource_file_type }}",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/resourcefiles",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListEnvironmentResourcesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.resourcefiles.listEnvironmentResources":

type OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall struct {
	s            *Service
	parent       string
	type_        string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListEnvironmentResources: Lists all resource files. For more
// information about resource files, see [Resource
// files](/api-platform/develop/resource-files).
func (r *OrganizationsEnvironmentsResourcefilesService) ListEnvironmentResources(parent string, type_ string) *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall {
	c := &OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.type_ = type_
	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 *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall {
	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 *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall {
	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 *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall) Context(ctx context.Context) *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall {
	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 *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/resourcefiles/{type}")
	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{
		"parent": c.parent,
		"type":   c.type_,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.resourcefiles.listEnvironmentResources" call.
// Exactly one of *GoogleCloudApigeeV1ListEnvironmentResourcesResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudApigeeV1ListEnvironmentResourcesResponse.ServerResponse.He
// ader 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 *OrganizationsEnvironmentsResourcefilesListEnvironmentResourcesCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListEnvironmentResourcesResponse, 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 := &GoogleCloudApigeeV1ListEnvironmentResourcesResponse{
		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": "Lists all resource files. For more information about resource files, see [Resource files](/api-platform/develop/resource-files).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/resourcefiles/{type}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.resourcefiles.listEnvironmentResources",
	//   "parameterOrder": [
	//     "parent",
	//     "type"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the environment in which to list resource files in the following format: `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Optional. Type of resource files to list. {{ resource_file_type }}",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/resourcefiles/{type}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListEnvironmentResourcesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.resourcefiles.update":

type OrganizationsEnvironmentsResourcefilesUpdateCall struct {
	s                 *Service
	parent            string
	type_             string
	name              string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Update: Updates a resource file. Specify the `Content-Type` as
// `application/octet-stream` or `multipart/form-data`. For more
// information about resource files, see [Resource
// files](/api-platform/develop/resource-files).
func (r *OrganizationsEnvironmentsResourcefilesService) Update(parent string, type_ string, name string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsEnvironmentsResourcefilesUpdateCall {
	c := &OrganizationsEnvironmentsResourcefilesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.type_ = type_
	c.name = name
	c.googleapihttpbody = googleapihttpbody
	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 *OrganizationsEnvironmentsResourcefilesUpdateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsResourcefilesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsResourcefilesUpdateCall) Context(ctx context.Context) *OrganizationsEnvironmentsResourcefilesUpdateCall {
	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 *OrganizationsEnvironmentsResourcefilesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsResourcefilesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/resourcefiles/{type}/{name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
		"type":   c.type_,
		"name":   c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.resourcefiles.update" call.
// Exactly one of *GoogleCloudApigeeV1ResourceFile or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1ResourceFile.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 *OrganizationsEnvironmentsResourcefilesUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ResourceFile, 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 := &GoogleCloudApigeeV1ResourceFile{
		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": "Updates a resource file. Specify the `Content-Type` as `application/octet-stream` or `multipart/form-data`. For more information about resource files, see [Resource files](/api-platform/develop/resource-files).",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/resourcefiles/{type}/{name}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.environments.resourcefiles.update",
	//   "parameterOrder": [
	//     "parent",
	//     "type",
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. ID of the resource file to update. Must match the regular expression: [a-zA-Z0-9:/\\\\!@#$%^\u0026{}\\[\\]()+\\-=,.~'` ]{1,255}",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the environment in the following format: `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Required. Resource file type. {{ resource_file_type }}",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/resourcefiles/{type}/{name}",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ResourceFile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.sharedflows.deployments.list":

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

// List: Lists all deployments of a shared flow in an environment.
func (r *OrganizationsEnvironmentsSharedflowsDeploymentsService) List(parent string) *OrganizationsEnvironmentsSharedflowsDeploymentsListCall {
	c := &OrganizationsEnvironmentsSharedflowsDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsEnvironmentsSharedflowsDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsSharedflowsDeploymentsListCall {
	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 *OrganizationsEnvironmentsSharedflowsDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsSharedflowsDeploymentsListCall {
	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 *OrganizationsEnvironmentsSharedflowsDeploymentsListCall) Context(ctx context.Context) *OrganizationsEnvironmentsSharedflowsDeploymentsListCall {
	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 *OrganizationsEnvironmentsSharedflowsDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsSharedflowsDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.sharedflows.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsEnvironmentsSharedflowsDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of a shared flow in an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/sharedflows/{sharedflowsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.sharedflows.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name representing a shared flow in an environment in the following format: `organizations/{org}/environments/{env}/sharedflows/{sharedflow}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/sharedflows/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.sharedflows.revisions.deploy":

type OrganizationsEnvironmentsSharedflowsRevisionsDeployCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Deploy: Deploys a revision of a shared flow. If a shared flow
// revision is currently deployed, to ensure seamless deployment with
// zero downtime set the `override` parameter to `true`. In this case,
// hybrid attempts to deply the new revision fully before undeploying
// the existing revision. You cannot use a shared flows until it has
// been deployed to an environment.
func (r *OrganizationsEnvironmentsSharedflowsRevisionsService) Deploy(name string) *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall {
	c := &OrganizationsEnvironmentsSharedflowsRevisionsDeployCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Override sets the optional parameter "override": Flag that specifies
// whether to force the deployment of the new revision over the
// currently deployed revision by overriding conflict checks. If an
// existing shared flow revision is deployed, to ensure seamless
// deployment with no downtime, set this parameter to `true`. In this
// case, hybrid deploys the new revision fully before undeploying the
// existing revision. If set to `false`, you must undeploy the existing
// revision before deploying the new revision.
func (c *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall) Override(override bool) *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall {
	c.urlParams_.Set("override", fmt.Sprint(override))
	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 *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall) Context(ctx context.Context) *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall {
	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 *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/deployments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.sharedflows.revisions.deploy" call.
// Exactly one of *GoogleCloudApigeeV1Deployment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Deployment.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 *OrganizationsEnvironmentsSharedflowsRevisionsDeployCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Deployment, 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 := &GoogleCloudApigeeV1Deployment{
		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": "Deploys a revision of a shared flow. If a shared flow revision is currently deployed, to ensure seamless deployment with zero downtime set the `override` parameter to `true`. In this case, hybrid attempts to deply the new revision fully before undeploying the existing revision. You cannot use a shared flows until it has been deployed to an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/sharedflows/{sharedflowsId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.sharedflows.revisions.deploy",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the shared flow revision to deploy in the following format: `organizations/{org}/environments/{env}/sharedflows/{sharedflow}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/sharedflows/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "override": {
	//       "description": "Flag that specifies whether to force the deployment of the new revision over the currently deployed revision by overriding conflict checks. If an existing shared flow revision is deployed, to ensure seamless deployment with no downtime, set this parameter to `true`. In this case, hybrid deploys the new revision fully before undeploying the existing revision. If set to `false`, you must undeploy the existing revision before deploying the new revision.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Deployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.sharedflows.revisions.getDeployments":

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

// GetDeployments: Gets the deployment of a shared flow revision and
// actual state reported by runtime pods.
func (r *OrganizationsEnvironmentsSharedflowsRevisionsService) GetDeployments(name string) *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall {
	c := &OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall {
	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 *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall {
	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 *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall) Context(ctx context.Context) *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall {
	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 *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}/deployments")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.sharedflows.revisions.getDeployments" call.
// Exactly one of *GoogleCloudApigeeV1Deployment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1Deployment.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 *OrganizationsEnvironmentsSharedflowsRevisionsGetDeploymentsCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Deployment, 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 := &GoogleCloudApigeeV1Deployment{
		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": "Gets the deployment of a shared flow revision and actual state reported by runtime pods.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/sharedflows/{sharedflowsId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.sharedflows.revisions.getDeployments",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name representing a shared flow in an environment in the following format: `organizations/{org}/environments/{env}/sharedflows/{sharedflow}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/sharedflows/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Deployment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.sharedflows.revisions.undeploy":

type OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Undeploy: Undeploys a shared flow revision from an environment.
func (r *OrganizationsEnvironmentsSharedflowsRevisionsService) Undeploy(name string) *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall {
	c := &OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall) Context(ctx context.Context) *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall {
	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 *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/deployments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.sharedflows.revisions.undeploy" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OrganizationsEnvironmentsSharedflowsRevisionsUndeployCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Undeploys a shared flow revision from an environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/sharedflows/{sharedflowsId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.sharedflows.revisions.undeploy",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the shared flow revision to undeploy in the following format: `organizations/{org}/environments/{env}/sharedflows/{sharedflow}/revisions/{rev}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/sharedflows/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/deployments",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.stats.get":

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

// Get: Retrieve metrics grouped by dimensions. The types of metrics you
// can retrieve include traffic, message counts, API call latency,
// response size, and cache hits and counts. Dimensions let you view
// metrics in meaningful groups. The stats api does accept dimensions as
// path params. The dimensions are optional in which case the metrics
// are computed on the entire data for the given timerange.
func (r *OrganizationsEnvironmentsStatsService) Get(name string) *OrganizationsEnvironmentsStatsGetCall {
	c := &OrganizationsEnvironmentsStatsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Accuracy sets the optional parameter "accuracy": Legacy field: not
// used anymore. This field is present to support UI calls which still
// use this parameter.
func (c *OrganizationsEnvironmentsStatsGetCall) Accuracy(accuracy string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("accuracy", accuracy)
	return c
}

// AggTable sets the optional parameter "aggTable": If customers want to
// query custom aggregate tables, then this parameter can be used to
// specify the table name. If this parameter is skipped, then Edge Query
// will try to retrieve the data from fact tables which will be
// expensive.
func (c *OrganizationsEnvironmentsStatsGetCall) AggTable(aggTable string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("aggTable", aggTable)
	return c
}

// Filter sets the optional parameter "filter": Enables drill-down on
// specific dimension values
func (c *OrganizationsEnvironmentsStatsGetCall) Filter(filter string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// Limit sets the optional parameter "limit": This parameter is used to
// limit the number of result items. Default and the max value is 14400.
func (c *OrganizationsEnvironmentsStatsGetCall) Limit(limit string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("limit", limit)
	return c
}

// Offset sets the optional parameter "offset": Use offset with limit to
// enable pagination of results. For example, to display results 11-20,
// set limit to '10' and offset to '10'.
func (c *OrganizationsEnvironmentsStatsGetCall) Offset(offset string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("offset", offset)
	return c
}

// Realtime sets the optional parameter "realtime": Legacy field: not
// used anymore.
func (c *OrganizationsEnvironmentsStatsGetCall) Realtime(realtime bool) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("realtime", fmt.Sprint(realtime))
	return c
}

// Select sets the optional parameter "select": The select parameter
// contains a comma separated list of metrics. E.g.
// sum(message_count),sum(error_count)
func (c *OrganizationsEnvironmentsStatsGetCall) Select(select_ string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("select", select_)
	return c
}

// Sonar sets the optional parameter "sonar": This parameter routes the
// query to api monitoring service for last hour.
func (c *OrganizationsEnvironmentsStatsGetCall) Sonar(sonar bool) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("sonar", fmt.Sprint(sonar))
	return c
}

// Sort sets the optional parameter "sort": This parameter specifies if
// the sort order should be ascending or descending Supported values are
// DESC and ASC.
func (c *OrganizationsEnvironmentsStatsGetCall) Sort(sort string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("sort", sort)
	return c
}

// Sortby sets the optional parameter "sortby": Comma separated list of
// columns to sort the final result.
func (c *OrganizationsEnvironmentsStatsGetCall) Sortby(sortby string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("sortby", sortby)
	return c
}

// TimeRange sets the optional parameter "timeRange": Time interval for
// the interactive query. Time range is specified as start~end E.g.
// 04/15/2017 00:00~05/15/2017 23:59
func (c *OrganizationsEnvironmentsStatsGetCall) TimeRange(timeRange string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("timeRange", timeRange)
	return c
}

// TimeUnit sets the optional parameter "timeUnit": A value of second,
// minute, hour, day, week, month. Time Unit specifies the granularity
// of metrics returned.
func (c *OrganizationsEnvironmentsStatsGetCall) TimeUnit(timeUnit string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("timeUnit", timeUnit)
	return c
}

// Topk sets the optional parameter "topk": Take 'top k' results from
// results, for example, to return the top 5 results 'topk=5'.
func (c *OrganizationsEnvironmentsStatsGetCall) Topk(topk string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("topk", topk)
	return c
}

// TsAscending sets the optional parameter "tsAscending": Lists
// timestamps in ascending order if set to true. Recommend setting this
// value to true if you are using sortby with sort=DESC.
func (c *OrganizationsEnvironmentsStatsGetCall) TsAscending(tsAscending bool) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("tsAscending", fmt.Sprint(tsAscending))
	return c
}

// Tzo sets the optional parameter "tzo": This parameters contains the
// timezone offset value.
func (c *OrganizationsEnvironmentsStatsGetCall) Tzo(tzo string) *OrganizationsEnvironmentsStatsGetCall {
	c.urlParams_.Set("tzo", tzo)
	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 *OrganizationsEnvironmentsStatsGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsStatsGetCall {
	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 *OrganizationsEnvironmentsStatsGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsStatsGetCall {
	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 *OrganizationsEnvironmentsStatsGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsStatsGetCall {
	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 *OrganizationsEnvironmentsStatsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsStatsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.stats.get" call.
// Exactly one of *GoogleCloudApigeeV1Stats or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Stats.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 *OrganizationsEnvironmentsStatsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Stats, 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 := &GoogleCloudApigeeV1Stats{
		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": "Retrieve metrics grouped by dimensions. The types of metrics you can retrieve include traffic, message counts, API call latency, response size, and cache hits and counts. Dimensions let you view metrics in meaningful groups. The stats api does accept dimensions as path params. The dimensions are optional in which case the metrics are computed on the entire data for the given timerange.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/stats/{statsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.stats.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "accuracy": {
	//       "description": "Legacy field: not used anymore. This field is present to support UI calls which still use this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "aggTable": {
	//       "description": "If customers want to query custom aggregate tables, then this parameter can be used to specify the table name. If this parameter is skipped, then Edge Query will try to retrieve the data from fact tables which will be expensive.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Enables drill-down on specific dimension values",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "This parameter is used to limit the number of result items. Default and the max value is 14400.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The resource name for which the interactive query will be executed. Must be of the form `organizations/{organization_id}/environments/{environment_id/stats/{dimensions}` Dimensions let you view metrics in meaningful groupings. E.g. apiproxy, target_host. The value of dimensions should be comma separated list as shown below `organizations/{org}/environments/{env}/stats/apiproxy,request_verb`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/stats/.*$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "offset": {
	//       "description": "Use offset with limit to enable pagination of results. For example, to display results 11-20, set limit to '10' and offset to '10'.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "realtime": {
	//       "description": "Legacy field: not used anymore.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "select": {
	//       "description": "The select parameter contains a comma separated list of metrics. E.g. sum(message_count),sum(error_count)",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sonar": {
	//       "description": "This parameter routes the query to api monitoring service for last hour.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "sort": {
	//       "description": "This parameter specifies if the sort order should be ascending or descending Supported values are DESC and ASC.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortby": {
	//       "description": "Comma separated list of columns to sort the final result.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timeRange": {
	//       "description": "Time interval for the interactive query. Time range is specified as start~end E.g. 04/15/2017 00:00~05/15/2017 23:59",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timeUnit": {
	//       "description": "A value of second, minute, hour, day, week, month. Time Unit specifies the granularity of metrics returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "topk": {
	//       "description": "Take 'top k' results from results, for example, to return the top 5 results 'topk=5'.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tsAscending": {
	//       "description": "Lists timestamps in ascending order if set to true. Recommend setting this value to true if you are using sortby with sort=DESC.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "tzo": {
	//       "description": "This parameters contains the timezone offset value.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Stats"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.targetservers.create":

type OrganizationsEnvironmentsTargetserversCreateCall struct {
	s                               *Service
	parent                          string
	googlecloudapigeev1targetserver *GoogleCloudApigeeV1TargetServer
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Create: Creates a TargetServer in the specified environment.
func (r *OrganizationsEnvironmentsTargetserversService) Create(parent string, googlecloudapigeev1targetserver *GoogleCloudApigeeV1TargetServer) *OrganizationsEnvironmentsTargetserversCreateCall {
	c := &OrganizationsEnvironmentsTargetserversCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1targetserver = googlecloudapigeev1targetserver
	return c
}

// Name sets the optional parameter "name": The ID to give the
// TargetServer. This will overwrite the value in TargetServer.
func (c *OrganizationsEnvironmentsTargetserversCreateCall) Name(name string) *OrganizationsEnvironmentsTargetserversCreateCall {
	c.urlParams_.Set("name", name)
	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 *OrganizationsEnvironmentsTargetserversCreateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsTargetserversCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsTargetserversCreateCall) Context(ctx context.Context) *OrganizationsEnvironmentsTargetserversCreateCall {
	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 *OrganizationsEnvironmentsTargetserversCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsTargetserversCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1targetserver)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/targetservers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.targetservers.create" call.
// Exactly one of *GoogleCloudApigeeV1TargetServer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1TargetServer.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 *OrganizationsEnvironmentsTargetserversCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1TargetServer, 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 := &GoogleCloudApigeeV1TargetServer{
		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": "Creates a TargetServer in the specified environment.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/targetservers",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.environments.targetservers.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Optional. The ID to give the TargetServer. This will overwrite the value in TargetServer.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent environment name under which the TargetServer will be created. Must be of the form `organizations/{org}/environments/{env}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/targetservers",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1TargetServer"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1TargetServer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.targetservers.delete":

type OrganizationsEnvironmentsTargetserversDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a TargetServer from an environment. Returns the
// deleted TargetServer resource.
func (r *OrganizationsEnvironmentsTargetserversService) Delete(name string) *OrganizationsEnvironmentsTargetserversDeleteCall {
	c := &OrganizationsEnvironmentsTargetserversDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsTargetserversDeleteCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsTargetserversDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsTargetserversDeleteCall) Context(ctx context.Context) *OrganizationsEnvironmentsTargetserversDeleteCall {
	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 *OrganizationsEnvironmentsTargetserversDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsTargetserversDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.targetservers.delete" call.
// Exactly one of *GoogleCloudApigeeV1TargetServer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1TargetServer.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 *OrganizationsEnvironmentsTargetserversDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1TargetServer, 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 := &GoogleCloudApigeeV1TargetServer{
		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": "Deletes a TargetServer from an environment. Returns the deleted TargetServer resource.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/targetservers/{targetserversId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.environments.targetservers.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the TargetServer to delete. Must be of the form `organizations/{org}/environments/{env}/targetservers/{target_server_id}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/targetservers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1TargetServer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.targetservers.get":

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

// Get: Gets a TargetServer resource.
func (r *OrganizationsEnvironmentsTargetserversService) Get(name string) *OrganizationsEnvironmentsTargetserversGetCall {
	c := &OrganizationsEnvironmentsTargetserversGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsEnvironmentsTargetserversGetCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsTargetserversGetCall {
	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 *OrganizationsEnvironmentsTargetserversGetCall) IfNoneMatch(entityTag string) *OrganizationsEnvironmentsTargetserversGetCall {
	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 *OrganizationsEnvironmentsTargetserversGetCall) Context(ctx context.Context) *OrganizationsEnvironmentsTargetserversGetCall {
	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 *OrganizationsEnvironmentsTargetserversGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsTargetserversGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.targetservers.get" call.
// Exactly one of *GoogleCloudApigeeV1TargetServer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1TargetServer.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 *OrganizationsEnvironmentsTargetserversGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1TargetServer, 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 := &GoogleCloudApigeeV1TargetServer{
		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": "Gets a TargetServer resource.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/targetservers/{targetserversId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.environments.targetservers.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the TargetServer to get. Must be of the form `organizations/{org}/environments/{env}/targetservers/{target_server_id}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/targetservers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1TargetServer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.environments.targetservers.update":

type OrganizationsEnvironmentsTargetserversUpdateCall struct {
	s                               *Service
	name                            string
	googlecloudapigeev1targetserver *GoogleCloudApigeeV1TargetServer
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Update: Updates an existing TargetServer. Note that this operation
// has PUT semantics; it will replace the entirety of the existing
// TargetServer with the resource in the request body.
func (r *OrganizationsEnvironmentsTargetserversService) Update(name string, googlecloudapigeev1targetserver *GoogleCloudApigeeV1TargetServer) *OrganizationsEnvironmentsTargetserversUpdateCall {
	c := &OrganizationsEnvironmentsTargetserversUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1targetserver = googlecloudapigeev1targetserver
	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 *OrganizationsEnvironmentsTargetserversUpdateCall) Fields(s ...googleapi.Field) *OrganizationsEnvironmentsTargetserversUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsEnvironmentsTargetserversUpdateCall) Context(ctx context.Context) *OrganizationsEnvironmentsTargetserversUpdateCall {
	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 *OrganizationsEnvironmentsTargetserversUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsEnvironmentsTargetserversUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1targetserver)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.environments.targetservers.update" call.
// Exactly one of *GoogleCloudApigeeV1TargetServer or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1TargetServer.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 *OrganizationsEnvironmentsTargetserversUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1TargetServer, 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 := &GoogleCloudApigeeV1TargetServer{
		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": "Updates an existing TargetServer. Note that this operation has PUT semantics; it will replace the entirety of the existing TargetServer with the resource in the request body.",
	//   "flatPath": "v1/organizations/{organizationsId}/environments/{environmentsId}/targetservers/{targetserversId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.environments.targetservers.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the TargetServer to replace. Must be of the form `organizations/{org}/environments/{env}/targetservers/{target_server_id}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/environments/[^/]+/targetservers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1TargetServer"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1TargetServer"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.create":

type OrganizationsInstancesCreateCall struct {
	s                           *Service
	parent                      string
	googlecloudapigeev1instance *GoogleCloudApigeeV1Instance
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// Create: Creates an Apigee runtime instance. The instance is
// accessible from the authorized network configured on the
// organization. **Note:** Not supported for Apigee hybrid.
func (r *OrganizationsInstancesService) Create(parent string, googlecloudapigeev1instance *GoogleCloudApigeeV1Instance) *OrganizationsInstancesCreateCall {
	c := &OrganizationsInstancesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1instance = googlecloudapigeev1instance
	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 *OrganizationsInstancesCreateCall) Fields(s ...googleapi.Field) *OrganizationsInstancesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsInstancesCreateCall) Context(ctx context.Context) *OrganizationsInstancesCreateCall {
	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 *OrganizationsInstancesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1instance)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.create" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsInstancesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Creates an Apigee runtime instance. The instance is accessible from the authorized network configured on the organization. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.instances.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the organization. Use the following structure in your request: `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/instances",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1Instance"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.delete":

type OrganizationsInstancesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an Apigee runtime instance. The instance stops
// serving requests and the runtime data is deleted. **Note:** Not
// supported for Apigee hybrid.
func (r *OrganizationsInstancesService) Delete(name string) *OrganizationsInstancesDeleteCall {
	c := &OrganizationsInstancesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsInstancesDeleteCall) Fields(s ...googleapi.Field) *OrganizationsInstancesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsInstancesDeleteCall) Context(ctx context.Context) *OrganizationsInstancesDeleteCall {
	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 *OrganizationsInstancesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.delete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsInstancesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes an Apigee runtime instance. The instance stops serving requests and the runtime data is deleted. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances/{instancesId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.instances.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the instance. Use the following structure in your request: `organizations/{org}/instance/{instance}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.get":

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

// Get: Gets the details for an Apigee runtime instance. **Note:** Not
// supported for Apigee hybrid.
func (r *OrganizationsInstancesService) Get(name string) *OrganizationsInstancesGetCall {
	c := &OrganizationsInstancesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsInstancesGetCall) Fields(s ...googleapi.Field) *OrganizationsInstancesGetCall {
	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 *OrganizationsInstancesGetCall) IfNoneMatch(entityTag string) *OrganizationsInstancesGetCall {
	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 *OrganizationsInstancesGetCall) Context(ctx context.Context) *OrganizationsInstancesGetCall {
	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 *OrganizationsInstancesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.get" call.
// Exactly one of *GoogleCloudApigeeV1Instance or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudApigeeV1Instance.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 *OrganizationsInstancesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1Instance, 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 := &GoogleCloudApigeeV1Instance{
		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": "Gets the details for an Apigee runtime instance. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances/{instancesId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.instances.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the instance. Use the following structure in your request: `organizations/{org}/instances/{instance}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1Instance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.list":

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

// List: Lists all Apigee runtime instances for the organization.
// **Note:** Not supported for Apigee hybrid.
func (r *OrganizationsInstancesService) List(parent string) *OrganizationsInstancesListCall {
	c := &OrganizationsInstancesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// instances to return. Defaults to 25.
func (c *OrganizationsInstancesListCall) PageSize(pageSize int64) *OrganizationsInstancesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned from a previous ListInstances call, that you can use to
// retrieve the next page of content.
func (c *OrganizationsInstancesListCall) PageToken(pageToken string) *OrganizationsInstancesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *OrganizationsInstancesListCall) Fields(s ...googleapi.Field) *OrganizationsInstancesListCall {
	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 *OrganizationsInstancesListCall) IfNoneMatch(entityTag string) *OrganizationsInstancesListCall {
	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 *OrganizationsInstancesListCall) Context(ctx context.Context) *OrganizationsInstancesListCall {
	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 *OrganizationsInstancesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/instances")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.list" call.
// Exactly one of *GoogleCloudApigeeV1ListInstancesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListInstancesResponse.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 *OrganizationsInstancesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListInstancesResponse, 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 := &GoogleCloudApigeeV1ListInstancesResponse{
		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": "Lists all Apigee runtime instances for the organization. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.instances.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum number of instances to return. Defaults to 25.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned from a previous ListInstances call, that you can use to retrieve the next page of content.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization. Use the following structure in your request: `organizations/{org}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/instances",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListInstancesResponse"
	//   },
	//   "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 *OrganizationsInstancesListCall) Pages(ctx context.Context, f func(*GoogleCloudApigeeV1ListInstancesResponse) 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 "apigee.organizations.instances.reportStatus":

type OrganizationsInstancesReportStatusCall struct {
	s                                              *Service
	instance                                       string
	googlecloudapigeev1reportinstancestatusrequest *GoogleCloudApigeeV1ReportInstanceStatusRequest
	urlParams_                                     gensupport.URLParams
	ctx_                                           context.Context
	header_                                        http.Header
}

// ReportStatus: Reports the latest status for a runtime instance.
func (r *OrganizationsInstancesService) ReportStatus(instance string, googlecloudapigeev1reportinstancestatusrequest *GoogleCloudApigeeV1ReportInstanceStatusRequest) *OrganizationsInstancesReportStatusCall {
	c := &OrganizationsInstancesReportStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.instance = instance
	c.googlecloudapigeev1reportinstancestatusrequest = googlecloudapigeev1reportinstancestatusrequest
	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 *OrganizationsInstancesReportStatusCall) Fields(s ...googleapi.Field) *OrganizationsInstancesReportStatusCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsInstancesReportStatusCall) Context(ctx context.Context) *OrganizationsInstancesReportStatusCall {
	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 *OrganizationsInstancesReportStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesReportStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1reportinstancestatusrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+instance}:reportStatus")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"instance": c.instance,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.reportStatus" call.
// Exactly one of *GoogleCloudApigeeV1ReportInstanceStatusResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ReportInstanceStatusResponse.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 *OrganizationsInstancesReportStatusCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ReportInstanceStatusResponse, 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 := &GoogleCloudApigeeV1ReportInstanceStatusResponse{
		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": "Reports the latest status for a runtime instance.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances/{instancesId}:reportStatus",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.instances.reportStatus",
	//   "parameterOrder": [
	//     "instance"
	//   ],
	//   "parameters": {
	//     "instance": {
	//       "description": "The name of the instance reporting this status. For SaaS the request will be rejected if no instance exists under this name. Format is organizations/{org}/instances/{instance}",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+instance}:reportStatus",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1ReportInstanceStatusRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ReportInstanceStatusResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.attachments.create":

type OrganizationsInstancesAttachmentsCreateCall struct {
	s                                     *Service
	parent                                string
	googlecloudapigeev1instanceattachment *GoogleCloudApigeeV1InstanceAttachment
	urlParams_                            gensupport.URLParams
	ctx_                                  context.Context
	header_                               http.Header
}

// Create: Creates a new attachment of an environment to an instance.
// **Note:** Not supported for Apigee hybrid.
func (r *OrganizationsInstancesAttachmentsService) Create(parent string, googlecloudapigeev1instanceattachment *GoogleCloudApigeeV1InstanceAttachment) *OrganizationsInstancesAttachmentsCreateCall {
	c := &OrganizationsInstancesAttachmentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1instanceattachment = googlecloudapigeev1instanceattachment
	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 *OrganizationsInstancesAttachmentsCreateCall) Fields(s ...googleapi.Field) *OrganizationsInstancesAttachmentsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsInstancesAttachmentsCreateCall) Context(ctx context.Context) *OrganizationsInstancesAttachmentsCreateCall {
	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 *OrganizationsInstancesAttachmentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesAttachmentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1instanceattachment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/attachments")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.attachments.create" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsInstancesAttachmentsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Creates a new attachment of an environment to an instance. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances/{instancesId}/attachments",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.instances.attachments.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the instance. Use the following structure in your request: `organizations/{org}/instances/{instance}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attachments",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1InstanceAttachment"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.attachments.delete":

type OrganizationsInstancesAttachmentsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an attachment. **Note:** Not supported for Apigee
// hybrid.
func (r *OrganizationsInstancesAttachmentsService) Delete(name string) *OrganizationsInstancesAttachmentsDeleteCall {
	c := &OrganizationsInstancesAttachmentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsInstancesAttachmentsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsInstancesAttachmentsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsInstancesAttachmentsDeleteCall) Context(ctx context.Context) *OrganizationsInstancesAttachmentsDeleteCall {
	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 *OrganizationsInstancesAttachmentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesAttachmentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.attachments.delete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsInstancesAttachmentsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes an attachment. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances/{instancesId}/attachments/{attachmentsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.instances.attachments.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the attachment. Use the following structure in your request: `organizations/{org}/instances/{instance}/attachments/{attachment}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/instances/[^/]+/attachments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.attachments.get":

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

// Get: Gets an attachment. **Note:** Not supported for Apigee hybrid.
func (r *OrganizationsInstancesAttachmentsService) Get(name string) *OrganizationsInstancesAttachmentsGetCall {
	c := &OrganizationsInstancesAttachmentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsInstancesAttachmentsGetCall) Fields(s ...googleapi.Field) *OrganizationsInstancesAttachmentsGetCall {
	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 *OrganizationsInstancesAttachmentsGetCall) IfNoneMatch(entityTag string) *OrganizationsInstancesAttachmentsGetCall {
	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 *OrganizationsInstancesAttachmentsGetCall) Context(ctx context.Context) *OrganizationsInstancesAttachmentsGetCall {
	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 *OrganizationsInstancesAttachmentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesAttachmentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.attachments.get" call.
// Exactly one of *GoogleCloudApigeeV1InstanceAttachment or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudApigeeV1InstanceAttachment.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 *OrganizationsInstancesAttachmentsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1InstanceAttachment, 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 := &GoogleCloudApigeeV1InstanceAttachment{
		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": "Gets an attachment. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances/{instancesId}/attachments/{attachmentsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.instances.attachments.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the attachment. Use the following structure in your request: `organizations/{org}/instances/{instance}/attachments/{attachment}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/instances/[^/]+/attachments/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1InstanceAttachment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.instances.attachments.list":

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

// List: Lists all attachments to an instance. **Note:** Not supported
// for Apigee hybrid.
func (r *OrganizationsInstancesAttachmentsService) List(parent string) *OrganizationsInstancesAttachmentsListCall {
	c := &OrganizationsInstancesAttachmentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// instance attachments to return. Defaults to 25.
func (c *OrganizationsInstancesAttachmentsListCall) PageSize(pageSize int64) *OrganizationsInstancesAttachmentsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous ListInstanceAttachments call, that you can use
// to retrieve the next page of content.
func (c *OrganizationsInstancesAttachmentsListCall) PageToken(pageToken string) *OrganizationsInstancesAttachmentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *OrganizationsInstancesAttachmentsListCall) Fields(s ...googleapi.Field) *OrganizationsInstancesAttachmentsListCall {
	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 *OrganizationsInstancesAttachmentsListCall) IfNoneMatch(entityTag string) *OrganizationsInstancesAttachmentsListCall {
	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 *OrganizationsInstancesAttachmentsListCall) Context(ctx context.Context) *OrganizationsInstancesAttachmentsListCall {
	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 *OrganizationsInstancesAttachmentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsInstancesAttachmentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/attachments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.instances.attachments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListInstanceAttachmentsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListInstanceAttachmentsResponse.ServerResponse.Hea
// der 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 *OrganizationsInstancesAttachmentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListInstanceAttachmentsResponse, 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 := &GoogleCloudApigeeV1ListInstanceAttachmentsResponse{
		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": "Lists all attachments to an instance. **Note:** Not supported for Apigee hybrid.",
	//   "flatPath": "v1/organizations/{organizationsId}/instances/{instancesId}/attachments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.instances.attachments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum number of instance attachments to return. Defaults to 25.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous ListInstanceAttachments call, that you can use to retrieve the next page of content.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the organization. Use the following structure in your request: `organizations/{org}/instances/{instance}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/attachments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListInstanceAttachmentsResponse"
	//   },
	//   "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 *OrganizationsInstancesAttachmentsListCall) Pages(ctx context.Context, f func(*GoogleCloudApigeeV1ListInstanceAttachmentsResponse) 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 "apigee.organizations.keyvaluemaps.create":

type OrganizationsKeyvaluemapsCreateCall struct {
	s                              *Service
	parent                         string
	googlecloudapigeev1keyvaluemap *GoogleCloudApigeeV1KeyValueMap
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Create: Creates a key value map in an organization.
func (r *OrganizationsKeyvaluemapsService) Create(parent string, googlecloudapigeev1keyvaluemap *GoogleCloudApigeeV1KeyValueMap) *OrganizationsKeyvaluemapsCreateCall {
	c := &OrganizationsKeyvaluemapsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1keyvaluemap = googlecloudapigeev1keyvaluemap
	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 *OrganizationsKeyvaluemapsCreateCall) Fields(s ...googleapi.Field) *OrganizationsKeyvaluemapsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsKeyvaluemapsCreateCall) Context(ctx context.Context) *OrganizationsKeyvaluemapsCreateCall {
	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 *OrganizationsKeyvaluemapsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsKeyvaluemapsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1keyvaluemap)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/keyvaluemaps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.keyvaluemaps.create" call.
// Exactly one of *GoogleCloudApigeeV1KeyValueMap or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1KeyValueMap.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 *OrganizationsKeyvaluemapsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1KeyValueMap, 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 := &GoogleCloudApigeeV1KeyValueMap{
		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": "Creates a key value map in an organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/keyvaluemaps",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.keyvaluemaps.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the organization in which to create the key value map file. Must be of the form `organizations/{organization}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/keyvaluemaps",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.keyvaluemaps.delete":

type OrganizationsKeyvaluemapsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Delete a key value map in an organization.
func (r *OrganizationsKeyvaluemapsService) Delete(name string) *OrganizationsKeyvaluemapsDeleteCall {
	c := &OrganizationsKeyvaluemapsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsKeyvaluemapsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsKeyvaluemapsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsKeyvaluemapsDeleteCall) Context(ctx context.Context) *OrganizationsKeyvaluemapsDeleteCall {
	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 *OrganizationsKeyvaluemapsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsKeyvaluemapsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.keyvaluemaps.delete" call.
// Exactly one of *GoogleCloudApigeeV1KeyValueMap or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1KeyValueMap.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 *OrganizationsKeyvaluemapsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1KeyValueMap, 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 := &GoogleCloudApigeeV1KeyValueMap{
		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": "Delete a key value map in an organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/keyvaluemaps/{keyvaluemapsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.keyvaluemaps.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the key value map. Must be of the form `organizations/{organization}/keyvaluemaps/{keyvaluemap}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/keyvaluemaps/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1KeyValueMap"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.operations.get":

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

// Get: Gets the latest state of a long-running operation. Clients can
// use this method to poll the operation result at intervals as
// recommended by the API service.
func (r *OrganizationsOperationsService) Get(name string) *OrganizationsOperationsGetCall {
	c := &OrganizationsOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsOperationsGetCall) Fields(s ...googleapi.Field) *OrganizationsOperationsGetCall {
	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 *OrganizationsOperationsGetCall) IfNoneMatch(entityTag string) *OrganizationsOperationsGetCall {
	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 *OrganizationsOperationsGetCall) Context(ctx context.Context) *OrganizationsOperationsGetCall {
	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 *OrganizationsOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.operations.get" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *OrganizationsOperationsGetCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Gets the latest state of a long-running operation. Clients can use this method to poll the operation result at intervals as recommended by the API service.",
	//   "flatPath": "v1/organizations/{organizationsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.operations.list":

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

// List: Lists operations that match the specified filter in the
// request. If the server doesn't support this method, it returns
// `UNIMPLEMENTED`. NOTE: the `name` binding allows API services to
// override the binding to use different resource name schemes, such as
// `users/*/operations`. To override the binding, API services can add a
// binding such as "/v1/{name=users/*}/operations" to their service
// configuration. For backwards compatibility, the default name includes
// the operations collection id, however overriding users must ensure
// the name binding is the parent resource, without the operations
// collection id.
func (r *OrganizationsOperationsService) List(name string) *OrganizationsOperationsListCall {
	c := &OrganizationsOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *OrganizationsOperationsListCall) Filter(filter string) *OrganizationsOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *OrganizationsOperationsListCall) PageSize(pageSize int64) *OrganizationsOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *OrganizationsOperationsListCall) PageToken(pageToken string) *OrganizationsOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *OrganizationsOperationsListCall) Fields(s ...googleapi.Field) *OrganizationsOperationsListCall {
	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 *OrganizationsOperationsListCall) IfNoneMatch(entityTag string) *OrganizationsOperationsListCall {
	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 *OrganizationsOperationsListCall) Context(ctx context.Context) *OrganizationsOperationsListCall {
	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 *OrganizationsOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}/operations")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.operations.list" call.
// Exactly one of *GoogleLongrunningListOperationsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleLongrunningListOperationsResponse.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 *OrganizationsOperationsListCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningListOperationsResponse, 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 := &GoogleLongrunningListOperationsResponse{
		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": "Lists operations that match the specified filter in the request. If the server doesn't support this method, it returns `UNIMPLEMENTED`. NOTE: the `name` binding allows API services to override the binding to use different resource name schemes, such as `users/*/operations`. To override the binding, API services can add a binding such as `\"/v1/{name=users/*}/operations\"` to their service configuration. For backwards compatibility, the default name includes the operations collection id, however overriding users must ensure the name binding is the parent resource, without the operations collection id.",
	//   "flatPath": "v1/organizations/{organizationsId}/operations",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}/operations",
	//   "response": {
	//     "$ref": "GoogleLongrunningListOperationsResponse"
	//   },
	//   "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 *OrganizationsOperationsListCall) Pages(ctx context.Context, f func(*GoogleLongrunningListOperationsResponse) 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 "apigee.organizations.reports.create":

type OrganizationsReportsCreateCall struct {
	s                               *Service
	parent                          string
	googlecloudapigeev1customreport *GoogleCloudApigeeV1CustomReport
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Create: Creates a Custom Report for an Organization. A Custom Report
// provides Apigee Customers to create custom dashboards in addition to
// the standard dashboards which are provided. The Custom Report in its
// simplest form contains specifications about metrics, dimensions and
// filters. It is important to note that the custom report by itself
// does not provide an executable entity. The Edge UI converts the
// custom report definition into an analytics query and displays the
// result in a chart.
func (r *OrganizationsReportsService) Create(parent string, googlecloudapigeev1customreport *GoogleCloudApigeeV1CustomReport) *OrganizationsReportsCreateCall {
	c := &OrganizationsReportsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudapigeev1customreport = googlecloudapigeev1customreport
	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 *OrganizationsReportsCreateCall) Fields(s ...googleapi.Field) *OrganizationsReportsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsReportsCreateCall) Context(ctx context.Context) *OrganizationsReportsCreateCall {
	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 *OrganizationsReportsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsReportsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1customreport)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/reports")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.reports.create" call.
// Exactly one of *GoogleCloudApigeeV1CustomReport or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1CustomReport.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 *OrganizationsReportsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1CustomReport, 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 := &GoogleCloudApigeeV1CustomReport{
		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": "Creates a Custom Report for an Organization. A Custom Report provides Apigee Customers to create custom dashboards in addition to the standard dashboards which are provided. The Custom Report in its simplest form contains specifications about metrics, dimensions and filters. It is important to note that the custom report by itself does not provide an executable entity. The Edge UI converts the custom report definition into an analytics query and displays the result in a chart.",
	//   "flatPath": "v1/organizations/{organizationsId}/reports",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.reports.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent organization name under which the Custom Report will be created. Must be of the form: `organizations/{organization_id}/reports`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/reports",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1CustomReport"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1CustomReport"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.reports.delete":

type OrganizationsReportsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing custom report definition
func (r *OrganizationsReportsService) Delete(name string) *OrganizationsReportsDeleteCall {
	c := &OrganizationsReportsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsReportsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsReportsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsReportsDeleteCall) Context(ctx context.Context) *OrganizationsReportsDeleteCall {
	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 *OrganizationsReportsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsReportsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.reports.delete" call.
// Exactly one of *GoogleCloudApigeeV1DeleteCustomReportResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1DeleteCustomReportResponse.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 *OrganizationsReportsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1DeleteCustomReportResponse, 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 := &GoogleCloudApigeeV1DeleteCustomReportResponse{
		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": "Deletes an existing custom report definition",
	//   "flatPath": "v1/organizations/{organizationsId}/reports/{reportsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.reports.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Custom Report name of the form: `organizations/{organization_id}/reports/{report_name}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/reports/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1DeleteCustomReportResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.reports.get":

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

// Get: Retrieve a custom report definition.
func (r *OrganizationsReportsService) Get(name string) *OrganizationsReportsGetCall {
	c := &OrganizationsReportsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsReportsGetCall) Fields(s ...googleapi.Field) *OrganizationsReportsGetCall {
	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 *OrganizationsReportsGetCall) IfNoneMatch(entityTag string) *OrganizationsReportsGetCall {
	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 *OrganizationsReportsGetCall) Context(ctx context.Context) *OrganizationsReportsGetCall {
	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 *OrganizationsReportsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsReportsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.reports.get" call.
// Exactly one of *GoogleCloudApigeeV1CustomReport or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1CustomReport.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 *OrganizationsReportsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1CustomReport, 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 := &GoogleCloudApigeeV1CustomReport{
		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": "Retrieve a custom report definition.",
	//   "flatPath": "v1/organizations/{organizationsId}/reports/{reportsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.reports.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Custom Report name of the form: `organizations/{organization_id}/reports/{report_name}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/reports/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1CustomReport"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.reports.list":

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

// List: Return a list of Custom Reports
func (r *OrganizationsReportsService) List(parent string) *OrganizationsReportsListCall {
	c := &OrganizationsReportsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Expand sets the optional parameter "expand": Set to 'true' to get
// expanded details about each custom report.
func (c *OrganizationsReportsListCall) Expand(expand bool) *OrganizationsReportsListCall {
	c.urlParams_.Set("expand", fmt.Sprint(expand))
	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 *OrganizationsReportsListCall) Fields(s ...googleapi.Field) *OrganizationsReportsListCall {
	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 *OrganizationsReportsListCall) IfNoneMatch(entityTag string) *OrganizationsReportsListCall {
	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 *OrganizationsReportsListCall) Context(ctx context.Context) *OrganizationsReportsListCall {
	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 *OrganizationsReportsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsReportsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/reports")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.reports.list" call.
// Exactly one of *GoogleCloudApigeeV1ListCustomReportsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListCustomReportsResponse.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 *OrganizationsReportsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListCustomReportsResponse, 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 := &GoogleCloudApigeeV1ListCustomReportsResponse{
		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": "Return a list of Custom Reports",
	//   "flatPath": "v1/organizations/{organizationsId}/reports",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.reports.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "expand": {
	//       "description": "Set to 'true' to get expanded details about each custom report.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. The parent organization name under which the API product will be listed `organizations/{organization_id}/reports`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/reports",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListCustomReportsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.reports.update":

type OrganizationsReportsUpdateCall struct {
	s                               *Service
	name                            string
	googlecloudapigeev1customreport *GoogleCloudApigeeV1CustomReport
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Update: Update an existing custom report definition
func (r *OrganizationsReportsService) Update(name string, googlecloudapigeev1customreport *GoogleCloudApigeeV1CustomReport) *OrganizationsReportsUpdateCall {
	c := &OrganizationsReportsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudapigeev1customreport = googlecloudapigeev1customreport
	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 *OrganizationsReportsUpdateCall) Fields(s ...googleapi.Field) *OrganizationsReportsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsReportsUpdateCall) Context(ctx context.Context) *OrganizationsReportsUpdateCall {
	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 *OrganizationsReportsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsReportsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudapigeev1customreport)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.reports.update" call.
// Exactly one of *GoogleCloudApigeeV1CustomReport or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1CustomReport.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 *OrganizationsReportsUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1CustomReport, 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 := &GoogleCloudApigeeV1CustomReport{
		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": "Update an existing custom report definition",
	//   "flatPath": "v1/organizations/{organizationsId}/reports/{reportsId}",
	//   "httpMethod": "PUT",
	//   "id": "apigee.organizations.reports.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Custom Report name of the form: `organizations/{organization_id}/reports/{report_name}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/reports/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudApigeeV1CustomReport"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1CustomReport"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.create":

type OrganizationsSharedflowsCreateCall struct {
	s                 *Service
	parent            string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Uploads a ZIP-formatted shared flow configuration bundle to
// an organization. If the shared flow already exists, this creates a
// new revision of it. If the shared flow does not exist, this creates
// it. Once imported, the shared flow revision must be deployed before
// it can be accessed at runtime. The size limit of a shared flow bundle
// is 15 MB.
func (r *OrganizationsSharedflowsService) Create(parent string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsSharedflowsCreateCall {
	c := &OrganizationsSharedflowsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleapihttpbody = googleapihttpbody
	return c
}

// Action sets the optional parameter "action": Required. Must be set to
// either `import` or `validate`.
func (c *OrganizationsSharedflowsCreateCall) Action(action string) *OrganizationsSharedflowsCreateCall {
	c.urlParams_.Set("action", action)
	return c
}

// Name sets the optional parameter "name": Required. The name to give
// the shared flow
func (c *OrganizationsSharedflowsCreateCall) Name(name string) *OrganizationsSharedflowsCreateCall {
	c.urlParams_.Set("name", name)
	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 *OrganizationsSharedflowsCreateCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsSharedflowsCreateCall) Context(ctx context.Context) *OrganizationsSharedflowsCreateCall {
	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 *OrganizationsSharedflowsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/sharedflows")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.create" call.
// Exactly one of *GoogleCloudApigeeV1SharedFlowRevision or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudApigeeV1SharedFlowRevision.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 *OrganizationsSharedflowsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1SharedFlowRevision, 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 := &GoogleCloudApigeeV1SharedFlowRevision{
		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": "Uploads a ZIP-formatted shared flow configuration bundle to an organization. If the shared flow already exists, this creates a new revision of it. If the shared flow does not exist, this creates it. Once imported, the shared flow revision must be deployed before it can be accessed at runtime. The size limit of a shared flow bundle is 15 MB.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.sharedflows.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Required. Must be set to either `import` or `validate`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The name to give the shared flow",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The name of the parent organization under which to create the shared flow. Must be of the form: `organizations/{organization_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/sharedflows",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1SharedFlowRevision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.delete":

type OrganizationsSharedflowsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a shared flow and all it's revisions. The shared flow
// must be undeployed before you can delete it.
func (r *OrganizationsSharedflowsService) Delete(name string) *OrganizationsSharedflowsDeleteCall {
	c := &OrganizationsSharedflowsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsSharedflowsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsSharedflowsDeleteCall) Context(ctx context.Context) *OrganizationsSharedflowsDeleteCall {
	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 *OrganizationsSharedflowsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.delete" call.
// Exactly one of *GoogleCloudApigeeV1SharedFlow or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1SharedFlow.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 *OrganizationsSharedflowsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1SharedFlow, 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 := &GoogleCloudApigeeV1SharedFlow{
		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": "Deletes a shared flow and all it's revisions. The shared flow must be undeployed before you can delete it.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows/{sharedflowsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.sharedflows.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. shared flow name of the form: `organizations/{organization_id}/sharedflows/{shared_flow_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sharedflows/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1SharedFlow"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.get":

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

// Get: Gets a shared flow by name, including a list of its revisions.
func (r *OrganizationsSharedflowsService) Get(name string) *OrganizationsSharedflowsGetCall {
	c := &OrganizationsSharedflowsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsSharedflowsGetCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsGetCall {
	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 *OrganizationsSharedflowsGetCall) IfNoneMatch(entityTag string) *OrganizationsSharedflowsGetCall {
	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 *OrganizationsSharedflowsGetCall) Context(ctx context.Context) *OrganizationsSharedflowsGetCall {
	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 *OrganizationsSharedflowsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.get" call.
// Exactly one of *GoogleCloudApigeeV1SharedFlow or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudApigeeV1SharedFlow.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 *OrganizationsSharedflowsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1SharedFlow, 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 := &GoogleCloudApigeeV1SharedFlow{
		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": "Gets a shared flow by name, including a list of its revisions.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows/{sharedflowsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.sharedflows.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the shared flow to get. Must be of the form: `organizations/{organization_id}/sharedflows/{shared_flow_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sharedflows/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1SharedFlow"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.list":

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

// List: Lists all shared flows in the organization.
func (r *OrganizationsSharedflowsService) List(parent string) *OrganizationsSharedflowsListCall {
	c := &OrganizationsSharedflowsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// IncludeMetaData sets the optional parameter "includeMetaData":
// Indicates whether to include shared flow metadata in the response.
func (c *OrganizationsSharedflowsListCall) IncludeMetaData(includeMetaData bool) *OrganizationsSharedflowsListCall {
	c.urlParams_.Set("includeMetaData", fmt.Sprint(includeMetaData))
	return c
}

// IncludeRevisions sets the optional parameter "includeRevisions":
// Indicates whether to include a list of revisions in the response.
func (c *OrganizationsSharedflowsListCall) IncludeRevisions(includeRevisions bool) *OrganizationsSharedflowsListCall {
	c.urlParams_.Set("includeRevisions", fmt.Sprint(includeRevisions))
	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 *OrganizationsSharedflowsListCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsListCall {
	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 *OrganizationsSharedflowsListCall) IfNoneMatch(entityTag string) *OrganizationsSharedflowsListCall {
	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 *OrganizationsSharedflowsListCall) Context(ctx context.Context) *OrganizationsSharedflowsListCall {
	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 *OrganizationsSharedflowsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/sharedflows")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.list" call.
// Exactly one of *GoogleCloudApigeeV1ListSharedFlowsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListSharedFlowsResponse.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 *OrganizationsSharedflowsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListSharedFlowsResponse, 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 := &GoogleCloudApigeeV1ListSharedFlowsResponse{
		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": "Lists all shared flows in the organization.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.sharedflows.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "includeMetaData": {
	//       "description": "Indicates whether to include shared flow metadata in the response.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "includeRevisions": {
	//       "description": "Indicates whether to include a list of revisions in the response.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. The name of the parent organization under which to get shared flows. Must be of the form: `organizations/{organization_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/sharedflows",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListSharedFlowsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.deployments.list":

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

// List: Lists all deployments of a shared flow.
func (r *OrganizationsSharedflowsDeploymentsService) List(parent string) *OrganizationsSharedflowsDeploymentsListCall {
	c := &OrganizationsSharedflowsDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsSharedflowsDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsDeploymentsListCall {
	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 *OrganizationsSharedflowsDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsSharedflowsDeploymentsListCall {
	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 *OrganizationsSharedflowsDeploymentsListCall) Context(ctx context.Context) *OrganizationsSharedflowsDeploymentsListCall {
	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 *OrganizationsSharedflowsDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsSharedflowsDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of a shared flow.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows/{sharedflowsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.sharedflows.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the shared flow for which to return deployment information in the following format: `organizations/{org}/sharedflows/{sharedflow}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sharedflows/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.revisions.delete":

type OrganizationsSharedflowsRevisionsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a shared flow and all associated policies, resources,
// and revisions. You must undeploy the shared flow before deleting it.
func (r *OrganizationsSharedflowsRevisionsService) Delete(name string) *OrganizationsSharedflowsRevisionsDeleteCall {
	c := &OrganizationsSharedflowsRevisionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *OrganizationsSharedflowsRevisionsDeleteCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsRevisionsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsSharedflowsRevisionsDeleteCall) Context(ctx context.Context) *OrganizationsSharedflowsRevisionsDeleteCall {
	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 *OrganizationsSharedflowsRevisionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsRevisionsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.revisions.delete" call.
// Exactly one of *GoogleCloudApigeeV1SharedFlowRevision or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudApigeeV1SharedFlowRevision.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 *OrganizationsSharedflowsRevisionsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1SharedFlowRevision, 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 := &GoogleCloudApigeeV1SharedFlowRevision{
		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": "Deletes a shared flow and all associated policies, resources, and revisions. You must undeploy the shared flow before deleting it.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows/{sharedflowsId}/revisions/{revisionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "apigee.organizations.sharedflows.revisions.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the shared flow revision to delete. Must be of the form: `organizations/{organization_id}/sharedflows/{shared_flow_id}/revisions/{revision_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sharedflows/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1SharedFlowRevision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.revisions.get":

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

// Get: Gets a revision of a shared flow. If `format=bundle` is passed,
// it instead outputs a shared flow revision as a ZIP-formatted bundle
// of code and config files.
func (r *OrganizationsSharedflowsRevisionsService) Get(name string) *OrganizationsSharedflowsRevisionsGetCall {
	c := &OrganizationsSharedflowsRevisionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Format sets the optional parameter "format": Specify `bundle` to
// export the contents of the shared flow bundle. Otherwise, the bundle
// metadata is returned.
func (c *OrganizationsSharedflowsRevisionsGetCall) Format(format string) *OrganizationsSharedflowsRevisionsGetCall {
	c.urlParams_.Set("format", format)
	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 *OrganizationsSharedflowsRevisionsGetCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsRevisionsGetCall {
	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 *OrganizationsSharedflowsRevisionsGetCall) IfNoneMatch(entityTag string) *OrganizationsSharedflowsRevisionsGetCall {
	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 *OrganizationsSharedflowsRevisionsGetCall) Context(ctx context.Context) *OrganizationsSharedflowsRevisionsGetCall {
	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 *OrganizationsSharedflowsRevisionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsRevisionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.revisions.get" call.
// Exactly one of *GoogleApiHttpBody or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleApiHttpBody.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 *OrganizationsSharedflowsRevisionsGetCall) Do(opts ...googleapi.CallOption) (*GoogleApiHttpBody, 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 := &GoogleApiHttpBody{
		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": "Gets a revision of a shared flow. If `format=bundle` is passed, it instead outputs a shared flow revision as a ZIP-formatted bundle of code and config files.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows/{sharedflowsId}/revisions/{revisionsId}",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.sharedflows.revisions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "format": {
	//       "description": "Specify `bundle` to export the contents of the shared flow bundle. Otherwise, the bundle metadata is returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The name of the shared flow revision to get. Must be of the form: `organizations/{organization_id}/sharedflows/{shared_flow_id}/revisions/{revision_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sharedflows/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.revisions.updateSharedFlowRevision":

type OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall struct {
	s                 *Service
	name              string
	googleapihttpbody *GoogleApiHttpBody
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// UpdateSharedFlowRevision: Updates a shared flow revision. This
// operation is only allowed on revisions which have never been
// deployed. After deployment a revision becomes immutable, even if it
// becomes undeployed. The payload is a ZIP-formatted shared flow.
// Content type must be either multipart/form-data or
// application/octet-stream.
func (r *OrganizationsSharedflowsRevisionsService) UpdateSharedFlowRevision(name string, googleapihttpbody *GoogleApiHttpBody) *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall {
	c := &OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googleapihttpbody = googleapihttpbody
	return c
}

// Validate sets the optional parameter "validate": Ignored. All uploads
// are validated regardless of the value of this field. It is kept for
// compatibility with existing APIs. Must be `true` or `false` if
// provided.
func (c *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall) Validate(validate bool) *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall {
	c.urlParams_.Set("validate", fmt.Sprint(validate))
	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 *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall) Context(ctx context.Context) *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall {
	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 *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googleapihttpbody)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.revisions.updateSharedFlowRevision" call.
// Exactly one of *GoogleCloudApigeeV1SharedFlowRevision or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudApigeeV1SharedFlowRevision.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 *OrganizationsSharedflowsRevisionsUpdateSharedFlowRevisionCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1SharedFlowRevision, 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 := &GoogleCloudApigeeV1SharedFlowRevision{
		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": "Updates a shared flow revision. This operation is only allowed on revisions which have never been deployed. After deployment a revision becomes immutable, even if it becomes undeployed. The payload is a ZIP-formatted shared flow. Content type must be either multipart/form-data or application/octet-stream.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows/{sharedflowsId}/revisions/{revisionsId}",
	//   "httpMethod": "POST",
	//   "id": "apigee.organizations.sharedflows.revisions.updateSharedFlowRevision",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the shared flow revision to update. Must be of the form: `organizations/{organization_id}/sharedflows/{shared_flow_id}/revisions/{revision_id}`",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sharedflows/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "validate": {
	//       "description": "Ignored. All uploads are validated regardless of the value of this field. It is kept for compatibility with existing APIs. Must be `true` or `false` if provided.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "GoogleApiHttpBody"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1SharedFlowRevision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "apigee.organizations.sharedflows.revisions.deployments.list":

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

// List: Lists all deployments of a shared flow revision.
func (r *OrganizationsSharedflowsRevisionsDeploymentsService) List(parent string) *OrganizationsSharedflowsRevisionsDeploymentsListCall {
	c := &OrganizationsSharedflowsRevisionsDeploymentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *OrganizationsSharedflowsRevisionsDeploymentsListCall) Fields(s ...googleapi.Field) *OrganizationsSharedflowsRevisionsDeploymentsListCall {
	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 *OrganizationsSharedflowsRevisionsDeploymentsListCall) IfNoneMatch(entityTag string) *OrganizationsSharedflowsRevisionsDeploymentsListCall {
	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 *OrganizationsSharedflowsRevisionsDeploymentsListCall) Context(ctx context.Context) *OrganizationsSharedflowsRevisionsDeploymentsListCall {
	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 *OrganizationsSharedflowsRevisionsDeploymentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrganizationsSharedflowsRevisionsDeploymentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200820")
	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, "v1/{+parent}/deployments")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "apigee.organizations.sharedflows.revisions.deployments.list" call.
// Exactly one of *GoogleCloudApigeeV1ListDeploymentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudApigeeV1ListDeploymentsResponse.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 *OrganizationsSharedflowsRevisionsDeploymentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudApigeeV1ListDeploymentsResponse, 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 := &GoogleCloudApigeeV1ListDeploymentsResponse{
		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": "Lists all deployments of a shared flow revision.",
	//   "flatPath": "v1/organizations/{organizationsId}/sharedflows/{sharedflowsId}/revisions/{revisionsId}/deployments",
	//   "httpMethod": "GET",
	//   "id": "apigee.organizations.sharedflows.revisions.deployments.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Name of the API proxy revision for which to return deployment information in the following format: `organizations/{org}/sharedflows/{sharedflow}/revisions/{rev}`.",
	//       "location": "path",
	//       "pattern": "^organizations/[^/]+/sharedflows/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/deployments",
	//   "response": {
	//     "$ref": "GoogleCloudApigeeV1ListDeploymentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
