// 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/"

// 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))
	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, custom field
	// values are searchable.
	// If false, values are not searchable.
	//
	// 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"],
	// [buck
	// et(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 `<low>-<high>`,
	// 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
// <a
// href="http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf">WGS84
// st
// andard</a>. 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_infor
	// mation.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_infor
	// mation.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 <em>Foo,
	// Inc.</em>, 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:<br>
	// "distance_from('Hawaii')": Order by distance from
	// Hawaii.<br>
	// "distance_from(19.89, 155.5)": Order by distance from a
	// coordinate.<br>
	// "distance_from('Hawaii'), distance_from('Puerto Rico')": Order
	// by
	// multiple locations. See details below.<br>
	// "distance_from('Hawaii'), distance_from(19.89, 155.5)": Order
	// by
	// multiple locations. See details below.<br>
	// 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: Optional. Controls if the search job
	// request requires the return of a precise
	// count of the first 300 results. Setting this to `true`
	// ensures
	// consistency in the number of results per page. Best practice is to
	// set this
	// value to true if a client allows users to jump directly to
	// a
	// non-sequential search results page.
	//
	// Enabling this flag may adversely impact performance.
	//
	// Defaults to false.
	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 enable_precise_result_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, which is available only if the
	// client set
	// enable_precise_result_size to `true`, or if the response
	// is the last page of results. Otherwise, the value is `-1`.
	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"
//   "TENANT"
//   "PUBLIC"
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"
//   "JOB_TITLE"
//   "COMPANY_NAME"
//   "COMBINED"
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/20200422")
	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.\nIntended 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.\n\nThe format is \"projects/{project_id}/companies/{company_id}\", for example,\n\"projects/api-test-project/companies/foo\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCode": {
	//       "description": "Deprecated. Use language_codes instead.\n\nOptional.\n\nThe language of the query. This is\nthe BCP-47 language code, such as \"en-US\" or \"sr-Latn\".\nFor more information, see\n[Tags for Identifying Languages](https://tools.ietf.org/html/bcp47).\n\nFor CompletionType.JOB_TITLE type, only open jobs with the same\nlanguage_code are returned.\n\nFor CompletionType.COMPANY_NAME type,\nonly companies having open jobs with the same language_code are\nreturned.\n\nFor CompletionType.COMBINED type, only open jobs with the same\nlanguage_code or companies having open jobs with the same\nlanguage_code are returned.\n\nThe maximum number of allowed characters is 255.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCodes": {
	//       "description": "Optional. The list of languages of the query. This is\nthe BCP-47 language code, such as \"en-US\" or \"sr-Latn\".\nFor more information, see\n[Tags for Identifying Languages](https://tools.ietf.org/html/bcp47).\n\nFor CompletionType.JOB_TITLE type, only open jobs with the same\nlanguage_codes are returned.\n\nFor CompletionType.COMPANY_NAME type,\nonly companies having open jobs with the same language_codes are\nreturned.\n\nFor CompletionType.COMBINED type, only open jobs with the same\nlanguage_codes or companies having open jobs with the same\nlanguage_codes are returned.\n\nThe 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.\n\nThe format is \"projects/{project_id}\", for example,\n\"projects/api-test-project\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Required. Completion result count.\n\nThe maximum allowed page size is 10.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "query": {
	//       "description": "Required. The query used to generate suggestions.\n\nThe 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"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Optional. The completion topic. The default is CompletionType.COMBINED.",
	//       "enum": [
	//         "COMPLETION_TYPE_UNSPECIFIED",
	//         "JOB_TITLE",
	//         "COMPANY_NAME",
	//         "COMBINED"
	//       ],
	//       "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/overvi
// ew).
// [Learn
// more](https://cloud.google.com/talent-solution/docs/manage
// ment-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/20200422")
	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\nthat uses Cloud Talent Solution. You may inspect the created events in\n[self service\ntools](https://console.cloud.google.com/talent-solution/overview).\n[Learn\nmore](https://cloud.google.com/talent-solution/docs/management-tools)\nabout 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/20200422")
	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.\n\nThe format is \"projects/{project_id}\", for example,\n\"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/20200422")
	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.\nPrerequisite: 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.\n\nThe format is \"projects/{project_id}/companies/{company_id}\", for example,\n\"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/20200422")
	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.\n\nThe format is \"projects/{project_id}/companies/{company_id}\", for example,\n\"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/20200422")
	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.\nDefault 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.\n\nThe format is \"projects/{project_id}\", for example,\n\"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.\n\nDefaults to false.\n\nIf true, at most page_size of companies are fetched, among which\nonly 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/20200422")
	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\ncompany name, delete the company and all jobs associated with it, and only\nthen 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.\n\nThe resource name for a company. This is generated by the service when a\ncompany is created.\n\nThe format is \"projects/{project_id}/companies/{company_id}\", for example,\n\"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/20200422")
	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.\n\nThe format is \"projects/{project_id}\", for example,\n\"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/20200422")
	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.\n\nTypically, the job becomes searchable within 10 seconds, but it may take\nup 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.\n\nThe format is \"projects/{project_id}\", for example,\n\"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/20200422")
	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.\n\nTypically, the job becomes unsearchable within 10 seconds, but it may take\nup 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.\n\nThe format is \"projects/{project_id}/jobs/{job_id}\",\nfor 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/20200422")
	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\nwithin 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.\n\nThe format is \"projects/{project_id}/jobs/{job_id}\",\nfor 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"
//   "JOB_VIEW_ID_ONLY"
//   "JOB_VIEW_MINIMAL"
//   "JOB_VIEW_SMALL"
//   "JOB_VIEW_FULL"
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/20200422")
	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.\n\nSupported operator: =, AND\n\nThe fields eligible for filtering are:\n\n* `companyName` (Required)\n* `requisitionId` (Optional)\n\nSample Query:\n\n* companyName = \"projects/api-test-project/companies/123\"\n* companyName = \"projects/api-test-project/companies/123\" AND requisitionId\n= \"req-1\"",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "jobView": {
	//       "description": "Optional. The desired job attributes returned for jobs in the\nsearch response. Defaults to JobView.JOB_VIEW_FULL if no value is\nspecified.",
	//       "enum": [
	//         "JOB_VIEW_UNSPECIFIED",
	//         "JOB_VIEW_ID_ONLY",
	//         "JOB_VIEW_MINIMAL",
	//         "JOB_VIEW_SMALL",
	//         "JOB_VIEW_FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The maximum number of jobs to be returned per page of results.\n\nIf job_view is set to JobView.JOB_VIEW_ID_ONLY, the maximum allowed\npage size is 1000. Otherwise, the maximum allowed page size is 100.\n\nDefault 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.\n\nThe format is \"projects/{project_id}\", for example,\n\"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/20200422")
	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.\n\nTypically, updated contents become visible in search results within 10\nseconds, 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.\n\nThe resource name for the job. This is generated by the service when a\njob is created.\n\nThe format is \"projects/{project_id}/jobs/{job_id}\",\nfor example, \"projects/api-test-project/jobs/1234\".\n\nUse of this field in job queries and API calls is preferred over the use of\nrequisition_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/20200422")
	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.\n\nThis call constrains the visibility of jobs\npresent in the database, and only returns jobs that the caller has\npermission 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.\n\nThe format is \"projects/{project_id}\", for example,\n\"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/20200422")
	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.\n\nThis API call is intended for the use case of targeting passive job\nseekers (for example, job seekers who have signed up to receive email\nalerts about potential job opportunities), and has different algorithmic\nadjustments that are targeted to passive job seekers.\n\nThis call constrains the visibility of jobs\npresent in the database, and only returns jobs the caller has\npermission 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.\n\nThe format is \"projects/{project_id}\", for example,\n\"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/20200422")
	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\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "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"
	//   ]
	// }

}
