// 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 jobs provides access to the Cloud Talent Solution API.
//
// For product documentation, see: https://cloud.google.com/talent-solution/job-search/docs/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/jobs/v3p1beta1"
//   ...
//   ctx := context.Background()
//   jobsService, err := jobs.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
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   jobsService, err := jobs.NewService(ctx, option.WithScopes(jobs.JobsScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   jobsService, err := jobs.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, ...)
//   jobsService, err := jobs.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package jobs // import "google.golang.org/api/jobs/v3p1beta1"

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 = "jobs:v3p1beta1"
const apiName = "jobs"
const apiVersion = "v3p1beta1"
const basePath = "https://jobs.googleapis.com/"
const mtlsBasePath = "https://jobs.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"

	// Manage job postings
	JobsScope = "https://www.googleapis.com/auth/jobs"
)

// 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",
		"https://www.googleapis.com/auth/jobs",
	)
	// 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.Projects = NewProjectsService(s)
	return s, nil
}

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

	Projects *ProjectsService
}

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

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.ClientEvents = NewProjectsClientEventsService(s)
	rs.Companies = NewProjectsCompaniesService(s)
	rs.Jobs = NewProjectsJobsService(s)
	rs.Operations = NewProjectsOperationsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	ClientEvents *ProjectsClientEventsService

	Companies *ProjectsCompaniesService

	Jobs *ProjectsJobsService

	Operations *ProjectsOperationsService
}

func NewProjectsClientEventsService(s *Service) *ProjectsClientEventsService {
	rs := &ProjectsClientEventsService{s: s}
	return rs
}

type ProjectsClientEventsService struct {
	s *Service
}

func NewProjectsCompaniesService(s *Service) *ProjectsCompaniesService {
	rs := &ProjectsCompaniesService{s: s}
	return rs
}

type ProjectsCompaniesService struct {
	s *Service
}

func NewProjectsJobsService(s *Service) *ProjectsJobsService {
	rs := &ProjectsJobsService{s: s}
	return rs
}

type ProjectsJobsService struct {
	s *Service
}

func NewProjectsOperationsService(s *Service) *ProjectsOperationsService {
	rs := &ProjectsOperationsService{s: s}
	return rs
}

type ProjectsOperationsService struct {
	s *Service
}

// ApplicationInfo: Application related details of a job posting.
type ApplicationInfo struct {
	// Emails: Optional but at least one of uris, emails or instruction must
	// be specified. Use this field to specify email address(es) to which
	// resumes or applications can be sent. The maximum number of allowed
	// characters for each entry is 255.
	Emails []string `json:"emails,omitempty"`

	// Instruction: Optional but at least one of uris, emails or instruction
	// must be specified. Use this field to provide instructions, such as
	// "Mail your application to ...", that a candidate can follow to apply
	// for the job. This field accepts and sanitizes HTML input, and also
	// accepts bold, italic, ordered list, and unordered list markup tags.
	// The maximum number of allowed characters is 3,000.
	Instruction string `json:"instruction,omitempty"`

	// Uris: Optional but at least one of uris, emails or instruction must
	// be specified. Use this URI field to direct an applicant to a website,
	// for example to link to an online application form. The maximum number
	// of allowed characters for each entry is 2,000.
	Uris []string `json:"uris,omitempty"`

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

// BatchDeleteJobsRequest: Input only. Batch delete jobs request.
type BatchDeleteJobsRequest struct {
	// Filter: Required. The filter string specifies the jobs to be deleted.
	// Supported operator: =, AND The fields eligible for filtering are: *
	// `companyName` (Required) * `requisitionId` (Required) Sample Query:
	// companyName = "projects/api-test-project/companies/123" AND
	// requisitionId = "req-1"
	Filter string `json:"filter,omitempty"`

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

// BucketRange: Represents starting and ending value of a range in
// double.
type BucketRange struct {
	// From: Starting value of the bucket range.
	From float64 `json:"from,omitempty"`

	// To: Ending value of the bucket range.
	To float64 `json:"to,omitempty"`

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

func (s *BucketRange) UnmarshalJSON(data []byte) error {
	type NoMethod BucketRange
	var s1 struct {
		From gensupport.JSONFloat64 `json:"from"`
		To   gensupport.JSONFloat64 `json:"to"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.From = float64(s1.From)
	s.To = float64(s1.To)
	return nil
}

// BucketizedCount: Represents count of jobs within one bucket.
type BucketizedCount struct {
	// Count: Number of jobs whose numeric field value fall into `range`.
	Count int64 `json:"count,omitempty"`

	// Range: Bucket range on which histogram was performed for the numeric
	// field, that is, the count represents number of jobs in this range.
	Range *BucketRange `json:"range,omitempty"`

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

// ClientEvent: An event issued when an end user interacts with the
// application that implements Cloud Talent Solution. Providing this
// information improves the quality of search and recommendation for the
// API clients, enabling the service to perform optimally. The number of
// events sent must be consistent with other calls, such as job
// searches, issued to the service by the client.
type ClientEvent struct {
	// CreateTime: Required. The timestamp of the event.
	CreateTime string `json:"createTime,omitempty"`

	// EventId: Required. A unique identifier, generated by the client
	// application. This `event_id` is used to establish the relationship
	// between different events (see parent_event_id).
	EventId string `json:"eventId,omitempty"`

	// ExtraInfo: Optional. Extra information about this event. Used for
	// storing information with no matching field in event payload, for
	// example, user application specific context or details. At most 20
	// keys are supported. The maximum total size of all keys and values is
	// 2 KB.
	ExtraInfo map[string]string `json:"extraInfo,omitempty"`

	// JobEvent: A event issued when a job seeker interacts with the
	// application that implements Cloud Talent Solution.
	JobEvent *JobEvent `json:"jobEvent,omitempty"`

	// ParentEventId: Optional. The event_id of an event that resulted in
	// the current event. For example, a Job view event usually follows a
	// parent impression event: A job seeker first does a search where a
	// list of jobs appears (impression). The job seeker then selects a
	// result and views the description of a particular job (Job view).
	ParentEventId string `json:"parentEventId,omitempty"`

	// RequestId: Required. A unique ID generated in the API responses. It
	// can be found in ResponseMetadata.request_id.
	RequestId string `json:"requestId,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 *ClientEvent) MarshalJSON() ([]byte, error) {
	type NoMethod ClientEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CommuteFilter: Input only. Parameters needed for commute search.
type CommuteFilter struct {
	// AllowImpreciseAddresses: Optional. If true, jobs without "precise"
	// addresses (street level addresses or GPS coordinates) might also be
	// returned. For city and coarser level addresses, text matching is
	// used. If this field is set to false or is not specified, only jobs
	// that include precise addresses are returned by Commute Search. Note:
	// If `allow_imprecise_addresses` is set to true, Commute Search is not
	// able to calculate accurate commute times to jobs with city level and
	// coarser address information. Jobs with imprecise addresses will
	// return a `travel_duration` time of 0 regardless of distance from the
	// job seeker.
	AllowImpreciseAddresses bool `json:"allowImpreciseAddresses,omitempty"`

	// CommuteMethod: Required. The method of transportation for which to
	// calculate the commute time.
	//
	// Possible values:
	//   "COMMUTE_METHOD_UNSPECIFIED" - Commute method is not specified.
	//   "DRIVING" - Commute time is calculated based on driving time.
	//   "TRANSIT" - Commute time is calculated based on public transit
	// including bus, metro, subway, etc.
	//   "WALKING" - Commute time is calculated based on walking time.
	//   "CYCLING" - Commute time is calculated based on biking time.
	CommuteMethod string `json:"commuteMethod,omitempty"`

	// DepartureTime: Optional. The departure time used to calculate traffic
	// impact, represented as google.type.TimeOfDay in local time zone.
	// Currently traffic model is restricted to hour level resolution.
	DepartureTime *TimeOfDay `json:"departureTime,omitempty"`

	// RoadTraffic: Optional. Specifies the traffic density to use when
	// calculating commute time.
	//
	// Possible values:
	//   "ROAD_TRAFFIC_UNSPECIFIED" - Road traffic situation is not
	// specified.
	//   "TRAFFIC_FREE" - Optimal commute time without considering any
	// traffic impact.
	//   "BUSY_HOUR" - Commute time calculation takes in account the peak
	// traffic impact.
	RoadTraffic string `json:"roadTraffic,omitempty"`

	// StartCoordinates: Required. The latitude and longitude of the
	// location from which to calculate the commute time.
	StartCoordinates *LatLng `json:"startCoordinates,omitempty"`

	// TravelDuration: Required. The maximum travel time in seconds. The
	// maximum allowed value is `3600s` (one hour). Format is `123s`.
	TravelDuration string `json:"travelDuration,omitempty"`

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

// CommuteInfo: Output only. Commute details related to this job.
type CommuteInfo struct {
	// JobLocation: Location used as the destination in the commute
	// calculation.
	JobLocation *Location `json:"jobLocation,omitempty"`

	// TravelDuration: The number of seconds required to travel to the job
	// location from the query location. A duration of 0 seconds indicates
	// that the job is not reachable within the requested duration, but was
	// returned as part of an expanded query.
	TravelDuration string `json:"travelDuration,omitempty"`

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

// Company: A Company resource represents a company in the service. A
// company is the entity that owns job postings, that is, the hiring
// entity responsible for employing applicants for the job position.
type Company struct {
	// CareerSiteUri: Optional. The URI to employer's career site or careers
	// page on the employer's web site, for example,
	// "https://careers.google.com".
	CareerSiteUri string `json:"careerSiteUri,omitempty"`

	// DerivedInfo: Output only. Derived details about the company.
	DerivedInfo *CompanyDerivedInfo `json:"derivedInfo,omitempty"`

	// DisplayName: Required. The display name of the company, for example,
	// "Google LLC".
	DisplayName string `json:"displayName,omitempty"`

	// EeoText: Optional. Equal Employment Opportunity legal disclaimer text
	// to be associated with all jobs, and typically to be displayed in all
	// roles. The maximum number of allowed characters is 500.
	EeoText string `json:"eeoText,omitempty"`

	// ExternalId: Required. Client side company identifier, used to
	// uniquely identify the company. The maximum number of allowed
	// characters is 255.
	ExternalId string `json:"externalId,omitempty"`

	// HeadquartersAddress: Optional. The street address of the company's
	// main headquarters, which may be different from the job location. The
	// service attempts to geolocate the provided address, and populates a
	// more specific location wherever possible in
	// DerivedInfo.headquarters_location.
	HeadquartersAddress string `json:"headquartersAddress,omitempty"`

	// HiringAgency: Optional. Set to true if it is the hiring agency that
	// post jobs for other employers. Defaults to false if not provided.
	HiringAgency bool `json:"hiringAgency,omitempty"`

	// ImageUri: Optional. A URI that hosts the employer's company logo.
	ImageUri string `json:"imageUri,omitempty"`

	// KeywordSearchableJobCustomAttributes: Optional. A list of keys of
	// filterable Job.custom_attributes, whose corresponding `string_values`
	// are used in keyword search. Jobs with `string_values` under these
	// specified field keys are returned if any of the values matches the
	// search keyword. Custom field values with parenthesis, brackets and
	// special symbols won't be properly searchable, and those keyword
	// queries need to be surrounded by quotes.
	KeywordSearchableJobCustomAttributes []string `json:"keywordSearchableJobCustomAttributes,omitempty"`

	// Name: Required during company update. The resource name for a
	// company. This is generated by the service when a company is created.
	// The format is "projects/{project_id}/companies/{company_id}", for
	// example, "projects/api-test-project/companies/foo".
	Name string `json:"name,omitempty"`

	// Size: Optional. The employer's company size.
	//
	// Possible values:
	//   "COMPANY_SIZE_UNSPECIFIED" - Default value if the size is not
	// specified.
	//   "MINI" - The company has less than 50 employees.
	//   "SMALL" - The company has between 50 and 99 employees.
	//   "SMEDIUM" - The company has between 100 and 499 employees.
	//   "MEDIUM" - The company has between 500 and 999 employees.
	//   "BIG" - The company has between 1,000 and 4,999 employees.
	//   "BIGGER" - The company has between 5,000 and 9,999 employees.
	//   "GIANT" - The company has 10,000 or more employees.
	Size string `json:"size,omitempty"`

	// Suspended: Output only. Indicates whether a company is flagged to be
	// suspended from public availability by the service when job content
	// appears suspicious, abusive, or spammy.
	Suspended bool `json:"suspended,omitempty"`

	// WebsiteUri: Optional. The URI representing the company's primary web
	// site or home page, for example, "https://www.google.com". The maximum
	// number of allowed characters is 255.
	WebsiteUri string `json:"websiteUri,omitempty"`

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

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

// CompanyDerivedInfo: Derived details about the company.
type CompanyDerivedInfo struct {
	// HeadquartersLocation: A structured headquarters location of the
	// company, resolved from Company.hq_location if provided.
	HeadquartersLocation *Location `json:"headquartersLocation,omitempty"`

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

// CompensationEntry: A compensation entry that represents one component
// of compensation, such as base pay, bonus, or other compensation type.
// Annualization: One compensation entry can be annualized if - it
// contains valid amount or range. - and its expected_units_per_year is
// set or can be derived. Its annualized range is determined as (amount
// or range) times expected_units_per_year.
type CompensationEntry struct {
	// Amount: Optional. Compensation amount.
	Amount *Money `json:"amount,omitempty"`

	// Description: Optional. Compensation description. For example, could
	// indicate equity terms or provide additional context to an estimated
	// bonus.
	Description string `json:"description,omitempty"`

	// ExpectedUnitsPerYear: Optional. Expected number of units paid each
	// year. If not specified, when Job.employment_types is FULLTIME, a
	// default value is inferred based on unit. Default values: - HOURLY:
	// 2080 - DAILY: 260 - WEEKLY: 52 - MONTHLY: 12 - ANNUAL: 1
	ExpectedUnitsPerYear float64 `json:"expectedUnitsPerYear,omitempty"`

	// Range: Optional. Compensation range.
	Range *CompensationRange `json:"range,omitempty"`

	// Type: Optional. Compensation type. Default is
	// CompensationUnit.COMPENSATION_TYPE_UNSPECIFIED.
	//
	// Possible values:
	//   "COMPENSATION_TYPE_UNSPECIFIED" - Default value.
	//   "BASE" - Base compensation: Refers to the fixed amount of money
	// paid to an employee by an employer in return for work performed. Base
	// compensation does not include benefits, bonuses or any other
	// potential compensation from an employer.
	//   "BONUS" - Bonus.
	//   "SIGNING_BONUS" - Signing bonus.
	//   "EQUITY" - Equity.
	//   "PROFIT_SHARING" - Profit sharing.
	//   "COMMISSIONS" - Commission.
	//   "TIPS" - Tips.
	//   "OTHER_COMPENSATION_TYPE" - Other compensation type.
	Type string `json:"type,omitempty"`

	// Unit: Optional. Frequency of the specified amount. Default is
	// CompensationUnit.COMPENSATION_UNIT_UNSPECIFIED.
	//
	// Possible values:
	//   "COMPENSATION_UNIT_UNSPECIFIED" - Default value.
	//   "HOURLY" - Hourly.
	//   "DAILY" - Daily.
	//   "WEEKLY" - Weekly
	//   "MONTHLY" - Monthly.
	//   "YEARLY" - Yearly.
	//   "ONE_TIME" - One time.
	//   "OTHER_COMPENSATION_UNIT" - Other compensation units.
	Unit string `json:"unit,omitempty"`

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

func (s *CompensationEntry) UnmarshalJSON(data []byte) error {
	type NoMethod CompensationEntry
	var s1 struct {
		ExpectedUnitsPerYear gensupport.JSONFloat64 `json:"expectedUnitsPerYear"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ExpectedUnitsPerYear = float64(s1.ExpectedUnitsPerYear)
	return nil
}

// CompensationFilter: Input only. Filter on job compensation type and
// amount.
type CompensationFilter struct {
	// IncludeJobsWithUnspecifiedCompensationRange: Optional. If set to
	// true, jobs with unspecified compensation range fields are included.
	IncludeJobsWithUnspecifiedCompensationRange bool `json:"includeJobsWithUnspecifiedCompensationRange,omitempty"`

	// Range: Optional. Compensation range.
	Range *CompensationRange `json:"range,omitempty"`

	// Type: Required. Type of filter.
	//
	// Possible values:
	//   "FILTER_TYPE_UNSPECIFIED" - Filter type unspecified. Position
	// holder, INVALID, should never be used.
	//   "UNIT_ONLY" - Filter by `base compensation entry's` unit. A job is
	// a match if and only if the job contains a base CompensationEntry and
	// the base CompensationEntry's unit matches provided units. Populate
	// one or more units. See CompensationInfo.CompensationEntry for
	// definition of base compensation entry.
	//   "UNIT_AND_AMOUNT" - Filter by `base compensation entry's` unit and
	// amount / range. A job is a match if and only if the job contains a
	// base CompensationEntry, and the base entry's unit matches provided
	// compensation_units and amount or range overlaps with provided
	// compensation_range. See CompensationInfo.CompensationEntry for
	// definition of base compensation entry. Set exactly one units and
	// populate range.
	//   "ANNUALIZED_BASE_AMOUNT" - Filter by annualized base compensation
	// amount and `base compensation entry's` unit. Populate range and zero
	// or more units.
	//   "ANNUALIZED_TOTAL_AMOUNT" - Filter by annualized total compensation
	// amount and `base compensation entry's` unit . Populate range and zero
	// or more units.
	Type string `json:"type,omitempty"`

	// Units: Required. Specify desired `base compensation entry's`
	// CompensationInfo.CompensationUnit.
	//
	// Possible values:
	//   "COMPENSATION_UNIT_UNSPECIFIED" - Default value.
	//   "HOURLY" - Hourly.
	//   "DAILY" - Daily.
	//   "WEEKLY" - Weekly
	//   "MONTHLY" - Monthly.
	//   "YEARLY" - Yearly.
	//   "ONE_TIME" - One time.
	//   "OTHER_COMPENSATION_UNIT" - Other compensation units.
	Units []string `json:"units,omitempty"`

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

// CompensationHistogramRequest: Input only. Compensation based
// histogram request.
type CompensationHistogramRequest struct {
	// BucketingOption: Required. Numeric histogram options, like buckets,
	// whether include min or max value.
	BucketingOption *NumericBucketingOption `json:"bucketingOption,omitempty"`

	// Type: Required. Type of the request, representing which field the
	// histogramming should be performed over. A single request can only
	// specify one histogram of each `CompensationHistogramRequestType`.
	//
	// Possible values:
	//   "COMPENSATION_HISTOGRAM_REQUEST_TYPE_UNSPECIFIED" - Default value.
	// Invalid.
	//   "BASE" - Histogram by job's base compensation. See
	// CompensationEntry for definition of base compensation.
	//   "ANNUALIZED_BASE" - Histogram by job's annualized base
	// compensation. See CompensationEntry for definition of annualized base
	// compensation.
	//   "ANNUALIZED_TOTAL" - Histogram by job's annualized total
	// compensation. See CompensationEntry for definition of annualized
	// total compensation.
	Type string `json:"type,omitempty"`

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

// CompensationHistogramResult: Output only. Compensation based
// histogram result.
type CompensationHistogramResult struct {
	// Result: Histogram result.
	Result *NumericBucketingResult `json:"result,omitempty"`

	// Type: Type of the request, corresponding to
	// CompensationHistogramRequest.type.
	//
	// Possible values:
	//   "COMPENSATION_HISTOGRAM_REQUEST_TYPE_UNSPECIFIED" - Default value.
	// Invalid.
	//   "BASE" - Histogram by job's base compensation. See
	// CompensationEntry for definition of base compensation.
	//   "ANNUALIZED_BASE" - Histogram by job's annualized base
	// compensation. See CompensationEntry for definition of annualized base
	// compensation.
	//   "ANNUALIZED_TOTAL" - Histogram by job's annualized total
	// compensation. See CompensationEntry for definition of annualized
	// total compensation.
	Type string `json:"type,omitempty"`

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

// CompensationInfo: Job compensation details.
type CompensationInfo struct {
	// AnnualizedBaseCompensationRange: Output only. Annualized base
	// compensation range. Computed as base compensation entry's
	// CompensationEntry.compensation times
	// CompensationEntry.expected_units_per_year. See CompensationEntry for
	// explanation on compensation annualization.
	AnnualizedBaseCompensationRange *CompensationRange `json:"annualizedBaseCompensationRange,omitempty"`

	// AnnualizedTotalCompensationRange: Output only. Annualized total
	// compensation range. Computed as all compensation entries'
	// CompensationEntry.compensation times
	// CompensationEntry.expected_units_per_year. See CompensationEntry for
	// explanation on compensation annualization.
	AnnualizedTotalCompensationRange *CompensationRange `json:"annualizedTotalCompensationRange,omitempty"`

	// Entries: Optional. Job compensation information. At most one entry
	// can be of type CompensationInfo.CompensationType.BASE, which is
	// referred as ** base compensation entry ** for the job.
	Entries []*CompensationEntry `json:"entries,omitempty"`

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

// CompensationRange: Compensation range.
type CompensationRange struct {
	// MaxCompensation: Optional. The maximum amount of compensation. If
	// left empty, the value is set to a maximal compensation value and the
	// currency code is set to match the currency code of min_compensation.
	MaxCompensation *Money `json:"maxCompensation,omitempty"`

	// MinCompensation: Optional. The minimum amount of compensation. If
	// left empty, the value is set to zero and the currency code is set to
	// match the currency code of max_compensation.
	MinCompensation *Money `json:"minCompensation,omitempty"`

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

// CompleteQueryResponse: Output only. Response of auto-complete query.
type CompleteQueryResponse struct {
	// CompletionResults: Results of the matching job/company candidates.
	CompletionResults []*CompletionResult `json:"completionResults,omitempty"`

	// Metadata: Additional information for the API invocation, such as the
	// request tracking id.
	Metadata *ResponseMetadata `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. "CompletionResults")
	// 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. "CompletionResults") 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 *CompleteQueryResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CompleteQueryResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CompletionResult: Output only. Resource that represents completion
// results.
type CompletionResult struct {
	// ImageUri: The URI of the company image for
	// CompletionType.COMPANY_NAME.
	ImageUri string `json:"imageUri,omitempty"`

	// Suggestion: The suggestion for the query.
	Suggestion string `json:"suggestion,omitempty"`

	// Type: The completion topic.
	//
	// Possible values:
	//   "COMPLETION_TYPE_UNSPECIFIED" - Default value.
	//   "JOB_TITLE" - Only suggest job titles.
	//   "COMPANY_NAME" - Only suggest company names.
	//   "COMBINED" - Suggest both job titles and company names.
	Type string `json:"type,omitempty"`

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

// CreateClientEventRequest: The report event request.
type CreateClientEventRequest struct {
	// ClientEvent: Required. Events issued when end user interacts with
	// customer's application that uses Cloud Talent Solution.
	ClientEvent *ClientEvent `json:"clientEvent,omitempty"`

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

// CreateCompanyRequest: Input only. The Request of the CreateCompany
// method.
type CreateCompanyRequest struct {
	// Company: Required. The company to be created.
	Company *Company `json:"company,omitempty"`

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

// CreateJobRequest: Input only. Create job request.
type CreateJobRequest struct {
	// Job: Required. The Job to be created.
	Job *Job `json:"job,omitempty"`

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

// CustomAttribute: Custom attribute values that are either filterable
// or non-filterable.
type CustomAttribute struct {
	// Filterable: Optional. If the `filterable` flag is true, the custom
	// field values may be used for custom attribute filters
	// JobQuery.custom_attribute_filter. If false, these values may not be
	// used for custom attribute filters. Default is false.
	Filterable bool `json:"filterable,omitempty"`

	// LongValues: Optional but exactly one of string_values or long_values
	// must be specified. This field is used to perform number range search.
	// (`EQ`, `GT`, `GE`, `LE`, `LT`) over filterable `long_value`.
	// Currently at most 1 long_values is supported.
	LongValues googleapi.Int64s `json:"longValues,omitempty"`

	// StringValues: Optional but exactly one of string_values or
	// long_values must be specified. This field is used to perform a string
	// match (`CASE_SENSITIVE_MATCH` or `CASE_INSENSITIVE_MATCH`) search.
	// For filterable `string_value`s, a maximum total number of 200 values
	// is allowed, with each `string_value` has a byte size of no more than
	// 500B. For unfilterable `string_values`, the maximum total byte size
	// of unfilterable `string_values` is 50KB. Empty string is not allowed.
	StringValues []string `json:"stringValues,omitempty"`

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

// CustomAttributeHistogramRequest: Custom attributes histogram request.
// An error is thrown if neither string_value_histogram or
// long_value_histogram_bucketing_option has been defined.
type CustomAttributeHistogramRequest struct {
	// Key: Required. Specifies the custom field key to perform a histogram
	// on. If specified without `long_value_histogram_bucketing_option`,
	// histogram on string values of the given `key` is triggered, otherwise
	// histogram is performed on long values.
	Key string `json:"key,omitempty"`

	// LongValueHistogramBucketingOption: Optional. Specifies buckets used
	// to perform a range histogram on Job's filterable long custom field
	// values, or min/max value requirements.
	LongValueHistogramBucketingOption *NumericBucketingOption `json:"longValueHistogramBucketingOption,omitempty"`

	// StringValueHistogram: Optional. If set to true, the response includes
	// the histogram value for each key as a string.
	StringValueHistogram bool `json:"stringValueHistogram,omitempty"`

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

// CustomAttributeHistogramResult: Output only. Custom attribute
// histogram result.
type CustomAttributeHistogramResult struct {
	// Key: Stores the key of custom attribute the histogram is performed
	// on.
	Key string `json:"key,omitempty"`

	// LongValueHistogramResult: Stores bucketed histogram counting result
	// or min/max values for custom attribute long values associated with
	// `key`.
	LongValueHistogramResult *NumericBucketingResult `json:"longValueHistogramResult,omitempty"`

	// StringValueHistogramResult: Stores a map from the values of string
	// custom field associated with `key` to the number of jobs with that
	// value in this histogram result.
	StringValueHistogramResult map[string]int64 `json:"stringValueHistogramResult,omitempty"`

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

// CustomRankingInfo: Input only. Custom ranking information for
// SearchJobsRequest.
type CustomRankingInfo struct {
	// ImportanceLevel: Required. Controls over how important the score of
	// CustomRankingInfo.ranking_expression gets applied to job's final
	// ranking position. An error is thrown if not specified.
	//
	// Possible values:
	//   "IMPORTANCE_LEVEL_UNSPECIFIED" - Default value if the importance
	// level is not specified.
	//   "NONE" - The given ranking expression is of None importance,
	// existing relevance score (determined by API algorithm) dominates
	// job's final ranking position.
	//   "LOW" - The given ranking expression is of Low importance in terms
	// of job's final ranking position compared to existing relevance score
	// (determined by API algorithm).
	//   "MILD" - The given ranking expression is of Mild importance in
	// terms of job's final ranking position compared to existing relevance
	// score (determined by API algorithm).
	//   "MEDIUM" - The given ranking expression is of Medium importance in
	// terms of job's final ranking position compared to existing relevance
	// score (determined by API algorithm).
	//   "HIGH" - The given ranking expression is of High importance in
	// terms of job's final ranking position compared to existing relevance
	// score (determined by API algorithm).
	//   "EXTREME" - The given ranking expression is of Extreme importance,
	// and dominates job's final ranking position with existing relevance
	// score (determined by API algorithm) ignored.
	ImportanceLevel string `json:"importanceLevel,omitempty"`

	// RankingExpression: Required. Controls over how job documents get
	// ranked on top of existing relevance score (determined by API
	// algorithm). A combination of the ranking expression and relevance
	// score is used to determine job's final ranking position. The syntax
	// for this expression is a subset of Google SQL syntax. Supported
	// operators are: +, -, *, /, where the left and right side of the
	// operator is either a numeric Job.custom_attributes key,
	// integer/double value or an expression that can be evaluated to a
	// number. Parenthesis are supported to adjust calculation precedence.
	// The expression must be < 100 characters in length. The expression is
	// considered invalid for a job if the expression references custom
	// attributes that are not populated on the job or if the expression
	// results in a divide by zero. If an expression is invalid for a job,
	// that job is demoted to the end of the results. Sample ranking
	// expression (year + 25) * 0.25 - (freshness / 0.5)
	RankingExpression string `json:"rankingExpression,omitempty"`

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

// DeviceInfo: Device information collected from the job seeker,
// candidate, or other entity conducting the job search. Providing this
// information improves the quality of the search results across
// devices.
type DeviceInfo struct {
	// DeviceType: Optional. Type of the device.
	//
	// Possible values:
	//   "DEVICE_TYPE_UNSPECIFIED" - The device type isn't specified.
	//   "WEB" - A desktop web browser, such as, Chrome, Firefox, Safari, or
	// Internet Explorer)
	//   "MOBILE_WEB" - A mobile device web browser, such as a phone or
	// tablet with a Chrome browser.
	//   "ANDROID" - An Android device native application.
	//   "IOS" - An iOS device native application.
	//   "BOT" - A bot, as opposed to a device operated by human beings,
	// such as a web crawler.
	//   "OTHER" - Other devices types.
	DeviceType string `json:"deviceType,omitempty"`

	// Id: Optional. A device-specific ID. The ID must be a unique
	// identifier that distinguishes the device from other devices.
	Id string `json:"id,omitempty"`

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

// Empty: 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 Empty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// HistogramFacets: Input only. Histogram facets to be specified in
// SearchJobsRequest.
type HistogramFacets struct {
	// CompensationHistogramFacets: Optional. Specifies compensation
	// field-based histogram requests. Duplicate values of
	// CompensationHistogramRequest.type are not allowed.
	CompensationHistogramFacets []*CompensationHistogramRequest `json:"compensationHistogramFacets,omitempty"`

	// CustomAttributeHistogramFacets: Optional. Specifies the custom
	// attributes histogram requests. Duplicate values of
	// CustomAttributeHistogramRequest.key are not allowed.
	CustomAttributeHistogramFacets []*CustomAttributeHistogramRequest `json:"customAttributeHistogramFacets,omitempty"`

	// SimpleHistogramFacets: Optional. Specifies the simple type of
	// histogram facets, for example, `COMPANY_SIZE`, `EMPLOYMENT_TYPE` etc.
	//
	// Possible values:
	//   "SEARCH_TYPE_UNSPECIFIED" - The default value if search type is not
	// specified.
	//   "COMPANY_ID" - Filter by the company id field.
	//   "EMPLOYMENT_TYPE" - Filter by the employment type field, such as
	// `FULL_TIME` or `PART_TIME`.
	//   "COMPANY_SIZE" - Filter by the company size type field, such as
	// `BIG`, `SMALL` or `BIGGER`.
	//   "DATE_PUBLISHED" - Filter by the date published field. Possible
	// return values are: * PAST_24_HOURS (The past 24 hours) * PAST_3_DAYS
	// (The past 3 days) * PAST_WEEK (The past 7 days) * PAST_MONTH (The
	// past 30 days) * PAST_YEAR (The past 365 days)
	//   "EDUCATION_LEVEL" - Filter by the required education level of the
	// job.
	//   "EXPERIENCE_LEVEL" - Filter by the required experience level of the
	// job.
	//   "ADMIN_1" - Filter by Admin1, which is a global placeholder for
	// referring to state, province, or the particular term a country uses
	// to define the geographic structure below the country level. Examples
	// include states codes such as "CA", "IL", "NY", and provinces, such as
	// "BC".
	//   "COUNTRY" - Filter by the country code of job, such as US, JP, FR.
	//   "CITY" - Filter by the "city name", "Admin1 code", for example,
	// "Mountain View, CA" or "New York, NY".
	//   "LOCALE" - Filter by the locale field of a job, such as "en-US",
	// "fr-FR". This is the BCP-47 language code, such as "en-US" or
	// "sr-Latn". For more information, see [Tags for Identifying
	// Languages](https://tools.ietf.org/html/bcp47).
	//   "LANGUAGE" - Filter by the language code portion of the locale
	// field, such as "en" or "fr".
	//   "CATEGORY" - Filter by the Category.
	//   "CITY_COORDINATE" - Filter by the city center GPS coordinate
	// (latitude and longitude), for example, 37.4038522,-122.0987765. Since
	// the coordinates of a city center can change, clients may need to
	// refresh them periodically.
	//   "ADMIN_1_COUNTRY" - A combination of state or province code with a
	// country code. This field differs from `JOB_ADMIN1`, which can be used
	// in multiple countries.
	//   "COMPANY_DISPLAY_NAME" - Company display name.
	//   "BASE_COMPENSATION_UNIT" - Base compensation unit.
	SimpleHistogramFacets []string `json:"simpleHistogramFacets,omitempty"`

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

// HistogramQuery: Input Only. The histogram request.
type HistogramQuery struct {
	// HistogramQuery: An expression specifies a histogram request against
	// matching resources (for example, jobs) for searches. Expression
	// syntax is a aggregation function call with histogram facets and other
	// options. Available aggregation function calls are: *
	// `count(string_histogram_facet)`: Count the number of matching entity,
	// for each distinct attribute value. * `count(numeric_histogram_facet,
	// list of buckets)`: Count the number of matching entity within each
	// bucket. Data types: * Histogram facet: facet names with format
	// a-zA-Z+. * String: string like "any string with backslash escape for
	// quote(\")." * Number: whole number and floating point number like 10,
	// -1 and -0.01. * List: list of elements with comma(,) separator
	// surrounded by square brackets. For example, [1, 2, 3] and ["one",
	// "two", "three"]. Built-in constants: * MIN (minimum number similar to
	// java Double.MIN_VALUE) * MAX (maximum number similar to java
	// Double.MAX_VALUE) Built-in functions: * bucket(start, end[, label]):
	// bucket built-in function creates a bucket with range of start, end).
	// Note that the end is exclusive. For example, bucket(1, MAX, "positive
	// number") or bucket(1, 10). Job histogram facets: * company_id:
	// histogram by [Job.distributor_company_id. * company_display_name:
	// histogram by Job.company_display_name. * employment_type: histogram
	// by Job.employment_types. For example, "FULL_TIME", "PART_TIME". *
	// company_size: histogram by CompanySize, for example, "SMALL",
	// "MEDIUM", "BIG". * publish_time_in_month: histogram by the
	// Job.publish_time in months. Must specify list of numeric buckets in
	// spec. * publish_time_in_year: histogram by the Job.publish_time in
	// years. Must specify list of numeric buckets in spec. * degree_type:
	// histogram by the Job.degree_type. For example, "Bachelors",
	// "Masters". * job_level: histogram by the Job.job_level. For example,
	// "Entry Level". * country: histogram by the country code of jobs. For
	// example, "US", "FR". * admin1: histogram by the admin1 code of jobs,
	// which is a global placeholder referring to the state, province, or
	// the particular term a country uses to define the geographic structure
	// below the country level. For example, "CA", "IL". * city: histogram
	// by a combination of the "city name, admin1 code". For example,
	// "Mountain View, CA", "New York, NY". * admin1_country: histogram by a
	// combination of the "admin1 code, country". For example, "CA, US",
	// "IL, US". * city_coordinate: histogram by the city center's GPS
	// coordinates (latitude and longitude). For example,
	// 37.4038522,-122.0987765. Since the coordinates of a city center can
	// change, customers may need to refresh them periodically. * locale:
	// histogram by the Job.language_code. For example, "en-US", "fr-FR". *
	// language: histogram by the language subtag of the Job.language_code.
	// For example, "en", "fr". * category: histogram by the JobCategory.
	// For example, "COMPUTER_AND_IT", "HEALTHCARE". *
	// base_compensation_unit: histogram by the CompensationUnit of base
	// salary. For example, "WEEKLY", "MONTHLY". * base_compensation:
	// histogram by the base salary. Must specify list of numeric buckets to
	// group results by. * annualized_base_compensation: histogram by the
	// base annualized salary. Must specify list of numeric buckets to group
	// results by. * annualized_total_compensation: histogram by the total
	// annualized salary. Must specify list of numeric buckets to group
	// results by. * string_custom_attribute: histogram by string
	// Job.custom_attributes. Values can be accessed via square bracket
	// notations like string_custom_attribute["key1"]. *
	// numeric_custom_attribute: histogram by numeric Job.custom_attributes.
	// Values can be accessed via square bracket notations like
	// numeric_custom_attribute["key1"]. Must specify list of numeric
	// buckets to group results by. Example expressions: * count(admin1) *
	// count(base_compensation, [bucket(1000, 10000), bucket(10000, 100000),
	// bucket(100000, MAX)]) *
	// count(string_custom_attribute["some-string-custom-attribute"]) *
	// count(numeric_custom_attribute["some-numeric-custom-attribute"],
	// [bucket(MIN, 0, "negative"), bucket(0, MAX, "non-negative"])
	HistogramQuery string `json:"histogramQuery,omitempty"`

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

// HistogramQueryResult: Output only. Histogram result that matches
// HistogramSpec specified in searches.
type HistogramQueryResult struct {
	// Histogram: A map from the values of the facet associated with
	// distinct values to the number of matching entries with corresponding
	// value. The key format is: * (for string histogram) string values
	// stored in the field. * (for named numeric bucket) name specified in
	// `bucket()` function, like for `bucket(0, MAX, "non-negative")`, the
	// key will be `non-negative`. * (for anonymous numeric bucket) range
	// formatted as `-`, for example, `0-1000`, `MIN-0`, and `0-MAX`.
	Histogram map[string]string `json:"histogram,omitempty"`

	// HistogramQuery: Requested histogram expression.
	HistogramQuery string `json:"histogramQuery,omitempty"`

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

// HistogramResult: Output only. Result of a histogram call. The
// response contains the histogram map for the search type specified by
// HistogramResult.field. The response is a map of each filter value to
// the corresponding count of jobs for that filter.
type HistogramResult struct {
	// SearchType: The Histogram search filters.
	//
	// Possible values:
	//   "SEARCH_TYPE_UNSPECIFIED" - The default value if search type is not
	// specified.
	//   "COMPANY_ID" - Filter by the company id field.
	//   "EMPLOYMENT_TYPE" - Filter by the employment type field, such as
	// `FULL_TIME` or `PART_TIME`.
	//   "COMPANY_SIZE" - Filter by the company size type field, such as
	// `BIG`, `SMALL` or `BIGGER`.
	//   "DATE_PUBLISHED" - Filter by the date published field. Possible
	// return values are: * PAST_24_HOURS (The past 24 hours) * PAST_3_DAYS
	// (The past 3 days) * PAST_WEEK (The past 7 days) * PAST_MONTH (The
	// past 30 days) * PAST_YEAR (The past 365 days)
	//   "EDUCATION_LEVEL" - Filter by the required education level of the
	// job.
	//   "EXPERIENCE_LEVEL" - Filter by the required experience level of the
	// job.
	//   "ADMIN_1" - Filter by Admin1, which is a global placeholder for
	// referring to state, province, or the particular term a country uses
	// to define the geographic structure below the country level. Examples
	// include states codes such as "CA", "IL", "NY", and provinces, such as
	// "BC".
	//   "COUNTRY" - Filter by the country code of job, such as US, JP, FR.
	//   "CITY" - Filter by the "city name", "Admin1 code", for example,
	// "Mountain View, CA" or "New York, NY".
	//   "LOCALE" - Filter by the locale field of a job, such as "en-US",
	// "fr-FR". This is the BCP-47 language code, such as "en-US" or
	// "sr-Latn". For more information, see [Tags for Identifying
	// Languages](https://tools.ietf.org/html/bcp47).
	//   "LANGUAGE" - Filter by the language code portion of the locale
	// field, such as "en" or "fr".
	//   "CATEGORY" - Filter by the Category.
	//   "CITY_COORDINATE" - Filter by the city center GPS coordinate
	// (latitude and longitude), for example, 37.4038522,-122.0987765. Since
	// the coordinates of a city center can change, clients may need to
	// refresh them periodically.
	//   "ADMIN_1_COUNTRY" - A combination of state or province code with a
	// country code. This field differs from `JOB_ADMIN1`, which can be used
	// in multiple countries.
	//   "COMPANY_DISPLAY_NAME" - Company display name.
	//   "BASE_COMPENSATION_UNIT" - Base compensation unit.
	SearchType string `json:"searchType,omitempty"`

	// Values: A map from the values of field to the number of jobs with
	// that value in this search result. Key: search type (filter names,
	// such as the companyName). Values: the count of jobs that match the
	// filter for this search.
	Values map[string]int64 `json:"values,omitempty"`

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

// HistogramResults: Output only. Histogram results that match
// HistogramFacets specified in SearchJobsRequest.
type HistogramResults struct {
	// CompensationHistogramResults: Specifies compensation field-based
	// histogram results that match
	// HistogramFacets.compensation_histogram_requests.
	CompensationHistogramResults []*CompensationHistogramResult `json:"compensationHistogramResults,omitempty"`

	// CustomAttributeHistogramResults: Specifies histogram results for
	// custom attributes that match
	// HistogramFacets.custom_attribute_histogram_facets.
	CustomAttributeHistogramResults []*CustomAttributeHistogramResult `json:"customAttributeHistogramResults,omitempty"`

	// SimpleHistogramResults: Specifies histogram results that matches
	// HistogramFacets.simple_histogram_facets.
	SimpleHistogramResults []*HistogramResult `json:"simpleHistogramResults,omitempty"`

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

// Job: A Job resource represents a job posting (also referred to as a
// "job listing" or "job requisition"). A job belongs to a Company,
// which is the hiring entity responsible for the job.
type Job struct {
	// Addresses: Optional but strongly recommended for the best service
	// experience. Location(s) where the employer is looking to hire for
	// this job posting. Specifying the full street address(es) of the
	// hiring location enables better API results, especially job searches
	// by commute time. At most 50 locations are allowed for best search
	// performance. If a job has more locations, it is suggested to split it
	// into multiple jobs with unique requisition_ids (e.g. 'ReqA' becomes
	// 'ReqA-1', 'ReqA-2', etc.) as multiple jobs with the same
	// company_name, language_code and requisition_id are not allowed. If
	// the original requisition_id must be preserved, a custom field should
	// be used for storage. It is also suggested to group the locations that
	// close to each other in the same job for better search experience. The
	// maximum number of allowed characters is 500.
	Addresses []string `json:"addresses,omitempty"`

	// ApplicationInfo: Required. At least one field within ApplicationInfo
	// must be specified. Job application information.
	ApplicationInfo *ApplicationInfo `json:"applicationInfo,omitempty"`

	// CompanyDisplayName: Output only. Display name of the company listing
	// the job.
	CompanyDisplayName string `json:"companyDisplayName,omitempty"`

	// CompanyName: Required. The resource name of the company listing the
	// job, such as "projects/api-test-project/companies/foo".
	CompanyName string `json:"companyName,omitempty"`

	// CompensationInfo: Optional. Job compensation information.
	CompensationInfo *CompensationInfo `json:"compensationInfo,omitempty"`

	// CustomAttributes: Optional. A map of fields to hold both filterable
	// and non-filterable custom job attributes that are not covered by the
	// provided structured fields. The keys of the map are strings up to 64
	// bytes and must match the pattern: a-zA-Z*. For example, key0LikeThis
	// or KEY_1_LIKE_THIS. At most 100 filterable and at most 100
	// unfilterable keys are supported. For filterable `string_values`,
	// across all keys at most 200 values are allowed, with each string no
	// more than 255 characters. For unfilterable `string_values`, the
	// maximum total size of `string_values` across all keys is 50KB.
	CustomAttributes map[string]CustomAttribute `json:"customAttributes,omitempty"`

	// DegreeTypes: Optional. The desired education degrees for the job,
	// such as Bachelors, Masters.
	//
	// Possible values:
	//   "DEGREE_TYPE_UNSPECIFIED" - Default value. Represents no degree, or
	// early childhood education. Maps to ISCED code 0. Ex) Kindergarten
	//   "PRIMARY_EDUCATION" - Primary education which is typically the
	// first stage of compulsory education. ISCED code 1. Ex) Elementary
	// school
	//   "LOWER_SECONDARY_EDUCATION" - Lower secondary education; First
	// stage of secondary education building on primary education, typically
	// with a more subject-oriented curriculum. ISCED code 2. Ex) Middle
	// school
	//   "UPPER_SECONDARY_EDUCATION" - Middle education; Second/final stage
	// of secondary education preparing for tertiary education and/or
	// providing skills relevant to employment. Usually with an increased
	// range of subject options and streams. ISCED code 3. Ex) High school
	//   "ADULT_REMEDIAL_EDUCATION" - Adult Remedial Education; Programmes
	// providing learning experiences that build on secondary education and
	// prepare for labour market entry and/or tertiary education. The
	// content is broader than secondary but not as complex as tertiary
	// education. ISCED code 4.
	//   "ASSOCIATES_OR_EQUIVALENT" - Associate's or equivalent; Short first
	// tertiary programmes that are typically practically-based,
	// occupationally-specific and prepare for labour market entry. These
	// programmes may also provide a pathway to other tertiary programmes.
	// ISCED code 5.
	//   "BACHELORS_OR_EQUIVALENT" - Bachelor's or equivalent; Programmes
	// designed to provide intermediate academic and/or professional
	// knowledge, skills and competencies leading to a first tertiary degree
	// or equivalent qualification. ISCED code 6.
	//   "MASTERS_OR_EQUIVALENT" - Master's or equivalent; Programmes
	// designed to provide advanced academic and/or professional knowledge,
	// skills and competencies leading to a second tertiary degree or
	// equivalent qualification. ISCED code 7.
	//   "DOCTORAL_OR_EQUIVALENT" - Doctoral or equivalent; Programmes
	// designed primarily to lead to an advanced research qualification,
	// usually concluding with the submission and defense of a substantive
	// dissertation of publishable quality based on original research. ISCED
	// code 8.
	DegreeTypes []string `json:"degreeTypes,omitempty"`

	// Department: Optional. The department or functional area within the
	// company with the open position. The maximum number of allowed
	// characters is 255.
	Department string `json:"department,omitempty"`

	// DerivedInfo: Output only. Derived details about the job posting.
	DerivedInfo *JobDerivedInfo `json:"derivedInfo,omitempty"`

	// Description: Required. The description of the job, which typically
	// includes a multi-paragraph description of the company and related
	// information. Separate fields are provided on the job object for
	// responsibilities, qualifications, and other job characteristics. Use
	// of these separate job fields is recommended. This field accepts and
	// sanitizes HTML input, and also accepts bold, italic, ordered list,
	// and unordered list markup tags. The maximum number of allowed
	// characters is 100,000.
	Description string `json:"description,omitempty"`

	// EmploymentTypes: Optional. The employment type(s) of a job, for
	// example, full time or part time.
	//
	// Possible values:
	//   "EMPLOYMENT_TYPE_UNSPECIFIED" - The default value if the employment
	// type is not specified.
	//   "FULL_TIME" - The job requires working a number of hours that
	// constitute full time employment, typically 40 or more hours per week.
	//   "PART_TIME" - The job entails working fewer hours than a full time
	// job, typically less than 40 hours a week.
	//   "CONTRACTOR" - The job is offered as a contracted, as opposed to a
	// salaried employee, position.
	//   "CONTRACT_TO_HIRE" - The job is offered as a contracted position
	// with the understanding that it's converted into a full-time position
	// at the end of the contract. Jobs of this type are also returned by a
	// search for EmploymentType.CONTRACTOR jobs.
	//   "TEMPORARY" - The job is offered as a temporary employment
	// opportunity, usually a short-term engagement.
	//   "INTERN" - The job is a fixed-term opportunity for students or
	// entry-level job seekers to obtain on-the-job training, typically
	// offered as a summer position.
	//   "VOLUNTEER" - The is an opportunity for an individual to volunteer,
	// where there's no expectation of compensation for the provided
	// services.
	//   "PER_DIEM" - The job requires an employee to work on an as-needed
	// basis with a flexible schedule.
	//   "FLY_IN_FLY_OUT" - The job involves employing people in remote
	// areas and flying them temporarily to the work site instead of
	// relocating employees and their families permanently.
	//   "OTHER_EMPLOYMENT_TYPE" - The job does not fit any of the other
	// listed types.
	EmploymentTypes []string `json:"employmentTypes,omitempty"`

	// Incentives: Optional. A description of bonus, commission, and other
	// compensation incentives associated with the job not including salary
	// or pay. The maximum number of allowed characters is 10,000.
	Incentives string `json:"incentives,omitempty"`

	// JobBenefits: Optional. The benefits included with the job.
	//
	// Possible values:
	//   "JOB_BENEFIT_UNSPECIFIED" - Default value if the type is not
	// specified.
	//   "CHILD_CARE" - The job includes access to programs that support
	// child care, such as daycare.
	//   "DENTAL" - The job includes dental services covered by a dental
	// insurance plan.
	//   "DOMESTIC_PARTNER" - The job offers specific benefits to domestic
	// partners.
	//   "FLEXIBLE_HOURS" - The job allows for a flexible work schedule.
	//   "MEDICAL" - The job includes health services covered by a medical
	// insurance plan.
	//   "LIFE_INSURANCE" - The job includes a life insurance plan provided
	// by the employer or available for purchase by the employee.
	//   "PARENTAL_LEAVE" - The job allows for a leave of absence to a
	// parent to care for a newborn child.
	//   "RETIREMENT_PLAN" - The job includes a workplace retirement plan
	// provided by the employer or available for purchase by the employee.
	//   "SICK_DAYS" - The job allows for paid time off due to illness.
	//   "VACATION" - The job includes paid time off for vacation.
	//   "VISION" - The job includes vision services covered by a vision
	// insurance plan.
	JobBenefits []string `json:"jobBenefits,omitempty"`

	// JobEndTime: Optional. The end timestamp of the job. Typically this
	// field is used for contracting engagements. Invalid timestamps are
	// ignored.
	JobEndTime string `json:"jobEndTime,omitempty"`

	// JobLevel: Optional. The experience level associated with the job,
	// such as "Entry Level".
	//
	// Possible values:
	//   "JOB_LEVEL_UNSPECIFIED" - The default value if the level is not
	// specified.
	//   "ENTRY_LEVEL" - Entry-level individual contributors, typically with
	// less than 2 years of experience in a similar role. Includes interns.
	//   "EXPERIENCED" - Experienced individual contributors, typically with
	// 2+ years of experience in a similar role.
	//   "MANAGER" - Entry- to mid-level managers responsible for managing a
	// team of people.
	//   "DIRECTOR" - Senior-level managers responsible for managing teams
	// of managers.
	//   "EXECUTIVE" - Executive-level managers and above, including C-level
	// positions.
	JobLevel string `json:"jobLevel,omitempty"`

	// JobStartTime: Optional. The start timestamp of the job in UTC time
	// zone. Typically this field is used for contracting engagements.
	// Invalid timestamps are ignored.
	JobStartTime string `json:"jobStartTime,omitempty"`

	// LanguageCode: Optional. The language of the posting. This field is
	// distinct from any requirements for fluency that are associated with
	// the job. Language codes must be in BCP-47 format, such as "en-US" or
	// "sr-Latn". For more information, see [Tags for Identifying
	// Languages](https://tools.ietf.org/html/bcp47){: class="external"
	// target="_blank" }. If this field is unspecified and Job.description
	// is present, detected language code based on Job.description is
	// assigned, otherwise defaults to 'en_US'.
	LanguageCode string `json:"languageCode,omitempty"`

	// Name: Required during job update. The resource name for the job. This
	// is generated by the service when a job is created. The format is
	// "projects/{project_id}/jobs/{job_id}", for example,
	// "projects/api-test-project/jobs/1234". Use of this field in job
	// queries and API calls is preferred over the use of requisition_id
	// since this value is unique.
	Name string `json:"name,omitempty"`

	// PostingCreateTime: Output only. The timestamp when this job posting
	// was created.
	PostingCreateTime string `json:"postingCreateTime,omitempty"`

	// PostingExpireTime: Optional but strongly recommended for the best
	// service experience. The expiration timestamp of the job. After this
	// timestamp, the job is marked as expired, and it no longer appears in
	// search results. The expired job can't be deleted or listed by the
	// DeleteJob and ListJobs APIs, but it can be retrieved with the GetJob
	// API or updated with the UpdateJob API. An expired job can be updated
	// and opened again by using a future expiration timestamp. Updating an
	// expired job fails if there is another existing open job with same
	// company_name, language_code and requisition_id. The expired jobs are
	// retained in our system for 90 days. However, the overall expired job
	// count cannot exceed 3 times the maximum of open jobs count over the
	// past week, otherwise jobs with earlier expire time are cleaned first.
	// Expired jobs are no longer accessible after they are cleaned out.
	// Invalid timestamps are ignored, and treated as expire time not
	// provided. Timestamp before the instant request is made is considered
	// valid, the job will be treated as expired immediately. If this value
	// is not provided at the time of job creation or is invalid, the job
	// posting expires after 30 days from the job's creation time. For
	// example, if the job was created on 2017/01/01 13:00AM UTC with an
	// unspecified expiration date, the job expires after 2017/01/31 13:00AM
	// UTC. If this value is not provided on job update, it depends on the
	// field masks set by UpdateJobRequest.update_mask. If the field masks
	// include expiry_time, or the masks are empty meaning that every field
	// is updated, the job posting expires after 30 days from the job's last
	// update time. Otherwise the expiration date isn't updated.
	PostingExpireTime string `json:"postingExpireTime,omitempty"`

	// PostingPublishTime: Optional. The timestamp this job posting was most
	// recently published. The default value is the time the request arrives
	// at the server. Invalid timestamps are ignored.
	PostingPublishTime string `json:"postingPublishTime,omitempty"`

	// PostingRegion: Optional. The job PostingRegion (for example, state,
	// country) throughout which the job is available. If this field is set,
	// a LocationFilter in a search query within the job region finds this
	// job posting if an exact location match isn't specified. If this field
	// is set to PostingRegion.NATION or PostingRegion.ADMINISTRATIVE_AREA,
	// setting job Job.addresses to the same location level as this field is
	// strongly recommended.
	//
	// Possible values:
	//   "POSTING_REGION_UNSPECIFIED" - If the region is unspecified, the
	// job is only returned if it matches the LocationFilter.
	//   "ADMINISTRATIVE_AREA" - In addition to exact location matching, job
	// posting is returned when the LocationFilter in the search query is in
	// the same administrative area as the returned job posting. For
	// example, if a `ADMINISTRATIVE_AREA` job is posted in "CA, USA", it's
	// returned if LocationFilter has "Mountain View". Administrative area
	// refers to top-level administrative subdivision of this country. For
	// example, US state, IT region, UK constituent nation and JP
	// prefecture.
	//   "NATION" - In addition to exact location matching, job is returned
	// when LocationFilter in search query is in the same country as this
	// job. For example, if a `NATION_WIDE` job is posted in "USA", it's
	// returned if LocationFilter has 'Mountain View'.
	//   "TELECOMMUTE" - Job allows employees to work remotely
	// (telecommute). If locations are provided with this value, the job is
	// considered as having a location, but telecommuting is allowed.
	PostingRegion string `json:"postingRegion,omitempty"`

	// PostingUpdateTime: Output only. The timestamp when this job posting
	// was last updated.
	PostingUpdateTime string `json:"postingUpdateTime,omitempty"`

	// ProcessingOptions: Optional. Options for job processing.
	ProcessingOptions *ProcessingOptions `json:"processingOptions,omitempty"`

	// PromotionValue: Optional. A promotion value of the job, as determined
	// by the client. The value determines the sort order of the jobs
	// returned when searching for jobs using the featured jobs search call,
	// with higher promotional values being returned first and ties being
	// resolved by relevance sort. Only the jobs with a promotionValue >0
	// are returned in a FEATURED_JOB_SEARCH. Default value is 0, and
	// negative values are treated as 0.
	PromotionValue int64 `json:"promotionValue,omitempty"`

	// Qualifications: Optional. A description of the qualifications
	// required to perform the job. The use of this field is recommended as
	// an alternative to using the more general description field. This
	// field accepts and sanitizes HTML input, and also accepts bold,
	// italic, ordered list, and unordered list markup tags. The maximum
	// number of allowed characters is 10,000.
	Qualifications string `json:"qualifications,omitempty"`

	// RequisitionId: Required. The requisition ID, also referred to as the
	// posting ID, assigned by the client to identify a job. This field is
	// intended to be used by clients for client identification and tracking
	// of postings. A job is not allowed to be created if there is another
	// job with the same [company_name], language_code and requisition_id.
	// The maximum number of allowed characters is 255.
	RequisitionId string `json:"requisitionId,omitempty"`

	// Responsibilities: Optional. A description of job responsibilities.
	// The use of this field is recommended as an alternative to using the
	// more general description field. This field accepts and sanitizes HTML
	// input, and also accepts bold, italic, ordered list, and unordered
	// list markup tags. The maximum number of allowed characters is 10,000.
	Responsibilities string `json:"responsibilities,omitempty"`

	// Title: Required. The title of the job, such as "Software Engineer"
	// The maximum number of allowed characters is 500.
	Title string `json:"title,omitempty"`

	// Visibility: Deprecated. The job is only visible to the owner. The
	// visibility of the job. Defaults to Visibility.ACCOUNT_ONLY if not
	// specified.
	//
	// Possible values:
	//   "VISIBILITY_UNSPECIFIED" - Default value.
	//   "ACCOUNT_ONLY" - The resource is only visible to the GCP account
	// who owns it.
	//   "SHARED_WITH_GOOGLE" - The resource is visible to the owner and may
	// be visible to other applications and processes at Google.
	//   "SHARED_WITH_PUBLIC" - The resource is visible to the owner and may
	// be visible to all other API clients.
	Visibility string `json:"visibility,omitempty"`

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

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

// JobDerivedInfo: Output only. Derived details about the job posting.
type JobDerivedInfo struct {
	// JobCategories: Job categories derived from Job.title and
	// Job.description.
	//
	// Possible values:
	//   "JOB_CATEGORY_UNSPECIFIED" - The default value if the category
	// isn't specified.
	//   "ACCOUNTING_AND_FINANCE" - An accounting and finance job, such as
	// an Accountant.
	//   "ADMINISTRATIVE_AND_OFFICE" - An administrative and office job,
	// such as an Administrative Assistant.
	//   "ADVERTISING_AND_MARKETING" - An advertising and marketing job,
	// such as Marketing Manager.
	//   "ANIMAL_CARE" - An animal care job, such as Veterinarian.
	//   "ART_FASHION_AND_DESIGN" - An art, fashion, or design job, such as
	// Designer.
	//   "BUSINESS_OPERATIONS" - A business operations job, such as Business
	// Operations Manager.
	//   "CLEANING_AND_FACILITIES" - A cleaning and facilities job, such as
	// Custodial Staff.
	//   "COMPUTER_AND_IT" - A computer and IT job, such as Systems
	// Administrator.
	//   "CONSTRUCTION" - A construction job, such as General Laborer.
	//   "CUSTOMER_SERVICE" - A customer service job, such s Cashier.
	//   "EDUCATION" - An education job, such as School Teacher.
	//   "ENTERTAINMENT_AND_TRAVEL" - An entertainment and travel job, such
	// as Flight Attendant.
	//   "FARMING_AND_OUTDOORS" - A farming or outdoor job, such as Park
	// Ranger.
	//   "HEALTHCARE" - A healthcare job, such as Registered Nurse.
	//   "HUMAN_RESOURCES" - A human resources job, such as Human Resources
	// Director.
	//   "INSTALLATION_MAINTENANCE_AND_REPAIR" - An installation,
	// maintenance, or repair job, such as Electrician.
	//   "LEGAL" - A legal job, such as Law Clerk.
	//   "MANAGEMENT" - A management job, often used in conjunction with
	// another category, such as Store Manager.
	//   "MANUFACTURING_AND_WAREHOUSE" - A manufacturing or warehouse job,
	// such as Assembly Technician.
	//   "MEDIA_COMMUNICATIONS_AND_WRITING" - A media, communications, or
	// writing job, such as Media Relations.
	//   "OIL_GAS_AND_MINING" - An oil, gas or mining job, such as Offshore
	// Driller.
	//   "PERSONAL_CARE_AND_SERVICES" - A personal care and services job,
	// such as Hair Stylist.
	//   "PROTECTIVE_SERVICES" - A protective services job, such as Security
	// Guard.
	//   "REAL_ESTATE" - A real estate job, such as Buyer's Agent.
	//   "RESTAURANT_AND_HOSPITALITY" - A restaurant and hospitality job,
	// such as Restaurant Server.
	//   "SALES_AND_RETAIL" - A sales and/or retail job, such Sales
	// Associate.
	//   "SCIENCE_AND_ENGINEERING" - A science and engineering job, such as
	// Lab Technician.
	//   "SOCIAL_SERVICES_AND_NON_PROFIT" - A social services or non-profit
	// job, such as Case Worker.
	//   "SPORTS_FITNESS_AND_RECREATION" - A sports, fitness, or recreation
	// job, such as Personal Trainer.
	//   "TRANSPORTATION_AND_LOGISTICS" - A transportation or logistics job,
	// such as Truck Driver.
	JobCategories []string `json:"jobCategories,omitempty"`

	// Locations: Structured locations of the job, resolved from
	// Job.addresses. locations are exactly matched to Job.addresses in the
	// same order.
	Locations []*Location `json:"locations,omitempty"`

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

// JobEvent: An event issued when a job seeker interacts with the
// application that implements Cloud Talent Solution.
type JobEvent struct {
	// Jobs: Required. The job name(s) associated with this event. For
	// example, if this is an impression event, this field contains the
	// identifiers of all jobs shown to the job seeker. If this was a view
	// event, this field contains the identifier of the viewed job.
	Jobs []string `json:"jobs,omitempty"`

	// Type: Required. The type of the event (see JobEventType).
	//
	// Possible values:
	//   "JOB_EVENT_TYPE_UNSPECIFIED" - The event is unspecified by other
	// provided values.
	//   "IMPRESSION" - The job seeker or other entity interacting with the
	// service has had a job rendered in their view, such as in a list of
	// search results in a compressed or clipped format. This event is
	// typically associated with the viewing of a jobs list on a single page
	// by a job seeker.
	//   "VIEW" - The job seeker, or other entity interacting with the
	// service, has viewed the details of a job, including the full
	// description. This event doesn't apply to the viewing a snippet of a
	// job appearing as a part of the job search results. Viewing a snippet
	// is associated with an impression).
	//   "VIEW_REDIRECT" - The job seeker or other entity interacting with
	// the service performed an action to view a job and was redirected to a
	// different website for job.
	//   "APPLICATION_START" - The job seeker or other entity interacting
	// with the service began the process or demonstrated the intention of
	// applying for a job.
	//   "APPLICATION_FINISH" - The job seeker or other entity interacting
	// with the service submitted an application for a job.
	//   "APPLICATION_QUICK_SUBMISSION" - The job seeker or other entity
	// interacting with the service submitted an application for a job with
	// a single click without entering information. If a job seeker performs
	// this action, send only this event to the service. Do not also send
	// JobEventType.APPLICATION_START or JobEventType.APPLICATION_FINISH
	// events.
	//   "APPLICATION_REDIRECT" - The job seeker or other entity interacting
	// with the service performed an action to apply to a job and was
	// redirected to a different website to complete the application.
	//   "APPLICATION_START_FROM_SEARCH" - The job seeker or other entity
	// interacting with the service began the process or demonstrated the
	// intention of applying for a job from the search results page without
	// viewing the details of the job posting. If sending this event,
	// JobEventType.VIEW event shouldn't be sent.
	//   "APPLICATION_REDIRECT_FROM_SEARCH" - The job seeker, or other
	// entity interacting with the service, performs an action with a single
	// click from the search results page to apply to a job (without viewing
	// the details of the job posting), and is redirected to a different
	// website to complete the application. If a candidate performs this
	// action, send only this event to the service. Do not also send
	// JobEventType.APPLICATION_START, JobEventType.APPLICATION_FINISH or
	// JobEventType.VIEW events.
	//   "APPLICATION_COMPANY_SUBMIT" - This event should be used when a
	// company submits an application on behalf of a job seeker. This event
	// is intended for use by staffing agencies attempting to place
	// candidates.
	//   "BOOKMARK" - The job seeker or other entity interacting with the
	// service demonstrated an interest in a job by bookmarking or saving
	// it.
	//   "NOTIFICATION" - The job seeker or other entity interacting with
	// the service was sent a notification, such as an email alert or device
	// notification, containing one or more jobs listings generated by the
	// service.
	//   "HIRED" - The job seeker or other entity interacting with the
	// service was employed by the hiring entity (employer). Send this event
	// only if the job seeker was hired through an application that was
	// initiated by a search conducted through the Cloud Talent Solution
	// service.
	//   "SENT_CV" - A recruiter or staffing agency submitted an application
	// on behalf of the candidate after interacting with the service to
	// identify a suitable job posting.
	//   "INTERVIEW_GRANTED" - The entity interacting with the service (for
	// example, the job seeker), was granted an initial interview by the
	// hiring entity (employer). This event should only be sent if the job
	// seeker was granted an interview as part of an application that was
	// initiated by a search conducted through / recommendation provided by
	// the Cloud Talent Solution service.
	//   "NOT_INTERESTED" - The job seeker or other entity interacting with
	// the service showed no interest in the job.
	Type string `json:"type,omitempty"`

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

// JobQuery: Input only. The query required to perform a search query.
type JobQuery struct {
	// CommuteFilter: Optional. Allows filtering jobs by commute time with
	// different travel methods (for example, driving or public transit).
	// Note: This only works with COMMUTE MODE. When specified,
	// [JobQuery.location_filters] is ignored. Currently we don't support
	// sorting by commute time.
	CommuteFilter *CommuteFilter `json:"commuteFilter,omitempty"`

	// CompanyDisplayNames: Optional. This filter specifies the exact
	// company display name of the jobs to search against. If a value isn't
	// specified, jobs within the search results are associated with any
	// company. If multiple values are specified, jobs within the search
	// results may be associated with any of the specified companies. At
	// most 20 company display name filters are allowed.
	CompanyDisplayNames []string `json:"companyDisplayNames,omitempty"`

	// CompanyNames: Optional. This filter specifies the company entities to
	// search against. If a value isn't specified, jobs are searched for
	// against all companies. If multiple values are specified, jobs are
	// searched against the companies specified. The format is
	// "projects/{project_id}/companies/{company_id}", for example,
	// "projects/api-test-project/companies/foo". At most 20 company filters
	// are allowed.
	CompanyNames []string `json:"companyNames,omitempty"`

	// CompensationFilter: Optional. This search filter is applied only to
	// Job.compensation_info. For example, if the filter is specified as
	// "Hourly job with per-hour compensation > $15", only jobs meeting
	// these criteria are searched. If a filter isn't defined, all open jobs
	// are searched.
	CompensationFilter *CompensationFilter `json:"compensationFilter,omitempty"`

	// CustomAttributeFilter: Optional. This filter specifies a structured
	// syntax to match against the Job.custom_attributes marked as
	// `filterable`. The syntax for this expression is a subset of SQL
	// syntax. Supported operators are: `=`, `!=`, `<`, `<=`, `>`, and `>=`
	// where the left of the operator is a custom field key and the right of
	// the operator is a number or a quoted string. You must escape
	// backslash (\\) and quote (\") characters. Supported functions are
	// `LOWER([field_name])` to perform a case insensitive match and
	// `EMPTY([field_name])` to filter on the existence of a key. Boolean
	// expressions (AND/OR/NOT) are supported up to 3 levels of nesting (for
	// example, "((A AND B AND C) OR NOT D) AND E"), a maximum of 100
	// comparisons or functions are allowed in the expression. The
	// expression must be < 6000 bytes in length. Sample Query:
	// `(LOWER(driving_license)="class \"a\"" OR EMPTY(driving_license)) AND
	// driving_years > 10`
	CustomAttributeFilter string `json:"customAttributeFilter,omitempty"`

	// DisableSpellCheck: Optional. This flag controls the spell-check
	// feature. If false, the service attempts to correct a misspelled
	// query, for example, "enginee" is corrected to "engineer". Defaults to
	// false: a spell check is performed.
	DisableSpellCheck bool `json:"disableSpellCheck,omitempty"`

	// EmploymentTypes: Optional. The employment type filter specifies the
	// employment type of jobs to search against, such as
	// EmploymentType.FULL_TIME. If a value is not specified, jobs in the
	// search results includes any employment type. If multiple values are
	// specified, jobs in the search results include any of the specified
	// employment types.
	//
	// Possible values:
	//   "EMPLOYMENT_TYPE_UNSPECIFIED" - The default value if the employment
	// type is not specified.
	//   "FULL_TIME" - The job requires working a number of hours that
	// constitute full time employment, typically 40 or more hours per week.
	//   "PART_TIME" - The job entails working fewer hours than a full time
	// job, typically less than 40 hours a week.
	//   "CONTRACTOR" - The job is offered as a contracted, as opposed to a
	// salaried employee, position.
	//   "CONTRACT_TO_HIRE" - The job is offered as a contracted position
	// with the understanding that it's converted into a full-time position
	// at the end of the contract. Jobs of this type are also returned by a
	// search for EmploymentType.CONTRACTOR jobs.
	//   "TEMPORARY" - The job is offered as a temporary employment
	// opportunity, usually a short-term engagement.
	//   "INTERN" - The job is a fixed-term opportunity for students or
	// entry-level job seekers to obtain on-the-job training, typically
	// offered as a summer position.
	//   "VOLUNTEER" - The is an opportunity for an individual to volunteer,
	// where there's no expectation of compensation for the provided
	// services.
	//   "PER_DIEM" - The job requires an employee to work on an as-needed
	// basis with a flexible schedule.
	//   "FLY_IN_FLY_OUT" - The job involves employing people in remote
	// areas and flying them temporarily to the work site instead of
	// relocating employees and their families permanently.
	//   "OTHER_EMPLOYMENT_TYPE" - The job does not fit any of the other
	// listed types.
	EmploymentTypes []string `json:"employmentTypes,omitempty"`

	// ExcludedJobs: Optional. This filter specifies a list of job names to
	// be excluded during search. At most 400 excluded job names are
	// allowed.
	ExcludedJobs []string `json:"excludedJobs,omitempty"`

	// JobCategories: Optional. The category filter specifies the categories
	// of jobs to search against. See Category for more information. If a
	// value is not specified, jobs from any category are searched against.
	// If multiple values are specified, jobs from any of the specified
	// categories are searched against.
	//
	// Possible values:
	//   "JOB_CATEGORY_UNSPECIFIED" - The default value if the category
	// isn't specified.
	//   "ACCOUNTING_AND_FINANCE" - An accounting and finance job, such as
	// an Accountant.
	//   "ADMINISTRATIVE_AND_OFFICE" - An administrative and office job,
	// such as an Administrative Assistant.
	//   "ADVERTISING_AND_MARKETING" - An advertising and marketing job,
	// such as Marketing Manager.
	//   "ANIMAL_CARE" - An animal care job, such as Veterinarian.
	//   "ART_FASHION_AND_DESIGN" - An art, fashion, or design job, such as
	// Designer.
	//   "BUSINESS_OPERATIONS" - A business operations job, such as Business
	// Operations Manager.
	//   "CLEANING_AND_FACILITIES" - A cleaning and facilities job, such as
	// Custodial Staff.
	//   "COMPUTER_AND_IT" - A computer and IT job, such as Systems
	// Administrator.
	//   "CONSTRUCTION" - A construction job, such as General Laborer.
	//   "CUSTOMER_SERVICE" - A customer service job, such s Cashier.
	//   "EDUCATION" - An education job, such as School Teacher.
	//   "ENTERTAINMENT_AND_TRAVEL" - An entertainment and travel job, such
	// as Flight Attendant.
	//   "FARMING_AND_OUTDOORS" - A farming or outdoor job, such as Park
	// Ranger.
	//   "HEALTHCARE" - A healthcare job, such as Registered Nurse.
	//   "HUMAN_RESOURCES" - A human resources job, such as Human Resources
	// Director.
	//   "INSTALLATION_MAINTENANCE_AND_REPAIR" - An installation,
	// maintenance, or repair job, such as Electrician.
	//   "LEGAL" - A legal job, such as Law Clerk.
	//   "MANAGEMENT" - A management job, often used in conjunction with
	// another category, such as Store Manager.
	//   "MANUFACTURING_AND_WAREHOUSE" - A manufacturing or warehouse job,
	// such as Assembly Technician.
	//   "MEDIA_COMMUNICATIONS_AND_WRITING" - A media, communications, or
	// writing job, such as Media Relations.
	//   "OIL_GAS_AND_MINING" - An oil, gas or mining job, such as Offshore
	// Driller.
	//   "PERSONAL_CARE_AND_SERVICES" - A personal care and services job,
	// such as Hair Stylist.
	//   "PROTECTIVE_SERVICES" - A protective services job, such as Security
	// Guard.
	//   "REAL_ESTATE" - A real estate job, such as Buyer's Agent.
	//   "RESTAURANT_AND_HOSPITALITY" - A restaurant and hospitality job,
	// such as Restaurant Server.
	//   "SALES_AND_RETAIL" - A sales and/or retail job, such Sales
	// Associate.
	//   "SCIENCE_AND_ENGINEERING" - A science and engineering job, such as
	// Lab Technician.
	//   "SOCIAL_SERVICES_AND_NON_PROFIT" - A social services or non-profit
	// job, such as Case Worker.
	//   "SPORTS_FITNESS_AND_RECREATION" - A sports, fitness, or recreation
	// job, such as Personal Trainer.
	//   "TRANSPORTATION_AND_LOGISTICS" - A transportation or logistics job,
	// such as Truck Driver.
	JobCategories []string `json:"jobCategories,omitempty"`

	// LanguageCodes: Optional. This filter specifies the locale of jobs to
	// search against, for example, "en-US". If a value isn't specified, the
	// search results can contain jobs in any locale. Language codes should
	// be in BCP-47 format, such as "en-US" or "sr-Latn". For more
	// information, see [Tags for Identifying
	// Languages](https://tools.ietf.org/html/bcp47). At most 10 language
	// code filters are allowed.
	LanguageCodes []string `json:"languageCodes,omitempty"`

	// LocationFilters: Optional. The location filter specifies geo-regions
	// containing the jobs to search against. See LocationFilter for more
	// information. If a location value isn't specified, jobs fitting the
	// other search criteria are retrieved regardless of where they're
	// located. If multiple values are specified, jobs are retrieved from
	// any of the specified locations. If different values are specified for
	// the LocationFilter.distance_in_miles parameter, the maximum provided
	// distance is used for all locations. At most 5 location filters are
	// allowed.
	LocationFilters []*LocationFilter `json:"locationFilters,omitempty"`

	// PublishTimeRange: Optional. Jobs published within a range specified
	// by this filter are searched against.
	PublishTimeRange *TimestampRange `json:"publishTimeRange,omitempty"`

	// Query: Optional. The query string that matches against the job title,
	// description, and location fields. The maximum number of allowed
	// characters is 255.
	Query string `json:"query,omitempty"`

	// QueryLanguageCode: The language code of query. For example, "en-US".
	// This field helps to better interpret the query. If a value isn't
	// specified, the query language code is automatically detected, which
	// may not be accurate. Language code should be in BCP-47 format, such
	// as "en-US" or "sr-Latn". For more information, see [Tags for
	// Identifying Languages](https://tools.ietf.org/html/bcp47).
	QueryLanguageCode string `json:"queryLanguageCode,omitempty"`

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

// LatLng: An object representing a latitude/longitude pair. This is
// expressed as a pair of doubles representing degrees latitude and
// degrees longitude. Unless specified otherwise, this must conform to
// the WGS84 standard. Values must be within normalized ranges.
type LatLng struct {
	// Latitude: The latitude in degrees. It must be in the range [-90.0,
	// +90.0].
	Latitude float64 `json:"latitude,omitempty"`

	// Longitude: The longitude in degrees. It must be in the range [-180.0,
	// +180.0].
	Longitude float64 `json:"longitude,omitempty"`

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

func (s *LatLng) UnmarshalJSON(data []byte) error {
	type NoMethod LatLng
	var s1 struct {
		Latitude  gensupport.JSONFloat64 `json:"latitude"`
		Longitude gensupport.JSONFloat64 `json:"longitude"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Latitude = float64(s1.Latitude)
	s.Longitude = float64(s1.Longitude)
	return nil
}

// ListCompaniesResponse: Output only. The List companies response
// object.
type ListCompaniesResponse struct {
	// Companies: Companies for the current client.
	Companies []*Company `json:"companies,omitempty"`

	// Metadata: Additional information for the API invocation, such as the
	// request tracking id.
	Metadata *ResponseMetadata `json:"metadata,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	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. "Companies") 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. "Companies") 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 *ListCompaniesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListCompaniesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListJobsResponse: Output only. List jobs response.
type ListJobsResponse struct {
	// Jobs: The Jobs for a given company. The maximum number of items
	// returned is based on the limit field provided in the request.
	Jobs []*Job `json:"jobs,omitempty"`

	// Metadata: Additional information for the API invocation, such as the
	// request tracking id.
	Metadata *ResponseMetadata `json:"metadata,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	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. "Jobs") 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. "Jobs") 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 *ListJobsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListJobsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Location: Output only. A resource that represents a location with
// full geographic information.
type Location struct {
	// LatLng: An object representing a latitude/longitude pair.
	LatLng *LatLng `json:"latLng,omitempty"`

	// LocationType: The type of a location, which corresponds to the
	// address lines field of PostalAddress. For example, "Downtown,
	// Atlanta, GA, USA" has a type of LocationType#NEIGHBORHOOD, and
	// "Kansas City, KS, USA" has a type of LocationType#LOCALITY.
	//
	// Possible values:
	//   "LOCATION_TYPE_UNSPECIFIED" - Default value if the type is not
	// specified.
	//   "COUNTRY" - A country level location.
	//   "ADMINISTRATIVE_AREA" - A state or equivalent level location.
	//   "SUB_ADMINISTRATIVE_AREA" - A county or equivalent level location.
	//   "LOCALITY" - A city or equivalent level location.
	//   "POSTAL_CODE" - A postal code level location.
	//   "SUB_LOCALITY" - A sublocality is a subdivision of a locality, for
	// example a city borough, ward, or arrondissement. Sublocalities are
	// usually recognized by a local political authority. For example,
	// Manhattan and Brooklyn are recognized as boroughs by the City of New
	// York, and are therefore modeled as sublocalities.
	//   "SUB_LOCALITY_1" - A district or equivalent level location.
	//   "SUB_LOCALITY_2" - A smaller district or equivalent level display.
	//   "NEIGHBORHOOD" - A neighborhood level location.
	//   "STREET_ADDRESS" - A street address level location.
	LocationType string `json:"locationType,omitempty"`

	// PostalAddress: Postal address of the location that includes human
	// readable information, such as postal delivery and payments addresses.
	// Given a postal address, a postal service can deliver items to a
	// premises, P.O. Box, or other delivery location.
	PostalAddress *PostalAddress `json:"postalAddress,omitempty"`

	// RadiusInMiles: Radius in miles of the job location. This value is
	// derived from the location bounding box in which a circle with the
	// specified radius centered from LatLng covers the area associated with
	// the job location. For example, currently, "Mountain View, CA, USA"
	// has a radius of 6.17 miles.
	RadiusInMiles float64 `json:"radiusInMiles,omitempty"`

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

func (s *Location) UnmarshalJSON(data []byte) error {
	type NoMethod Location
	var s1 struct {
		RadiusInMiles gensupport.JSONFloat64 `json:"radiusInMiles"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.RadiusInMiles = float64(s1.RadiusInMiles)
	return nil
}

// LocationFilter: Input only. Geographic region of the search.
type LocationFilter struct {
	// Address: Optional. The address name, such as "Mountain View" or "Bay
	// Area".
	Address string `json:"address,omitempty"`

	// DistanceInMiles: Optional. The distance_in_miles is applied when the
	// location being searched for is identified as a city or smaller. When
	// the location being searched for is a state or larger, this field is
	// ignored.
	DistanceInMiles float64 `json:"distanceInMiles,omitempty"`

	// LatLng: Optional. The latitude and longitude of the geographic center
	// from which to search. This field's ignored if `address` is provided.
	LatLng *LatLng `json:"latLng,omitempty"`

	// RegionCode: Optional. CLDR region code of the country/region of the
	// address. This is used to address ambiguity of the user-input
	// location, for example, "Liverpool" against "Liverpool, NY, US" or
	// "Liverpool, UK". Set this field if all the jobs to search against are
	// from a same region, or jobs are world-wide, but the job seeker is
	// from a specific region. See http://cldr.unicode.org/ and
	// http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html for details. Example: "CH" for
	// Switzerland.
	RegionCode string `json:"regionCode,omitempty"`

	// TelecommutePreference: Optional. Allows the client to return jobs
	// without a set location, specifically, telecommuting jobs
	// (telecommuting is considered by the service as a special location.
	// Job.posting_region indicates if a job permits telecommuting. If this
	// field is set to TelecommutePreference.TELECOMMUTE_ALLOWED,
	// telecommuting jobs are searched, and address and lat_lng are ignored.
	// If not set or set to TelecommutePreference.TELECOMMUTE_EXCLUDED,
	// telecommute job are not searched. This filter can be used by itself
	// to search exclusively for telecommuting jobs, or it can be combined
	// with another location filter to search for a combination of job
	// locations, such as "Mountain View" or "telecommuting" jobs. However,
	// when used in combination with other location filters, telecommuting
	// jobs can be treated as less relevant than other jobs in the search
	// response.
	//
	// Possible values:
	//   "TELECOMMUTE_PREFERENCE_UNSPECIFIED" - Default value if the
	// telecommute preference is not specified.
	//   "TELECOMMUTE_EXCLUDED" - Exclude telecommute jobs.
	//   "TELECOMMUTE_ALLOWED" - Allow telecommute jobs.
	TelecommutePreference string `json:"telecommutePreference,omitempty"`

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

func (s *LocationFilter) UnmarshalJSON(data []byte) error {
	type NoMethod LocationFilter
	var s1 struct {
		DistanceInMiles gensupport.JSONFloat64 `json:"distanceInMiles"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DistanceInMiles = float64(s1.DistanceInMiles)
	return nil
}

// MatchingJob: Output only. Job entry with metadata inside
// SearchJobsResponse.
type MatchingJob struct {
	// CommuteInfo: Commute information which is generated based on
	// specified CommuteFilter.
	CommuteInfo *CommuteInfo `json:"commuteInfo,omitempty"`

	// Job: Job resource that matches the specified SearchJobsRequest.
	Job *Job `json:"job,omitempty"`

	// JobSummary: A summary of the job with core information that's
	// displayed on the search results listing page.
	JobSummary string `json:"jobSummary,omitempty"`

	// JobTitleSnippet: Contains snippets of text from the Job.job_title
	// field most closely matching a search query's keywords, if available.
	// The matching query keywords are enclosed in HTML bold tags.
	JobTitleSnippet string `json:"jobTitleSnippet,omitempty"`

	// SearchTextSnippet: Contains snippets of text from the Job.description
	// and similar fields that most closely match a search query's keywords,
	// if available. All HTML tags in the original fields are stripped when
	// returned in this field, and matching query keywords are enclosed in
	// HTML bold tags.
	SearchTextSnippet string `json:"searchTextSnippet,omitempty"`

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

// MendelDebugInput: Message representing input to a Mendel server for
// debug forcing. See go/mendel-debug-forcing for more details. Next ID:
// 2
type MendelDebugInput struct {
	// NamespacedDebugInput: When a request spans multiple servers, a
	// MendelDebugInput may travel with the request and take effect in all
	// the servers. This field is a map of namespaces to
	// NamespacedMendelDebugInput protos. In a single server, up to two
	// NamespacedMendelDebugInput protos are applied: 1.
	// NamespacedMendelDebugInput with the global namespace (key == ""). 2.
	// NamespacedMendelDebugInput with the server's namespace. When both
	// NamespacedMendelDebugInput protos are present, they are merged. See
	// go/mendel-debug-forcing for more details.
	NamespacedDebugInput map[string]NamespacedDebugInput `json:"namespacedDebugInput,omitempty"`

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

// Money: Represents an amount of money with its currency type.
type Money struct {
	// CurrencyCode: The 3-letter currency code defined in ISO 4217.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// Nanos: Number of nano (10^-9) units of the amount. The value must be
	// between -999,999,999 and +999,999,999 inclusive. If `units` is
	// positive, `nanos` must be positive or zero. If `units` is zero,
	// `nanos` can be positive, zero, or negative. If `units` is negative,
	// `nanos` must be negative or zero. For example $-1.75 is represented
	// as `units`=-1 and `nanos`=-750,000,000.
	Nanos int64 `json:"nanos,omitempty"`

	// Units: The whole units of the amount. For example if `currencyCode`
	// is "USD", then 1 unit is one US dollar.
	Units int64 `json:"units,omitempty,string"`

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

// NamespacedDebugInput: Next ID: 15
type NamespacedDebugInput struct {
	// AbsolutelyForcedExpNames: Set of experiment names to be absolutely
	// forced. These experiments will be forced without evaluating the
	// conditions.
	AbsolutelyForcedExpNames []string `json:"absolutelyForcedExpNames,omitempty"`

	// AbsolutelyForcedExpTags: Set of experiment tags to be absolutely
	// forced. The experiments with these tags will be forced without
	// evaluating the conditions.
	AbsolutelyForcedExpTags []string `json:"absolutelyForcedExpTags,omitempty"`

	// AbsolutelyForcedExps: Set of experiment ids to be absolutely forced.
	// These ids will be forced without evaluating the conditions.
	AbsolutelyForcedExps []int64 `json:"absolutelyForcedExps,omitempty"`

	// ConditionallyForcedExpNames: Set of experiment names to be
	// conditionally forced. These experiments will be forced only if their
	// conditions and their parent domain's conditions are true.
	ConditionallyForcedExpNames []string `json:"conditionallyForcedExpNames,omitempty"`

	// ConditionallyForcedExpTags: Set of experiment tags to be
	// conditionally forced. The experiments with these tags will be forced
	// only if their conditions and their parent domain's conditions are
	// true.
	ConditionallyForcedExpTags []string `json:"conditionallyForcedExpTags,omitempty"`

	// ConditionallyForcedExps: Set of experiment ids to be conditionally
	// forced. These ids will be forced only if their conditions and their
	// parent domain's conditions are true.
	ConditionallyForcedExps []int64 `json:"conditionallyForcedExps,omitempty"`

	// DisableAutomaticEnrollmentSelection: If true, disable automatic
	// enrollment selection (at all diversion points). Automatic enrollment
	// selection means experiment selection process based on the
	// experiment's automatic enrollment condition. This does not disable
	// selection of forced experiments.
	DisableAutomaticEnrollmentSelection bool `json:"disableAutomaticEnrollmentSelection,omitempty"`

	// DisableExpNames: Set of experiment names to be disabled. If an
	// experiment is disabled, it is never selected nor forced. If an
	// aggregate experiment is disabled, its partitions are disabled
	// together. If an experiment with an enrollment is disabled, the
	// enrollment is disabled together. If a name corresponds to a domain,
	// the domain itself and all descendant experiments and domains are
	// disabled together.
	DisableExpNames []string `json:"disableExpNames,omitempty"`

	// DisableExpTags: Set of experiment tags to be disabled. All
	// experiments that are tagged with one or more of these tags are
	// disabled. If an experiment is disabled, it is never selected nor
	// forced. If an aggregate experiment is disabled, its partitions are
	// disabled together. If an experiment with an enrollment is disabled,
	// the enrollment is disabled together.
	DisableExpTags []string `json:"disableExpTags,omitempty"`

	// DisableExps: Set of experiment ids to be disabled. If an experiment
	// is disabled, it is never selected nor forced. If an aggregate
	// experiment is disabled, its partitions are disabled together. If an
	// experiment with an enrollment is disabled, the enrollment is disabled
	// together. If an ID corresponds to a domain, the domain itself and all
	// descendant experiments and domains are disabled together.
	DisableExps []int64 `json:"disableExps,omitempty"`

	// DisableManualEnrollmentSelection: If true, disable manual enrollment
	// selection (at all diversion points). Manual enrollment selection
	// means experiment selection process based on the request's manual
	// enrollment states (a.k.a. opt-in experiments). This does not disable
	// selection of forced experiments.
	DisableManualEnrollmentSelection bool `json:"disableManualEnrollmentSelection,omitempty"`

	// DisableOrganicSelection: If true, disable organic experiment
	// selection (at all diversion points). Organic selection means
	// experiment selection process based on traffic allocation and
	// diversion condition evaluation. This does not disable selection of
	// forced experiments. This is useful in cases when it is not known
	// whether experiment selection behavior is responsible for a error or
	// breakage. Disabling organic selection may help to isolate the cause
	// of a given problem.
	DisableOrganicSelection bool `json:"disableOrganicSelection,omitempty"`

	// ForcedFlags: Flags to force in a particular experiment state. Map
	// from flag name to flag value.
	ForcedFlags map[string]string `json:"forcedFlags,omitempty"`

	// ForcedRollouts: Rollouts to force in a particular experiment state.
	// Map from rollout name to rollout value.
	ForcedRollouts map[string]bool `json:"forcedRollouts,omitempty"`

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

// NumericBucketingOption: Input only. Use this field to specify
// bucketing option for the histogram search response.
type NumericBucketingOption struct {
	// BucketBounds: Required. Two adjacent values form a histogram bucket.
	// Values should be in ascending order. For example, if [5, 10, 15] are
	// provided, four buckets are created: (-inf, 5), 5, 10), [10, 15), [15,
	// inf). At most 20 [buckets_bound is supported.
	BucketBounds []float64 `json:"bucketBounds,omitempty"`

	// RequiresMinMax: Optional. If set to true, the histogram result
	// includes minimum/maximum value of the numeric field.
	RequiresMinMax bool `json:"requiresMinMax,omitempty"`

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

// NumericBucketingResult: Output only. Custom numeric bucketing result.
type NumericBucketingResult struct {
	// Counts: Count within each bucket. Its size is the length of
	// NumericBucketingOption.bucket_bounds plus 1.
	Counts []*BucketizedCount `json:"counts,omitempty"`

	// MaxValue: Stores the maximum value of the numeric field. Is populated
	// only if [NumericBucketingOption.requires_min_max] is set to true.
	MaxValue float64 `json:"maxValue,omitempty"`

	// MinValue: Stores the minimum value of the numeric field. Will be
	// populated only if [NumericBucketingOption.requires_min_max] is set to
	// true.
	MinValue float64 `json:"minValue,omitempty"`

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

func (s *NumericBucketingResult) UnmarshalJSON(data []byte) error {
	type NoMethod NumericBucketingResult
	var s1 struct {
		MaxValue gensupport.JSONFloat64 `json:"maxValue"`
		MinValue gensupport.JSONFloat64 `json:"minValue"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.MaxValue = float64(s1.MaxValue)
	s.MinValue = float64(s1.MinValue)
	return nil
}

// Operation: This resource represents a long-running operation that is
// the result of a network API call.
type Operation 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 *Status `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 *Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PostalAddress: Represents a postal address, e.g. for postal delivery
// or payments addresses. Given a postal address, a postal service can
// deliver items to a premise, P.O. Box or similar. It is not intended
// to model geographical locations (roads, towns, mountains). In typical
// usage an address would be created via user input or from importing
// existing data, depending on the type of process. Advice on address
// input / editing: - Use an i18n-ready address widget such as
// https://github.com/google/libaddressinput) - Users should not be
// presented with UI elements for input or editing of fields outside
// countries where that field is used. For more guidance on how to use
// this schema, please see:
// https://support.google.com/business/answer/6397478
type PostalAddress struct {
	// AddressLines: Unstructured address lines describing the lower levels
	// of an address. Because values in address_lines do not have type
	// information and may sometimes contain multiple values in a single
	// field (e.g. "Austin, TX"), it is important that the line order is
	// clear. The order of address lines should be "envelope order" for the
	// country/region of the address. In places where this can vary (e.g.
	// Japan), address_language is used to make it explicit (e.g. "ja" for
	// large-to-small ordering and "ja-Latn" or "en" for small-to-large).
	// This way, the most specific line of an address can be selected based
	// on the language. The minimum permitted structural representation of
	// an address consists of a region_code with all remaining information
	// placed in the address_lines. It would be possible to format such an
	// address very approximately without geocoding, but no semantic
	// reasoning could be made about any of the address components until it
	// was at least partially resolved. Creating an address only containing
	// a region_code and address_lines, and then geocoding is the
	// recommended way to handle completely unstructured addresses (as
	// opposed to guessing which parts of the address should be localities
	// or administrative areas).
	AddressLines []string `json:"addressLines,omitempty"`

	// AdministrativeArea: Optional. Highest administrative subdivision
	// which is used for postal addresses of a country or region. For
	// example, this can be a state, a province, an oblast, or a prefecture.
	// Specifically, for Spain this is the province and not the autonomous
	// community (e.g. "Barcelona" and not "Catalonia"). Many countries
	// don't use an administrative area in postal addresses. E.g. in
	// Switzerland this should be left unpopulated.
	AdministrativeArea string `json:"administrativeArea,omitempty"`

	// LanguageCode: Optional. BCP-47 language code of the contents of this
	// address (if known). This is often the UI language of the input form
	// or is expected to match one of the languages used in the address'
	// country/region, or their transliterated equivalents. This can affect
	// formatting in certain countries, but is not critical to the
	// correctness of the data and will never affect any validation or other
	// non-formatting related operations. If this value is not known, it
	// should be omitted (rather than specifying a possibly incorrect
	// default). Examples: "zh-Hant", "ja", "ja-Latn", "en".
	LanguageCode string `json:"languageCode,omitempty"`

	// Locality: Optional. Generally refers to the city/town portion of the
	// address. Examples: US city, IT comune, UK post town. In regions of
	// the world where localities are not well defined or do not fit into
	// this structure well, leave locality empty and use address_lines.
	Locality string `json:"locality,omitempty"`

	// Organization: Optional. The name of the organization at the address.
	Organization string `json:"organization,omitempty"`

	// PostalCode: Optional. Postal code of the address. Not all countries
	// use or require postal codes to be present, but where they are used,
	// they may trigger additional validation with other parts of the
	// address (e.g. state/zip validation in the U.S.A.).
	PostalCode string `json:"postalCode,omitempty"`

	// Recipients: Optional. The recipient at the address. This field may,
	// under certain circumstances, contain multiline information. For
	// example, it might contain "care of" information.
	Recipients []string `json:"recipients,omitempty"`

	// RegionCode: Required. CLDR region code of the country/region of the
	// address. This is never inferred and it is up to the user to ensure
	// the value is correct. See http://cldr.unicode.org/ and
	// http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html for details. Example: "CH" for
	// Switzerland.
	RegionCode string `json:"regionCode,omitempty"`

	// Revision: The schema revision of the `PostalAddress`. This must be
	// set to 0, which is the latest revision. All new revisions **must** be
	// backward compatible with old revisions.
	Revision int64 `json:"revision,omitempty"`

	// SortingCode: Optional. Additional, country-specific, sorting code.
	// This is not used in most regions. Where it is used, the value is
	// either a string like "CEDEX", optionally followed by a number (e.g.
	// "CEDEX 7"), or just a number alone, representing the "sector code"
	// (Jamaica), "delivery area indicator" (Malawi) or "post office
	// indicator" (e.g. Côte d'Ivoire).
	SortingCode string `json:"sortingCode,omitempty"`

	// Sublocality: Optional. Sublocality of the address. For example, this
	// can be neighborhoods, boroughs, districts.
	Sublocality string `json:"sublocality,omitempty"`

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

// ProcessingOptions: Input only. Options for job processing.
type ProcessingOptions struct {
	// DisableStreetAddressResolution: Optional. If set to `true`, the
	// service does not attempt to resolve a more precise address for the
	// job.
	DisableStreetAddressResolution bool `json:"disableStreetAddressResolution,omitempty"`

	// HtmlSanitization: Optional. Option for job HTML content sanitization.
	// Applied fields are: * description * applicationInfo.instruction *
	// incentives * qualifications * responsibilities HTML tags in these
	// fields may be stripped if sanitiazation is not disabled. Defaults to
	// HtmlSanitization.SIMPLE_FORMATTING_ONLY.
	//
	// Possible values:
	//   "HTML_SANITIZATION_UNSPECIFIED" - Default value.
	//   "HTML_SANITIZATION_DISABLED" - Disables sanitization on HTML input.
	//   "SIMPLE_FORMATTING_ONLY" - Sanitizes HTML input, only accepts bold,
	// italic, ordered list, and unordered list markup tags.
	HtmlSanitization string `json:"htmlSanitization,omitempty"`

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

// RequestMetadata: Input only. Meta information related to the job
// searcher or entity conducting the job search. This information is
// used to improve the performance of the service.
type RequestMetadata struct {
	// DeviceInfo: Optional. The type of device used by the job seeker at
	// the time of the call to the service.
	DeviceInfo *DeviceInfo `json:"deviceInfo,omitempty"`

	// Domain: Required. The client-defined scope or source of the service
	// call, which typically is the domain on which the service has been
	// implemented and is currently being run. For example, if the service
	// is being run by client *Foo, Inc.*, on job board www.foo.com and
	// career site www.bar.com, then this field is set to "foo.com" for use
	// on the job board, and "bar.com" for use on the career site. If this
	// field isn't available for some reason, send "UNKNOWN". Any
	// improvements to the model for a particular tenant site rely on this
	// field being set correctly to a domain. The maximum number of allowed
	// characters is 255.
	Domain string `json:"domain,omitempty"`

	// SessionId: Required. A unique session identification string. A
	// session is defined as the duration of an end user's interaction with
	// the service over a certain period. Obfuscate this field for privacy
	// concerns before providing it to the service. If this field is not
	// available for some reason, send "UNKNOWN". Note that any improvements
	// to the model for a particular tenant site, rely on this field being
	// set correctly to some unique session_id. The maximum number of
	// allowed characters is 255.
	SessionId string `json:"sessionId,omitempty"`

	// UserId: Required. A unique user identification string, as determined
	// by the client. To have the strongest positive impact on search
	// quality make sure the client-level is unique. Obfuscate this field
	// for privacy concerns before providing it to the service. If this
	// field is not available for some reason, send "UNKNOWN". Note that any
	// improvements to the model for a particular tenant site, rely on this
	// field being set correctly to a unique user_id. The maximum number of
	// allowed characters is 255.
	UserId string `json:"userId,omitempty"`

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

// ResponseMetadata: Output only. Additional information returned to
// client, such as debugging information.
type ResponseMetadata struct {
	// RequestId: A unique id associated with this call. This id is logged
	// for tracking purposes.
	RequestId string `json:"requestId,omitempty"`

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

// SearchJobsRequest: Input only. The Request body of the `SearchJobs`
// call.
type SearchJobsRequest struct {
	// CustomRankingInfo: Optional. Controls over how job documents get
	// ranked on top of existing relevance score (determined by API
	// algorithm).
	CustomRankingInfo *CustomRankingInfo `json:"customRankingInfo,omitempty"`

	// DisableKeywordMatch: Optional. Controls whether to disable exact
	// keyword match on Job.job_title, Job.description,
	// Job.company_display_name, Job.locations, Job.qualifications. When
	// disable keyword match is turned off, a keyword match returns jobs
	// that do not match given category filters when there are matching
	// keywords. For example, the query "program manager," a result is
	// returned even if the job posting has the title "software developer,"
	// which does not fall into "program manager" ontology, but does have
	// "program manager" appearing in its description. For queries like
	// "cloud" that does not contain title or location specific ontology,
	// jobs with "cloud" keyword matches are returned regardless of this
	// flag's value. Please use Company.keyword_searchable_custom_fields or
	// Company.keyword_searchable_custom_attributes if company specific
	// globally matched custom field/attribute string values is needed.
	// Enabling keyword match improves recall of subsequent search requests.
	// Defaults to false.
	DisableKeywordMatch bool `json:"disableKeywordMatch,omitempty"`

	// DiversificationLevel: Optional. Controls whether highly similar jobs
	// are returned next to each other in the search results. Jobs are
	// identified as highly similar based on their titles, job categories,
	// and locations. Highly similar results are clustered so that only one
	// representative job of the cluster is displayed to the job seeker
	// higher up in the results, with the other jobs being displayed lower
	// down in the results. Defaults to DiversificationLevel.SIMPLE if no
	// value is specified.
	//
	// Possible values:
	//   "DIVERSIFICATION_LEVEL_UNSPECIFIED" - The diversification level
	// isn't specified. By default, jobs with this enum are ordered
	// according to SIMPLE diversifying behavior.
	//   "DISABLED" - Disables diversification. Jobs that would normally be
	// pushed to the last page would not have their positions altered. This
	// may result in highly similar jobs appearing in sequence in the search
	// results.
	//   "SIMPLE" - Default diversifying behavior. The result list is
	// ordered so that highly similar results are pushed to the end of the
	// last page of search results.
	DiversificationLevel string `json:"diversificationLevel,omitempty"`

	// EnableBroadening: Optional. Controls whether to broaden the search
	// when it produces sparse results. Broadened queries append results to
	// the end of the matching results list. Defaults to false.
	EnableBroadening bool `json:"enableBroadening,omitempty"`

	// HistogramFacets: Optional. Histogram requests for jobs matching
	// JobQuery.
	HistogramFacets *HistogramFacets `json:"histogramFacets,omitempty"`

	// HistogramQueries: Optional. Expression based histogram requests for
	// jobs matching JobQuery.
	HistogramQueries []*HistogramQuery `json:"histogramQueries,omitempty"`

	// JobQuery: Optional. Query used to search against jobs, such as
	// keyword, location filters, etc.
	JobQuery *JobQuery `json:"jobQuery,omitempty"`

	// JobView: Optional. The desired job attributes returned for jobs in
	// the search response. Defaults to JobView.SMALL if no value is
	// specified.
	//
	// Possible values:
	//   "JOB_VIEW_UNSPECIFIED" - Default value.
	//   "JOB_VIEW_ID_ONLY" - A ID only view of job, with following
	// attributes: Job.name, Job.requisition_id, Job.language_code.
	//   "JOB_VIEW_MINIMAL" - A minimal view of the job, with the following
	// attributes: Job.name, Job.requisition_id, Job.title,
	// Job.company_name, Job.DerivedInfo.locations, Job.language_code.
	//   "JOB_VIEW_SMALL" - A small view of the job, with the following
	// attributes in the search results: Job.name, Job.requisition_id,
	// Job.title, Job.company_name, Job.DerivedInfo.locations,
	// Job.visibility, Job.language_code, Job.description.
	//   "JOB_VIEW_FULL" - All available attributes are included in the
	// search results.
	JobView string `json:"jobView,omitempty"`

	// Offset: Optional. An integer that specifies the current offset (that
	// is, starting result location, amongst the jobs deemed by the API as
	// relevant) in search results. This field is only considered if
	// page_token is unset. The maximum allowed value is 5000. Otherwise an
	// error is thrown. For example, 0 means to return results starting from
	// the first matching job, and 10 means to return from the 11th job.
	// This can be used for pagination, (for example, pageSize = 10 and
	// offset = 10 means to return from the second page).
	Offset int64 `json:"offset,omitempty"`

	// OrderBy: Optional. The criteria determining how search results are
	// sorted. Default is "relevance desc". Supported options are: *
	// "relevance desc": By relevance descending, as determined by the API
	// algorithms. Relevance thresholding of query results is only available
	// with this ordering. * "posting_publish_time desc": By
	// Job.posting_publish_time descending. * "posting_update_time desc":
	// By Job.posting_update_time descending. * "title": By Job.title
	// ascending. * "title desc": By Job.title descending. *
	// "annualized_base_compensation": By job's
	// CompensationInfo.annualized_base_compensation_range ascending. Jobs
	// whose annualized base compensation is unspecified are put at the end
	// of search results. * "annualized_base_compensation desc": By job's
	// CompensationInfo.annualized_base_compensation_range descending. Jobs
	// whose annualized base compensation is unspecified are put at the end
	// of search results. * "annualized_total_compensation": By job's
	// CompensationInfo.annualized_total_compensation_range ascending. Jobs
	// whose annualized base compensation is unspecified are put at the end
	// of search results. * "annualized_total_compensation desc": By job's
	// CompensationInfo.annualized_total_compensation_range descending. Jobs
	// whose annualized base compensation is unspecified are put at the end
	// of search results. * "custom_ranking desc": By the relevance score
	// adjusted to the
	// SearchJobsRequest.custom_ranking_info.ranking_expression with weight
	// factor assigned by
	// SearchJobsRequest.custom_ranking_info.importance_level in descending
	// order. * Location sorting: Use the special syntax to order jobs by
	// distance: "distance_from('Hawaii')": Order by distance from Hawaii.
	// "distance_from(19.89, 155.5)": Order by distance from a coordinate.
	// "distance_from('Hawaii'), distance_from('Puerto Rico')": Order by
	// multiple locations. See details below. "distance_from('Hawaii'),
	// distance_from(19.89, 155.5)": Order by multiple locations. See
	// details below. The string can have a maximum of 256 characters. When
	// multiple distance centers are provided, a job that is close to any of
	// the distance centers would have a high rank. When a job has multiple
	// locations, the job location closest to one of the distance centers
	// will be used. Jobs that don't have locations will be ranked at the
	// bottom. Distance is calculated with a precision of 11.3 meters (37.4
	// feet). Diversification strategy is still applied unless explicitly
	// disabled in diversification_level.
	OrderBy string `json:"orderBy,omitempty"`

	// PageSize: Optional. A limit on the number of jobs returned in the
	// search results. Increasing this value above the default value of 10
	// can increase search response time. The value can be between 1 and
	// 100.
	PageSize int64 `json:"pageSize,omitempty"`

	// PageToken: Optional. The token specifying the current offset within
	// search results. See SearchJobsResponse.next_page_token for an
	// explanation of how to obtain the next set of query results.
	PageToken string `json:"pageToken,omitempty"`

	// RequestMetadata: Required. The meta information collected about the
	// job searcher, used to improve the search quality of the service. The
	// identifiers (such as `user_id`) are provided by users, and must be
	// unique and consistent.
	RequestMetadata *RequestMetadata `json:"requestMetadata,omitempty"`

	// RequirePreciseResultSize: This field is deprecated.
	RequirePreciseResultSize bool `json:"requirePreciseResultSize,omitempty"`

	// SearchMode: Optional. Mode of a search. Defaults to
	// SearchMode.JOB_SEARCH.
	//
	// Possible values:
	//   "SEARCH_MODE_UNSPECIFIED" - The mode of the search method isn't
	// specified. The default search behavior is identical to JOB_SEARCH
	// search behavior.
	//   "JOB_SEARCH" - The job search matches against all jobs, and
	// featured jobs (jobs with promotionValue > 0) are not specially
	// handled.
	//   "FEATURED_JOB_SEARCH" - The job search matches only against
	// featured jobs (jobs with a promotionValue > 0). This method doesn't
	// return any jobs having a promotionValue <= 0. The search results
	// order is determined by the promotionValue (jobs with a higher
	// promotionValue are returned higher up in the search results), with
	// relevance being used as a tiebreaker.
	SearchMode string `json:"searchMode,omitempty"`

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

// SearchJobsResponse: Output only. Response for SearchJob method.
type SearchJobsResponse struct {
	// BroadenedQueryJobsCount: If query broadening is enabled, we may
	// append additional results from the broadened query. This number
	// indicates how many of the jobs returned in the jobs field are from
	// the broadened query. These results are always at the end of the jobs
	// list. In particular, a value of 0, or if the field isn't set, all the
	// jobs in the jobs list are from the original (without broadening)
	// query. If this field is non-zero, subsequent requests with offset
	// after this result set should contain all broadened results.
	BroadenedQueryJobsCount int64 `json:"broadenedQueryJobsCount,omitempty"`

	// EstimatedTotalSize: An estimation of the number of jobs that match
	// the specified query. This number is not guaranteed to be accurate.
	// For accurate results, see SearchJobsResponse.total_size.
	EstimatedTotalSize int64 `json:"estimatedTotalSize,omitempty"`

	// HistogramQueryResults: The histogram results that match with
	// specified SearchJobsRequest.histogram_queries.
	HistogramQueryResults []*HistogramQueryResult `json:"histogramQueryResults,omitempty"`

	// HistogramResults: The histogram results that match specified
	// SearchJobsRequest.histogram_facets.
	HistogramResults *HistogramResults `json:"histogramResults,omitempty"`

	// LocationFilters: The location filters that the service applied to the
	// specified query. If any filters are lat-lng based, the
	// JobLocation.location_type is
	// JobLocation.LocationType#LOCATION_TYPE_UNSPECIFIED.
	LocationFilters []*Location `json:"locationFilters,omitempty"`

	// MatchingJobs: The Job entities that match the specified
	// SearchJobsRequest.
	MatchingJobs []*MatchingJob `json:"matchingJobs,omitempty"`

	// Metadata: Additional information for the API invocation, such as the
	// request tracking id.
	Metadata *ResponseMetadata `json:"metadata,omitempty"`

	// NextPageToken: The token that specifies the starting position of the
	// next page of results. This field is empty if there are no more
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SpellCorrection: The spell checking result, and correction.
	SpellCorrection *SpellingCorrection `json:"spellCorrection,omitempty"`

	// TotalSize: The precise result count with limit 100,000.
	TotalSize int64 `json:"totalSize,omitempty"`

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

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

// SpellingCorrection: Output only. Spell check result.
type SpellingCorrection struct {
	// Corrected: Indicates if the query was corrected by the spell checker.
	Corrected bool `json:"corrected,omitempty"`

	// CorrectedText: Correction output consisting of the corrected keyword
	// string.
	CorrectedText string `json:"correctedText,omitempty"`

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

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

// TimeOfDay: Represents a time of day. The date and time zone are
// either not significant or are specified elsewhere. An API may choose
// to allow leap seconds. Related types are google.type.Date and
// `google.protobuf.Timestamp`.
type TimeOfDay struct {
	// Hours: Hours of day in 24 hour format. Should be from 0 to 23. An API
	// may choose to allow the value "24:00:00" for scenarios like business
	// closing time.
	Hours int64 `json:"hours,omitempty"`

	// Minutes: Minutes of hour of day. Must be from 0 to 59.
	Minutes int64 `json:"minutes,omitempty"`

	// Nanos: Fractions of seconds in nanoseconds. Must be from 0 to
	// 999,999,999.
	Nanos int64 `json:"nanos,omitempty"`

	// Seconds: Seconds of minutes of the time. Must normally be from 0 to
	// 59. An API may allow the value 60 if it allows leap-seconds.
	Seconds int64 `json:"seconds,omitempty"`

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

// TimestampRange: Message representing a period of time between two
// timestamps.
type TimestampRange struct {
	// EndTime: End of the period.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Begin of the period.
	StartTime string `json:"startTime,omitempty"`

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

// UpdateCompanyRequest: Input only. Request for updating a specified
// company.
type UpdateCompanyRequest struct {
	// Company: Required. The company resource to replace the current
	// resource in the system.
	Company *Company `json:"company,omitempty"`

	// UpdateMask: Optional but strongly recommended for the best service
	// experience. If update_mask is provided, only the specified fields in
	// company are updated. Otherwise all the fields are updated. A field
	// mask to specify the company fields to be updated. Only top level
	// fields of Company are supported.
	UpdateMask string `json:"updateMask,omitempty"`

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

// UpdateJobRequest: Input only. Update job request.
type UpdateJobRequest struct {
	// Job: Required. The Job to be updated.
	Job *Job `json:"job,omitempty"`

	// UpdateMask: Optional but strongly recommended to be provided for the
	// best service experience. If update_mask is provided, only the
	// specified fields in job are updated. Otherwise all the fields are
	// updated. A field mask to restrict the fields that are updated. Only
	// top level fields of Job are supported.
	UpdateMask string `json:"updateMask,omitempty"`

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

// method id "jobs.projects.complete":

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

// Complete: Completes the specified prefix with keyword suggestions.
// Intended for use by a job search auto-complete search box.
func (r *ProjectsService) Complete(name string) *ProjectsCompleteCall {
	c := &ProjectsCompleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// CompanyName sets the optional parameter "companyName": If provided,
// restricts completion to specified company. The format is
// "projects/{project_id}/companies/{company_id}", for example,
// "projects/api-test-project/companies/foo".
func (c *ProjectsCompleteCall) CompanyName(companyName string) *ProjectsCompleteCall {
	c.urlParams_.Set("companyName", companyName)
	return c
}

// LanguageCode sets the optional parameter "languageCode": Deprecated.
// Use language_codes instead.  The language of the query. This is the
// BCP-47 language code, such as "en-US" or "sr-Latn". For more
// information, see [Tags for Identifying
// Languages](https://tools.ietf.org/html/bcp47). For
// CompletionType.JOB_TITLE type, only open jobs with the same
// language_code are returned. For CompletionType.COMPANY_NAME type,
// only companies having open jobs with the same language_code are
// returned. For CompletionType.COMBINED type, only open jobs with the
// same language_code or companies having open jobs with the same
// language_code are returned. The maximum number of allowed characters
// is 255.
func (c *ProjectsCompleteCall) LanguageCode(languageCode string) *ProjectsCompleteCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// LanguageCodes sets the optional parameter "languageCodes": The list
// of languages of the query. This is the BCP-47 language code, such as
// "en-US" or "sr-Latn". For more information, see [Tags for Identifying
// Languages](https://tools.ietf.org/html/bcp47). For
// CompletionType.JOB_TITLE type, only open jobs with the same
// language_codes are returned. For CompletionType.COMPANY_NAME type,
// only companies having open jobs with the same language_codes are
// returned. For CompletionType.COMBINED type, only open jobs with the
// same language_codes or companies having open jobs with the same
// language_codes are returned. The maximum number of allowed characters
// is 255.
func (c *ProjectsCompleteCall) LanguageCodes(languageCodes ...string) *ProjectsCompleteCall {
	c.urlParams_.SetMulti("languageCodes", append([]string{}, languageCodes...))
	return c
}

// PageSize sets the optional parameter "pageSize": Required. Completion
// result count. The maximum allowed page size is 10.
func (c *ProjectsCompleteCall) PageSize(pageSize int64) *ProjectsCompleteCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// Query sets the optional parameter "query": Required. The query used
// to generate suggestions. The maximum number of allowed characters is
// 255.
func (c *ProjectsCompleteCall) Query(query string) *ProjectsCompleteCall {
	c.urlParams_.Set("query", query)
	return c
}

// Scope sets the optional parameter "scope": The scope of the
// completion. The defaults is CompletionScope.PUBLIC.
//
// Possible values:
//   "COMPLETION_SCOPE_UNSPECIFIED" - Default value.
//   "TENANT" - Suggestions are based only on the data provided by the
// client.
//   "PUBLIC" - Suggestions are based on all jobs data in the system
// that's visible to the client
func (c *ProjectsCompleteCall) Scope(scope string) *ProjectsCompleteCall {
	c.urlParams_.Set("scope", scope)
	return c
}

// Type sets the optional parameter "type": The completion topic. The
// default is CompletionType.COMBINED.
//
// Possible values:
//   "COMPLETION_TYPE_UNSPECIFIED" - Default value.
//   "JOB_TITLE" - Only suggest job titles.
//   "COMPANY_NAME" - Only suggest company names.
//   "COMBINED" - Suggest both job titles and company names.
func (c *ProjectsCompleteCall) Type(type_ string) *ProjectsCompleteCall {
	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 *ProjectsCompleteCall) Fields(s ...googleapi.Field) *ProjectsCompleteCall {
	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 *ProjectsCompleteCall) IfNoneMatch(entityTag string) *ProjectsCompleteCall {
	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 *ProjectsCompleteCall) Context(ctx context.Context) *ProjectsCompleteCall {
	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 *ProjectsCompleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCompleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+name}:complete")
	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 "jobs.projects.complete" call.
// Exactly one of *CompleteQueryResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CompleteQueryResponse.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 *ProjectsCompleteCall) Do(opts ...googleapi.CallOption) (*CompleteQueryResponse, 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 := &CompleteQueryResponse{
		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": "Completes the specified prefix with keyword suggestions. Intended for use by a job search auto-complete search box.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}:complete",
	//   "httpMethod": "GET",
	//   "id": "jobs.projects.complete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "companyName": {
	//       "description": "Optional. If provided, restricts completion to specified company. The format is \"projects/{project_id}/companies/{company_id}\", for example, \"projects/api-test-project/companies/foo\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCode": {
	//       "description": "Deprecated. Use language_codes instead. Optional. The language of the query. This is the BCP-47 language code, such as \"en-US\" or \"sr-Latn\". For more information, see [Tags for Identifying Languages](https://tools.ietf.org/html/bcp47). For CompletionType.JOB_TITLE type, only open jobs with the same language_code are returned. For CompletionType.COMPANY_NAME type, only companies having open jobs with the same language_code are returned. For CompletionType.COMBINED type, only open jobs with the same language_code or companies having open jobs with the same language_code are returned. The maximum number of allowed characters is 255.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCodes": {
	//       "description": "Optional. The list of languages of the query. This is the BCP-47 language code, such as \"en-US\" or \"sr-Latn\". For more information, see [Tags for Identifying Languages](https://tools.ietf.org/html/bcp47). For CompletionType.JOB_TITLE type, only open jobs with the same language_codes are returned. For CompletionType.COMPANY_NAME type, only companies having open jobs with the same language_codes are returned. For CompletionType.COMBINED type, only open jobs with the same language_codes or companies having open jobs with the same language_codes are returned. The maximum number of allowed characters is 255.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Resource name of project the completion is performed within. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Required. Completion result count. The maximum allowed page size is 10.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "query": {
	//       "description": "Required. The query used to generate suggestions. The maximum number of allowed characters is 255.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "scope": {
	//       "description": "Optional. The scope of the completion. The defaults is CompletionScope.PUBLIC.",
	//       "enum": [
	//         "COMPLETION_SCOPE_UNSPECIFIED",
	//         "TENANT",
	//         "PUBLIC"
	//       ],
	//       "enumDescriptions": [
	//         "Default value.",
	//         "Suggestions are based only on the data provided by the client.",
	//         "Suggestions are based on all jobs data in the system that's visible to the client"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Optional. The completion topic. The default is CompletionType.COMBINED.",
	//       "enum": [
	//         "COMPLETION_TYPE_UNSPECIFIED",
	//         "JOB_TITLE",
	//         "COMPANY_NAME",
	//         "COMBINED"
	//       ],
	//       "enumDescriptions": [
	//         "Default value.",
	//         "Only suggest job titles.",
	//         "Only suggest company names.",
	//         "Suggest both job titles and company names."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}:complete",
	//   "response": {
	//     "$ref": "CompleteQueryResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.clientEvents.create":

type ProjectsClientEventsCreateCall struct {
	s                        *Service
	parent                   string
	createclienteventrequest *CreateClientEventRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// Create: Report events issued when end user interacts with customer's
// application that uses Cloud Talent Solution. You may inspect the
// created events in [self service
// tools](https://console.cloud.google.com/talent-solution/overview).
// [Learn
// more](https://cloud.google.com/talent-solution/docs/management-tools)
// about self service tools.
func (r *ProjectsClientEventsService) Create(parent string, createclienteventrequest *CreateClientEventRequest) *ProjectsClientEventsCreateCall {
	c := &ProjectsClientEventsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.createclienteventrequest = createclienteventrequest
	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 *ProjectsClientEventsCreateCall) Fields(s ...googleapi.Field) *ProjectsClientEventsCreateCall {
	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 *ProjectsClientEventsCreateCall) Context(ctx context.Context) *ProjectsClientEventsCreateCall {
	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 *ProjectsClientEventsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsClientEventsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.createclienteventrequest)
	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, "v3p1beta1/{+parent}/clientEvents")
	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 "jobs.projects.clientEvents.create" call.
// Exactly one of *ClientEvent or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ClientEvent.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 *ProjectsClientEventsCreateCall) Do(opts ...googleapi.CallOption) (*ClientEvent, 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 := &ClientEvent{
		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": "Report events issued when end user interacts with customer's application that uses Cloud Talent Solution. You may inspect the created events in [self service tools](https://console.cloud.google.com/talent-solution/overview). [Learn more](https://cloud.google.com/talent-solution/docs/management-tools) about self service tools.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/clientEvents",
	//   "httpMethod": "POST",
	//   "id": "jobs.projects.clientEvents.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Parent project name.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/clientEvents",
	//   "request": {
	//     "$ref": "CreateClientEventRequest"
	//   },
	//   "response": {
	//     "$ref": "ClientEvent"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.companies.create":

type ProjectsCompaniesCreateCall struct {
	s                    *Service
	parent               string
	createcompanyrequest *CreateCompanyRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Create: Creates a new company entity.
func (r *ProjectsCompaniesService) Create(parent string, createcompanyrequest *CreateCompanyRequest) *ProjectsCompaniesCreateCall {
	c := &ProjectsCompaniesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.createcompanyrequest = createcompanyrequest
	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 *ProjectsCompaniesCreateCall) Fields(s ...googleapi.Field) *ProjectsCompaniesCreateCall {
	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 *ProjectsCompaniesCreateCall) Context(ctx context.Context) *ProjectsCompaniesCreateCall {
	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 *ProjectsCompaniesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCompaniesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.createcompanyrequest)
	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, "v3p1beta1/{+parent}/companies")
	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 "jobs.projects.companies.create" call.
// Exactly one of *Company or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Company.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 *ProjectsCompaniesCreateCall) Do(opts ...googleapi.CallOption) (*Company, 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 := &Company{
		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 company entity.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/companies",
	//   "httpMethod": "POST",
	//   "id": "jobs.projects.companies.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. Resource name of the project under which the company is created. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/companies",
	//   "request": {
	//     "$ref": "CreateCompanyRequest"
	//   },
	//   "response": {
	//     "$ref": "Company"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.companies.delete":

type ProjectsCompaniesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes specified company. Prerequisite: The company has no
// jobs associated with it.
func (r *ProjectsCompaniesService) Delete(name string) *ProjectsCompaniesDeleteCall {
	c := &ProjectsCompaniesDeleteCall{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 *ProjectsCompaniesDeleteCall) Fields(s ...googleapi.Field) *ProjectsCompaniesDeleteCall {
	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 *ProjectsCompaniesDeleteCall) Context(ctx context.Context) *ProjectsCompaniesDeleteCall {
	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 *ProjectsCompaniesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCompaniesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+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 "jobs.projects.companies.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *ProjectsCompaniesDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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 specified company. Prerequisite: The company has no jobs associated with it.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/companies/{companiesId}",
	//   "httpMethod": "DELETE",
	//   "id": "jobs.projects.companies.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the company to be deleted. The format is \"projects/{project_id}/companies/{company_id}\", for example, \"projects/api-test-project/companies/foo\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/companies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.companies.get":

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

// Get: Retrieves specified company.
func (r *ProjectsCompaniesService) Get(name string) *ProjectsCompaniesGetCall {
	c := &ProjectsCompaniesGetCall{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 *ProjectsCompaniesGetCall) Fields(s ...googleapi.Field) *ProjectsCompaniesGetCall {
	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 *ProjectsCompaniesGetCall) IfNoneMatch(entityTag string) *ProjectsCompaniesGetCall {
	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 *ProjectsCompaniesGetCall) Context(ctx context.Context) *ProjectsCompaniesGetCall {
	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 *ProjectsCompaniesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCompaniesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+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 "jobs.projects.companies.get" call.
// Exactly one of *Company or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Company.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 *ProjectsCompaniesGetCall) Do(opts ...googleapi.CallOption) (*Company, 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 := &Company{
		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 specified company.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/companies/{companiesId}",
	//   "httpMethod": "GET",
	//   "id": "jobs.projects.companies.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the company to be retrieved. The format is \"projects/{project_id}/companies/{company_id}\", for example, \"projects/api-test-project/companies/foo\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/companies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}",
	//   "response": {
	//     "$ref": "Company"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.companies.list":

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

// List: Lists all companies associated with the service account.
func (r *ProjectsCompaniesService) List(parent string) *ProjectsCompaniesListCall {
	c := &ProjectsCompaniesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of companies to be returned, at most 100. Default is 100 if a
// non-positive number is provided.
func (c *ProjectsCompaniesListCall) PageSize(pageSize int64) *ProjectsCompaniesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The starting
// indicator from which to return results.
func (c *ProjectsCompaniesListCall) PageToken(pageToken string) *ProjectsCompaniesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RequireOpenJobs sets the optional parameter "requireOpenJobs": Set to
// true if the companies requested must have open jobs. Defaults to
// false. If true, at most page_size of companies are fetched, among
// which only those with open jobs are returned.
func (c *ProjectsCompaniesListCall) RequireOpenJobs(requireOpenJobs bool) *ProjectsCompaniesListCall {
	c.urlParams_.Set("requireOpenJobs", fmt.Sprint(requireOpenJobs))
	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 *ProjectsCompaniesListCall) Fields(s ...googleapi.Field) *ProjectsCompaniesListCall {
	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 *ProjectsCompaniesListCall) IfNoneMatch(entityTag string) *ProjectsCompaniesListCall {
	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 *ProjectsCompaniesListCall) Context(ctx context.Context) *ProjectsCompaniesListCall {
	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 *ProjectsCompaniesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCompaniesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+parent}/companies")
	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 "jobs.projects.companies.list" call.
// Exactly one of *ListCompaniesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListCompaniesResponse.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 *ProjectsCompaniesListCall) Do(opts ...googleapi.CallOption) (*ListCompaniesResponse, 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 := &ListCompaniesResponse{
		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 companies associated with the service account.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/companies",
	//   "httpMethod": "GET",
	//   "id": "jobs.projects.companies.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of companies to be returned, at most 100. Default is 100 if a non-positive number is provided.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The starting indicator from which to return results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Resource name of the project under which the company is created. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requireOpenJobs": {
	//       "description": "Optional. Set to true if the companies requested must have open jobs. Defaults to false. If true, at most page_size of companies are fetched, among which only those with open jobs are returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/companies",
	//   "response": {
	//     "$ref": "ListCompaniesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// 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 *ProjectsCompaniesListCall) Pages(ctx context.Context, f func(*ListCompaniesResponse) 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 "jobs.projects.companies.patch":

type ProjectsCompaniesPatchCall struct {
	s                    *Service
	name                 string
	updatecompanyrequest *UpdateCompanyRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Patch: Updates specified company. Company names can't be updated. To
// update a company name, delete the company and all jobs associated
// with it, and only then re-create them.
func (r *ProjectsCompaniesService) Patch(name string, updatecompanyrequest *UpdateCompanyRequest) *ProjectsCompaniesPatchCall {
	c := &ProjectsCompaniesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.updatecompanyrequest = updatecompanyrequest
	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 *ProjectsCompaniesPatchCall) Fields(s ...googleapi.Field) *ProjectsCompaniesPatchCall {
	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 *ProjectsCompaniesPatchCall) Context(ctx context.Context) *ProjectsCompaniesPatchCall {
	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 *ProjectsCompaniesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsCompaniesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.updatecompanyrequest)
	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, "v3p1beta1/{+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 "jobs.projects.companies.patch" call.
// Exactly one of *Company or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Company.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 *ProjectsCompaniesPatchCall) Do(opts ...googleapi.CallOption) (*Company, 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 := &Company{
		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 specified company. Company names can't be updated. To update a company name, delete the company and all jobs associated with it, and only then re-create them.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/companies/{companiesId}",
	//   "httpMethod": "PATCH",
	//   "id": "jobs.projects.companies.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required during company update. The resource name for a company. This is generated by the service when a company is created. The format is \"projects/{project_id}/companies/{company_id}\", for example, \"projects/api-test-project/companies/foo\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/companies/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}",
	//   "request": {
	//     "$ref": "UpdateCompanyRequest"
	//   },
	//   "response": {
	//     "$ref": "Company"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.jobs.batchDelete":

type ProjectsJobsBatchDeleteCall struct {
	s                      *Service
	parent                 string
	batchdeletejobsrequest *BatchDeleteJobsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// BatchDelete: Deletes a list of Jobs by filter.
func (r *ProjectsJobsService) BatchDelete(parent string, batchdeletejobsrequest *BatchDeleteJobsRequest) *ProjectsJobsBatchDeleteCall {
	c := &ProjectsJobsBatchDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.batchdeletejobsrequest = batchdeletejobsrequest
	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 *ProjectsJobsBatchDeleteCall) Fields(s ...googleapi.Field) *ProjectsJobsBatchDeleteCall {
	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 *ProjectsJobsBatchDeleteCall) Context(ctx context.Context) *ProjectsJobsBatchDeleteCall {
	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 *ProjectsJobsBatchDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsBatchDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.batchdeletejobsrequest)
	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, "v3p1beta1/{+parent}/jobs:batchDelete")
	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 "jobs.projects.jobs.batchDelete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *ProjectsJobsBatchDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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 list of Jobs by filter.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs:batchDelete",
	//   "httpMethod": "POST",
	//   "id": "jobs.projects.jobs.batchDelete",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The resource name of the project under which the job is created. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/jobs:batchDelete",
	//   "request": {
	//     "$ref": "BatchDeleteJobsRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.jobs.create":

type ProjectsJobsCreateCall struct {
	s                *Service
	parent           string
	createjobrequest *CreateJobRequest
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Create: Creates a new job. Typically, the job becomes searchable
// within 10 seconds, but it may take up to 5 minutes.
func (r *ProjectsJobsService) Create(parent string, createjobrequest *CreateJobRequest) *ProjectsJobsCreateCall {
	c := &ProjectsJobsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.createjobrequest = createjobrequest
	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 *ProjectsJobsCreateCall) Fields(s ...googleapi.Field) *ProjectsJobsCreateCall {
	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 *ProjectsJobsCreateCall) Context(ctx context.Context) *ProjectsJobsCreateCall {
	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 *ProjectsJobsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.createjobrequest)
	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, "v3p1beta1/{+parent}/jobs")
	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 "jobs.projects.jobs.create" call.
// Exactly one of *Job or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either
// *Job.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 *ProjectsJobsCreateCall) Do(opts ...googleapi.CallOption) (*Job, 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 := &Job{
		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 job. Typically, the job becomes searchable within 10 seconds, but it may take up to 5 minutes.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs",
	//   "httpMethod": "POST",
	//   "id": "jobs.projects.jobs.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The resource name of the project under which the job is created. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/jobs",
	//   "request": {
	//     "$ref": "CreateJobRequest"
	//   },
	//   "response": {
	//     "$ref": "Job"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.jobs.delete":

type ProjectsJobsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified job. Typically, the job becomes
// unsearchable within 10 seconds, but it may take up to 5 minutes.
func (r *ProjectsJobsService) Delete(name string) *ProjectsJobsDeleteCall {
	c := &ProjectsJobsDeleteCall{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 *ProjectsJobsDeleteCall) Fields(s ...googleapi.Field) *ProjectsJobsDeleteCall {
	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 *ProjectsJobsDeleteCall) Context(ctx context.Context) *ProjectsJobsDeleteCall {
	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 *ProjectsJobsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+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 "jobs.projects.jobs.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *ProjectsJobsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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 specified job. Typically, the job becomes unsearchable within 10 seconds, but it may take up to 5 minutes.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs/{jobsId}",
	//   "httpMethod": "DELETE",
	//   "id": "jobs.projects.jobs.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the job to be deleted. The format is \"projects/{project_id}/jobs/{job_id}\", for example, \"projects/api-test-project/jobs/1234\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/jobs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.jobs.get":

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

// Get: Retrieves the specified job, whose status is OPEN or recently
// EXPIRED within the last 90 days.
func (r *ProjectsJobsService) Get(name string) *ProjectsJobsGetCall {
	c := &ProjectsJobsGetCall{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 *ProjectsJobsGetCall) Fields(s ...googleapi.Field) *ProjectsJobsGetCall {
	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 *ProjectsJobsGetCall) IfNoneMatch(entityTag string) *ProjectsJobsGetCall {
	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 *ProjectsJobsGetCall) Context(ctx context.Context) *ProjectsJobsGetCall {
	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 *ProjectsJobsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+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 "jobs.projects.jobs.get" call.
// Exactly one of *Job or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either
// *Job.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 *ProjectsJobsGetCall) Do(opts ...googleapi.CallOption) (*Job, 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 := &Job{
		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 the specified job, whose status is OPEN or recently EXPIRED within the last 90 days.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs/{jobsId}",
	//   "httpMethod": "GET",
	//   "id": "jobs.projects.jobs.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the job to retrieve. The format is \"projects/{project_id}/jobs/{job_id}\", for example, \"projects/api-test-project/jobs/1234\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/jobs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}",
	//   "response": {
	//     "$ref": "Job"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.jobs.list":

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

// List: Lists jobs by filter.
func (r *ProjectsJobsService) List(parent string) *ProjectsJobsListCall {
	c := &ProjectsJobsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Required. The filter
// string specifies the jobs to be enumerated. Supported operator: =,
// AND The fields eligible for filtering are: * `companyName` (Required)
// * `requisitionId` (Optional) Sample Query: * companyName =
// "projects/api-test-project/companies/123" * companyName =
// "projects/api-test-project/companies/123" AND requisitionId = "req-1"
func (c *ProjectsJobsListCall) Filter(filter string) *ProjectsJobsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// JobView sets the optional parameter "jobView": The desired job
// attributes returned for jobs in the search response. Defaults to
// JobView.JOB_VIEW_FULL if no value is specified.
//
// Possible values:
//   "JOB_VIEW_UNSPECIFIED" - Default value.
//   "JOB_VIEW_ID_ONLY" - A ID only view of job, with following
// attributes: Job.name, Job.requisition_id, Job.language_code.
//   "JOB_VIEW_MINIMAL" - A minimal view of the job, with the following
// attributes: Job.name, Job.requisition_id, Job.title,
// Job.company_name, Job.DerivedInfo.locations, Job.language_code.
//   "JOB_VIEW_SMALL" - A small view of the job, with the following
// attributes in the search results: Job.name, Job.requisition_id,
// Job.title, Job.company_name, Job.DerivedInfo.locations,
// Job.visibility, Job.language_code, Job.description.
//   "JOB_VIEW_FULL" - All available attributes are included in the
// search results.
func (c *ProjectsJobsListCall) JobView(jobView string) *ProjectsJobsListCall {
	c.urlParams_.Set("jobView", jobView)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of jobs to be returned per page of results. If job_view is set to
// JobView.JOB_VIEW_ID_ONLY, the maximum allowed page size is 1000.
// Otherwise, the maximum allowed page size is 100. Default is 100 if
// empty or a number < 1 is specified.
func (c *ProjectsJobsListCall) PageSize(pageSize int64) *ProjectsJobsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The starting point
// of a query result.
func (c *ProjectsJobsListCall) PageToken(pageToken string) *ProjectsJobsListCall {
	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 *ProjectsJobsListCall) Fields(s ...googleapi.Field) *ProjectsJobsListCall {
	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 *ProjectsJobsListCall) IfNoneMatch(entityTag string) *ProjectsJobsListCall {
	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 *ProjectsJobsListCall) Context(ctx context.Context) *ProjectsJobsListCall {
	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 *ProjectsJobsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+parent}/jobs")
	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 "jobs.projects.jobs.list" call.
// Exactly one of *ListJobsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListJobsResponse.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 *ProjectsJobsListCall) Do(opts ...googleapi.CallOption) (*ListJobsResponse, 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 := &ListJobsResponse{
		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 jobs by filter.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs",
	//   "httpMethod": "GET",
	//   "id": "jobs.projects.jobs.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Required. The filter string specifies the jobs to be enumerated. Supported operator: =, AND The fields eligible for filtering are: * `companyName` (Required) * `requisitionId` (Optional) Sample Query: * companyName = \"projects/api-test-project/companies/123\" * companyName = \"projects/api-test-project/companies/123\" AND requisitionId = \"req-1\"",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "jobView": {
	//       "description": "Optional. The desired job attributes returned for jobs in the search response. Defaults to JobView.JOB_VIEW_FULL if no value is specified.",
	//       "enum": [
	//         "JOB_VIEW_UNSPECIFIED",
	//         "JOB_VIEW_ID_ONLY",
	//         "JOB_VIEW_MINIMAL",
	//         "JOB_VIEW_SMALL",
	//         "JOB_VIEW_FULL"
	//       ],
	//       "enumDescriptions": [
	//         "Default value.",
	//         "A ID only view of job, with following attributes: Job.name, Job.requisition_id, Job.language_code.",
	//         "A minimal view of the job, with the following attributes: Job.name, Job.requisition_id, Job.title, Job.company_name, Job.DerivedInfo.locations, Job.language_code.",
	//         "A small view of the job, with the following attributes in the search results: Job.name, Job.requisition_id, Job.title, Job.company_name, Job.DerivedInfo.locations, Job.visibility, Job.language_code, Job.description.",
	//         "All available attributes are included in the search results."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The maximum number of jobs to be returned per page of results. If job_view is set to JobView.JOB_VIEW_ID_ONLY, the maximum allowed page size is 1000. Otherwise, the maximum allowed page size is 100. Default is 100 if empty or a number \u003c 1 is specified.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The starting point of a query result.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The resource name of the project under which the job is created. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/jobs",
	//   "response": {
	//     "$ref": "ListJobsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// 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 *ProjectsJobsListCall) Pages(ctx context.Context, f func(*ListJobsResponse) 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 "jobs.projects.jobs.patch":

type ProjectsJobsPatchCall struct {
	s                *Service
	name             string
	updatejobrequest *UpdateJobRequest
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Patch: Updates specified job. Typically, updated contents become
// visible in search results within 10 seconds, but it may take up to 5
// minutes.
func (r *ProjectsJobsService) Patch(name string, updatejobrequest *UpdateJobRequest) *ProjectsJobsPatchCall {
	c := &ProjectsJobsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.updatejobrequest = updatejobrequest
	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 *ProjectsJobsPatchCall) Fields(s ...googleapi.Field) *ProjectsJobsPatchCall {
	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 *ProjectsJobsPatchCall) Context(ctx context.Context) *ProjectsJobsPatchCall {
	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 *ProjectsJobsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.updatejobrequest)
	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, "v3p1beta1/{+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 "jobs.projects.jobs.patch" call.
// Exactly one of *Job or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either
// *Job.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 *ProjectsJobsPatchCall) Do(opts ...googleapi.CallOption) (*Job, 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 := &Job{
		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 specified job. Typically, updated contents become visible in search results within 10 seconds, but it may take up to 5 minutes.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs/{jobsId}",
	//   "httpMethod": "PATCH",
	//   "id": "jobs.projects.jobs.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required during job update. The resource name for the job. This is generated by the service when a job is created. The format is \"projects/{project_id}/jobs/{job_id}\", for example, \"projects/api-test-project/jobs/1234\". Use of this field in job queries and API calls is preferred over the use of requisition_id since this value is unique.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/jobs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}",
	//   "request": {
	//     "$ref": "UpdateJobRequest"
	//   },
	//   "response": {
	//     "$ref": "Job"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// method id "jobs.projects.jobs.search":

type ProjectsJobsSearchCall struct {
	s                 *Service
	parent            string
	searchjobsrequest *SearchJobsRequest
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Search: Searches for jobs using the provided SearchJobsRequest. This
// call constrains the visibility of jobs present in the database, and
// only returns jobs that the caller has permission to search against.
func (r *ProjectsJobsService) Search(parent string, searchjobsrequest *SearchJobsRequest) *ProjectsJobsSearchCall {
	c := &ProjectsJobsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.searchjobsrequest = searchjobsrequest
	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 *ProjectsJobsSearchCall) Fields(s ...googleapi.Field) *ProjectsJobsSearchCall {
	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 *ProjectsJobsSearchCall) Context(ctx context.Context) *ProjectsJobsSearchCall {
	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 *ProjectsJobsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.searchjobsrequest)
	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, "v3p1beta1/{+parent}/jobs:search")
	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 "jobs.projects.jobs.search" call.
// Exactly one of *SearchJobsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SearchJobsResponse.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 *ProjectsJobsSearchCall) Do(opts ...googleapi.CallOption) (*SearchJobsResponse, 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 := &SearchJobsResponse{
		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": "Searches for jobs using the provided SearchJobsRequest. This call constrains the visibility of jobs present in the database, and only returns jobs that the caller has permission to search against.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs:search",
	//   "httpMethod": "POST",
	//   "id": "jobs.projects.jobs.search",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The resource name of the project to search within. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/jobs:search",
	//   "request": {
	//     "$ref": "SearchJobsRequest"
	//   },
	//   "response": {
	//     "$ref": "SearchJobsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// 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 *ProjectsJobsSearchCall) Pages(ctx context.Context, f func(*SearchJobsResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.searchjobsrequest.PageToken = pt }(c.searchjobsrequest.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.searchjobsrequest.PageToken = x.NextPageToken
	}
}

// method id "jobs.projects.jobs.searchForAlert":

type ProjectsJobsSearchForAlertCall struct {
	s                 *Service
	parent            string
	searchjobsrequest *SearchJobsRequest
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// SearchForAlert: Searches for jobs using the provided
// SearchJobsRequest. This API call is intended for the use case of
// targeting passive job seekers (for example, job seekers who have
// signed up to receive email alerts about potential job opportunities),
// and has different algorithmic adjustments that are targeted to
// passive job seekers. This call constrains the visibility of jobs
// present in the database, and only returns jobs the caller has
// permission to search against.
func (r *ProjectsJobsService) SearchForAlert(parent string, searchjobsrequest *SearchJobsRequest) *ProjectsJobsSearchForAlertCall {
	c := &ProjectsJobsSearchForAlertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.searchjobsrequest = searchjobsrequest
	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 *ProjectsJobsSearchForAlertCall) Fields(s ...googleapi.Field) *ProjectsJobsSearchForAlertCall {
	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 *ProjectsJobsSearchForAlertCall) Context(ctx context.Context) *ProjectsJobsSearchForAlertCall {
	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 *ProjectsJobsSearchForAlertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsJobsSearchForAlertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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.searchjobsrequest)
	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, "v3p1beta1/{+parent}/jobs:searchForAlert")
	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 "jobs.projects.jobs.searchForAlert" call.
// Exactly one of *SearchJobsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SearchJobsResponse.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 *ProjectsJobsSearchForAlertCall) Do(opts ...googleapi.CallOption) (*SearchJobsResponse, 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 := &SearchJobsResponse{
		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": "Searches for jobs using the provided SearchJobsRequest. This API call is intended for the use case of targeting passive job seekers (for example, job seekers who have signed up to receive email alerts about potential job opportunities), and has different algorithmic adjustments that are targeted to passive job seekers. This call constrains the visibility of jobs present in the database, and only returns jobs the caller has permission to search against.",
	//   "flatPath": "v3p1beta1/projects/{projectsId}/jobs:searchForAlert",
	//   "httpMethod": "POST",
	//   "id": "jobs.projects.jobs.searchForAlert",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The resource name of the project to search within. The format is \"projects/{project_id}\", for example, \"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+parent}/jobs:searchForAlert",
	//   "request": {
	//     "$ref": "SearchJobsRequest"
	//   },
	//   "response": {
	//     "$ref": "SearchJobsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}

// 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 *ProjectsJobsSearchForAlertCall) Pages(ctx context.Context, f func(*SearchJobsResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.searchjobsrequest.PageToken = pt }(c.searchjobsrequest.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.searchjobsrequest.PageToken = x.NextPageToken
	}
}

// method id "jobs.projects.operations.get":

type ProjectsOperationsGetCall 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 *ProjectsOperationsService) Get(name string) *ProjectsOperationsGetCall {
	c := &ProjectsOperationsGetCall{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 *ProjectsOperationsGetCall) Fields(s ...googleapi.Field) *ProjectsOperationsGetCall {
	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 *ProjectsOperationsGetCall) IfNoneMatch(entityTag string) *ProjectsOperationsGetCall {
	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 *ProjectsOperationsGetCall) Context(ctx context.Context) *ProjectsOperationsGetCall {
	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 *ProjectsOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200918")
	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, "v3p1beta1/{+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 "jobs.projects.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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 *ProjectsOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, 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 := &Operation{
		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": "v3p1beta1/projects/{projectsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "jobs.projects.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v3p1beta1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/jobs"
	//   ]
	// }

}
