// 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 people provides access to the People API.
//
// For product documentation, see: https://developers.google.com/people/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/people/v1"
//   ...
//   ctx := context.Background()
//   peopleService, err := people.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:
//
//   peopleService, err := people.NewService(ctx, option.WithScopes(people.UserinfoProfileScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   peopleService, err := people.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, ...)
//   peopleService, err := people.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package people // import "google.golang.org/api/people/v1"

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

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

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

const apiId = "people:v1"
const apiName = "people"
const apiVersion = "v1"
const basePath = "https://people.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, edit, download, and permanently delete your contacts
	ContactsScope = "https://www.googleapis.com/auth/contacts"

	// See and download your contacts
	ContactsReadonlyScope = "https://www.googleapis.com/auth/contacts.readonly"

	// See and download your organization's GSuite directory
	DirectoryReadonlyScope = "https://www.googleapis.com/auth/directory.readonly"

	// View your street addresses
	UserAddressesReadScope = "https://www.googleapis.com/auth/user.addresses.read"

	// View your complete date of birth
	UserBirthdayReadScope = "https://www.googleapis.com/auth/user.birthday.read"

	// View your email addresses
	UserEmailsReadScope = "https://www.googleapis.com/auth/user.emails.read"

	// See your gender
	UserGenderReadScope = "https://www.googleapis.com/auth/user.gender.read"

	// See your education, work history and org info
	UserOrganizationReadScope = "https://www.googleapis.com/auth/user.organization.read"

	// View your phone numbers
	UserPhonenumbersReadScope = "https://www.googleapis.com/auth/user.phonenumbers.read"

	// View your email address
	UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email"

	// See your personal info, including any personal info you've made
	// publicly available
	UserinfoProfileScope = "https://www.googleapis.com/auth/userinfo.profile"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/contacts",
		"https://www.googleapis.com/auth/contacts.readonly",
		"https://www.googleapis.com/auth/directory.readonly",
		"https://www.googleapis.com/auth/user.addresses.read",
		"https://www.googleapis.com/auth/user.birthday.read",
		"https://www.googleapis.com/auth/user.emails.read",
		"https://www.googleapis.com/auth/user.gender.read",
		"https://www.googleapis.com/auth/user.organization.read",
		"https://www.googleapis.com/auth/user.phonenumbers.read",
		"https://www.googleapis.com/auth/userinfo.email",
		"https://www.googleapis.com/auth/userinfo.profile",
	)
	// 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.ContactGroups = NewContactGroupsService(s)
	s.OtherContacts = NewOtherContactsService(s)
	s.People = NewPeopleService(s)
	return s, nil
}

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

	ContactGroups *ContactGroupsService

	OtherContacts *OtherContactsService

	People *PeopleService
}

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

func NewContactGroupsService(s *Service) *ContactGroupsService {
	rs := &ContactGroupsService{s: s}
	rs.Members = NewContactGroupsMembersService(s)
	return rs
}

type ContactGroupsService struct {
	s *Service

	Members *ContactGroupsMembersService
}

func NewContactGroupsMembersService(s *Service) *ContactGroupsMembersService {
	rs := &ContactGroupsMembersService{s: s}
	return rs
}

type ContactGroupsMembersService struct {
	s *Service
}

func NewOtherContactsService(s *Service) *OtherContactsService {
	rs := &OtherContactsService{s: s}
	return rs
}

type OtherContactsService struct {
	s *Service
}

func NewPeopleService(s *Service) *PeopleService {
	rs := &PeopleService{s: s}
	rs.Connections = NewPeopleConnectionsService(s)
	return rs
}

type PeopleService struct {
	s *Service

	Connections *PeopleConnectionsService
}

func NewPeopleConnectionsService(s *Service) *PeopleConnectionsService {
	rs := &PeopleConnectionsService{s: s}
	return rs
}

type PeopleConnectionsService struct {
	s *Service
}

// Address: A person's physical address. May be a P.O. box or street
// address. All fields
// are optional.
type Address struct {
	// City: The city of the address.
	City string `json:"city,omitempty"`

	// Country: The country of the address.
	Country string `json:"country,omitempty"`

	// CountryCode: The [ISO 3166-1
	// alpha-2](http://www.iso.org/iso/country_codes.htm) country
	// code of the address.
	CountryCode string `json:"countryCode,omitempty"`

	// ExtendedAddress: The extended address of the address; for example,
	// the apartment number.
	ExtendedAddress string `json:"extendedAddress,omitempty"`

	// FormattedType: Output only. The type of the address translated and
	// formatted in the viewer's
	// account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// FormattedValue: The unstructured value of the address. If this is not
	// set by the user it
	// will be automatically constructed from structured values.
	FormattedValue string `json:"formattedValue,omitempty"`

	// Metadata: Metadata about the address.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// PoBox: The P.O. box of the address.
	PoBox string `json:"poBox,omitempty"`

	// PostalCode: The postal code of the address.
	PostalCode string `json:"postalCode,omitempty"`

	// Region: The region of the address; for example, the state or
	// province.
	Region string `json:"region,omitempty"`

	// StreetAddress: The street address.
	StreetAddress string `json:"streetAddress,omitempty"`

	// Type: The type of the address. The type can be custom or one of these
	// predefined
	// values:
	//
	// * `home`
	// * `work`
	// * `other`
	Type string `json:"type,omitempty"`

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

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

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

// AgeRangeType: A person's age range.
type AgeRangeType struct {
	// AgeRange: The age range.
	//
	// Possible values:
	//   "AGE_RANGE_UNSPECIFIED" - Unspecified.
	//   "LESS_THAN_EIGHTEEN" - Younger than eighteen.
	//   "EIGHTEEN_TO_TWENTY" - Between eighteen and twenty.
	//   "TWENTY_ONE_OR_OLDER" - Twenty-one and older.
	AgeRange string `json:"ageRange,omitempty"`

	// Metadata: Metadata about the age range.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

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

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

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

// BatchGetContactGroupsResponse: The response to a batch get contact
// groups request.
type BatchGetContactGroupsResponse struct {
	// Responses: The list of responses for each requested contact group
	// resource.
	Responses []*ContactGroupResponse `json:"responses,omitempty"`

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

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

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

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

// Biography: A person's short biography.
type Biography struct {
	// ContentType: The content type of the biography.
	//
	// Possible values:
	//   "CONTENT_TYPE_UNSPECIFIED" - Unspecified.
	//   "TEXT_PLAIN" - Plain text.
	//   "TEXT_HTML" - HTML text.
	ContentType string `json:"contentType,omitempty"`

	// Metadata: Metadata about the biography.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The short biography.
	Value string `json:"value,omitempty"`

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

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

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

// Birthday: A person's birthday. At least one of the `date` and `text`
// fields are
// specified. The `date` and `text` fields typically represent the
// same
// date, but are not guaranteed to.
type Birthday struct {
	// Date: The date of the birthday.
	Date *Date `json:"date,omitempty"`

	// Metadata: Metadata about the birthday.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Text: A free-form string representing the user's birthday.
	Text string `json:"text,omitempty"`

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

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

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

// BraggingRights: **DEPRECATED**: No data will be returned
// A person's bragging rights.
type BraggingRights struct {
	// Metadata: Metadata about the bragging rights.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The bragging rights; for example, `climbed mount everest`.
	Value string `json:"value,omitempty"`

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

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

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

// ContactGroup: A contact group.
type ContactGroup struct {
	// Etag: The [HTTP entity tag](https://en.wikipedia.org/wiki/HTTP_ETag)
	// of the
	// resource. Used for web cache validation.
	Etag string `json:"etag,omitempty"`

	// FormattedName: Output only. The name translated and formatted in the
	// viewer's account locale
	// or the `Accept-Language` HTTP header locale for system groups
	// names.
	// Group names set by the owner are the same as name.
	FormattedName string `json:"formattedName,omitempty"`

	// GroupType: Output only. The contact group type.
	//
	// Possible values:
	//   "GROUP_TYPE_UNSPECIFIED" - Unspecified.
	//   "USER_CONTACT_GROUP" - User defined contact group.
	//   "SYSTEM_CONTACT_GROUP" - System defined contact group.
	GroupType string `json:"groupType,omitempty"`

	// MemberCount: Output only. The total number of contacts in the group
	// irrespective of max members in
	// specified in the request.
	MemberCount int64 `json:"memberCount,omitempty"`

	// MemberResourceNames: Output only. The list of contact person resource
	// names that are members of the contact
	// group. The field is not populated for LIST requests and can only be
	// updated
	// through
	// the
	// [ModifyContactGroupMembers](/people/api/rest/v1/contactgroups/memb
	// ers/modify).
	MemberResourceNames []string `json:"memberResourceNames,omitempty"`

	// Metadata: Output only. Metadata about the contact group.
	Metadata *ContactGroupMetadata `json:"metadata,omitempty"`

	// Name: The contact group name set by the group owner or a system
	// provided name
	// for system groups.
	Name string `json:"name,omitempty"`

	// ResourceName: The resource name for the contact group, assigned by
	// the server. An ASCII
	// string, in the form of `contactGroups/{contact_group_id}`.
	ResourceName string `json:"resourceName,omitempty"`

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

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

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

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

// ContactGroupMembership: A Google contact group membership.
type ContactGroupMembership struct {
	// ContactGroupId: Output only. The contact group ID for the contact
	// group membership.
	ContactGroupId string `json:"contactGroupId,omitempty"`

	// ContactGroupResourceName: The resource name for the contact group,
	// assigned by the server. An ASCII
	// string, in the form of `contactGroups/{contact_group_id}`.
	// Only contact_group_resource_name can be used for modifying
	// memberships.
	// Any contact group membership can be removed, but only user group
	// or
	// "myContacts" or "starred" system groups memberships can be added.
	// A
	// contact must always have at least one contact group membership.
	ContactGroupResourceName string `json:"contactGroupResourceName,omitempty"`

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

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

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

// ContactGroupMetadata: The metadata about a contact group.
type ContactGroupMetadata struct {
	// Deleted: Output only. True if the contact group resource has been
	// deleted. Populated only
	// for
	// [`ListContactGroups`](/people/api/rest/v1/contactgroups/list)
	// requests
	// that include a sync token.
	Deleted bool `json:"deleted,omitempty"`

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

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

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

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

// ContactGroupResponse: The response for a specific contact group.
type ContactGroupResponse struct {
	// ContactGroup: The contact group.
	ContactGroup *ContactGroup `json:"contactGroup,omitempty"`

	// RequestedResourceName: The original requested resource name.
	RequestedResourceName string `json:"requestedResourceName,omitempty"`

	// Status: The status of the response.
	Status *Status `json:"status,omitempty"`

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

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

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

// CopyOtherContactToMyContactsGroupRequest: A request to copy an "Other
// contact" to my contacts group.
type CopyOtherContactToMyContactsGroupRequest struct {
	// CopyMask: Required. A field mask to restrict which fields are copied
	// into the new contact.
	// Valid values are:
	//
	// * emailAddresses
	// * names
	// * phoneNumbers
	CopyMask string `json:"copyMask,omitempty"`

	// ReadMask: Optional. A field mask to restrict which fields on the
	// person are returned. Multiple
	// fields can be specified by separating them with commas. Defaults to
	// the
	// copy mask with metadata and membership fields if not set. Valid
	// values are:
	//
	// * addresses
	// * ageRanges
	// * biographies
	// * birthdays
	// * coverPhotos
	// * emailAddresses
	// * events
	// * genders
	// * imClients
	// * interests
	// * locales
	// * memberships
	// * metadata
	// * names
	// * nicknames
	// * occupations
	// * organizations
	// * phoneNumbers
	// * photos
	// * relations
	// * residences
	// * sipAddresses
	// * skills
	// * urls
	// * userDefined
	ReadMask string `json:"readMask,omitempty"`

	// Sources: Optional. A mask of what source types to return. Defaults
	// to
	// ReadSourceType.CONTACT and
	// ReadSourceType.PROFILE if not
	// set.
	//
	// Possible values:
	//   "READ_SOURCE_TYPE_UNSPECIFIED" - Unspecified.
	//   "READ_SOURCE_TYPE_PROFILE" -
	// Returns
	// SourceType.ACCOUNT,
	// SourceType.DOMAIN_PROFILE,
	// and
	// SourceType.
	// PROFILE.
	//   "READ_SOURCE_TYPE_CONTACT" - Returns
	// SourceType.CONTACT.
	//   "READ_SOURCE_TYPE_DOMAIN_CONTACT" -
	// Returns
	// SourceType.DOMAIN_CONTACT.
	Sources []string `json:"sources,omitempty"`

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

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

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

// CoverPhoto: A person's cover photo. A large image shown on the
// person's
// profile page that represents who they are or what they care about.
type CoverPhoto struct {
	// Default: True if the cover photo is the default cover photo;
	// false if the cover photo is a user-provided cover photo.
	Default bool `json:"default,omitempty"`

	// Metadata: Metadata about the cover photo.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Url: The URL of the cover photo.
	Url string `json:"url,omitempty"`

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

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

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

// CreateContactGroupRequest: A request to create a new contact group.
type CreateContactGroupRequest struct {
	// ContactGroup: Required. The contact group to create.
	ContactGroup *ContactGroup `json:"contactGroup,omitempty"`

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

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

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

// Date: Represents a whole or partial calendar date, e.g. a birthday.
// The time of day
// and time zone are either specified elsewhere or are not significant.
// The date
// is relative to the Proleptic Gregorian Calendar. This can
// represent:
//
// * A full date, with non-zero year, month and day values
// * A month and day value, with a zero year, e.g. an anniversary
// * A year on its own, with zero month and day values
// * A year and month value, with a zero day, e.g. a credit card
// expiration date
//
// Related types are google.type.TimeOfDay and
// `google.protobuf.Timestamp`.
type Date struct {
	// Day: Day of month. Must be from 1 to 31 and valid for the year and
	// month, or 0
	// if specifying a year by itself or a year and month where the day is
	// not
	// significant.
	Day int64 `json:"day,omitempty"`

	// Month: Month of year. Must be from 1 to 12, or 0 if specifying a year
	// without a
	// month and day.
	Month int64 `json:"month,omitempty"`

	// Year: Year of date. Must be from 1 to 9999, or 0 if specifying a date
	// without
	// a year.
	Year int64 `json:"year,omitempty"`

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

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

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

// DeleteContactPhotoResponse: The response for deleteing a contact's
// photo.
type DeleteContactPhotoResponse struct {
	// Person: The updated person, if person_fields is set in
	// the
	// DeleteContactPhotoRequest; otherwise this will be unset.
	Person *Person `json:"person,omitempty"`

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

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

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

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

// DomainMembership: A G Suite Domain membership.
type DomainMembership struct {
	// InViewerDomain: True if the person is in the viewer's G Suite domain.
	InViewerDomain bool `json:"inViewerDomain,omitempty"`

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

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

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

// EmailAddress: A person's email address.
type EmailAddress struct {
	// DisplayName: The display name of the email.
	DisplayName string `json:"displayName,omitempty"`

	// FormattedType: Output only. The type of the email address translated
	// and formatted in the
	// viewer's account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// Metadata: Metadata about the email address.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Type: The type of the email address. The type can be custom or one of
	// these
	// predefined values:
	//
	// * `home`
	// * `work`
	// * `other`
	Type string `json:"type,omitempty"`

	// Value: The email address.
	Value string `json:"value,omitempty"`

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

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

func (s *EmailAddress) MarshalJSON() ([]byte, error) {
	type NoMethod EmailAddress
	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:"-"`
}

// Event: An event related to the person.
type Event struct {
	// Date: The date of the event.
	Date *Date `json:"date,omitempty"`

	// FormattedType: Output only. The type of the event translated and
	// formatted in the
	// viewer's account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// Metadata: Metadata about the event.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Type: The type of the event. The type can be custom or one of these
	// predefined
	// values:
	//
	// * `anniversary`
	// * `other`
	Type string `json:"type,omitempty"`

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

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

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

// FieldMetadata: Metadata about a field.
type FieldMetadata struct {
	// Primary: True if the field is the primary field; false if the field
	// is a secondary
	// field.
	Primary bool `json:"primary,omitempty"`

	// Source: The source of the field.
	Source *Source `json:"source,omitempty"`

	// Verified: Output only. True if the field is verified; false if the
	// field is unverified. A
	// verified field is typically a name, email address, phone number,
	// or
	// website that has been confirmed to be owned by the person.
	Verified bool `json:"verified,omitempty"`

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

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

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

// FileAs: The name that should be used to sort the person in a list.
type FileAs struct {
	// Metadata: Metadata about the file-as.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The file-as value
	Value string `json:"value,omitempty"`

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

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

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

// Gender: A person's gender.
type Gender struct {
	// AddressMeAs: The type of pronouns that should be used to address the
	// person. The value
	// can be custom or one of these predefined values:
	//
	// * `male`
	// * `female`
	// * `other`
	AddressMeAs string `json:"addressMeAs,omitempty"`

	// FormattedValue: Output only. The value of the gender translated and
	// formatted in the viewer's account
	// locale or the `Accept-Language` HTTP header locale. Unspecified or
	// custom
	// value are not localized.
	FormattedValue string `json:"formattedValue,omitempty"`

	// Metadata: Metadata about the gender.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The gender for the person. The gender can be custom or one of
	// these
	// predefined values:
	//
	// * `male`
	// * `female`
	// * `unspecified`
	Value string `json:"value,omitempty"`

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

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

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

// GetPeopleResponse: The response to a get request for a list of people
// by resource name.
type GetPeopleResponse struct {
	// Responses: The response for each requested resource name.
	Responses []*PersonResponse `json:"responses,omitempty"`

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

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

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

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

// ImClient: A person's instant messaging client.
type ImClient struct {
	// FormattedProtocol: Output only. The protocol of the IM client
	// formatted in the viewer's account
	// locale or the `Accept-Language` HTTP header locale.
	FormattedProtocol string `json:"formattedProtocol,omitempty"`

	// FormattedType: Output only. The type of the IM client translated and
	// formatted in the
	// viewer's account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// Metadata: Metadata about the IM client.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Protocol: The protocol of the IM client. The protocol can be custom
	// or one of these
	// predefined values:
	//
	// * `aim`
	// * `msn`
	// * `yahoo`
	// * `skype`
	// * `qq`
	// * `googleTalk`
	// * `icq`
	// * `jabber`
	// * `netMeeting`
	Protocol string `json:"protocol,omitempty"`

	// Type: The type of the IM client. The type can be custom or one of
	// these
	// predefined values:
	//
	// * `home`
	// * `work`
	// * `other`
	Type string `json:"type,omitempty"`

	// Username: The user name used in the IM client.
	Username string `json:"username,omitempty"`

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

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

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

// Interest: One of the person's interests.
type Interest struct {
	// Metadata: Metadata about the interest.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The interest; for example, `stargazing`.
	Value string `json:"value,omitempty"`

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

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

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

// ListConnectionsResponse: The response to a request for the
// authenticated user's connections.
type ListConnectionsResponse struct {
	// Connections: The list of people that the requestor is connected to.
	Connections []*Person `json:"connections,omitempty"`

	// NextPageToken: A token, which can be sent as `page_token` to retrieve
	// the next page.
	// If this field is omitted, there are no subsequent pages.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// NextSyncToken: A token, which can be sent as `sync_token` to retrieve
	// changes since the
	// last request. Request must set `request_sync_token` to return the
	// sync
	// token.
	NextSyncToken string `json:"nextSyncToken,omitempty"`

	// TotalItems: The total number of items in the list without pagination.
	TotalItems int64 `json:"totalItems,omitempty"`

	// TotalPeople: **DEPRECATED** (Please use totalItems)
	// The total number of people in the list without pagination.
	TotalPeople int64 `json:"totalPeople,omitempty"`

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

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

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

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

// ListContactGroupsResponse: The response to a list contact groups
// request.
type ListContactGroupsResponse struct {
	// ContactGroups: The list of contact groups. Members of the contact
	// groups are not
	// populated.
	ContactGroups []*ContactGroup `json:"contactGroups,omitempty"`

	// NextPageToken: The token that can be used to retrieve the next page
	// of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// NextSyncToken: The token that can be used to retrieve changes since
	// the last request.
	NextSyncToken string `json:"nextSyncToken,omitempty"`

	// TotalItems: The total number of items in the list without pagination.
	TotalItems int64 `json:"totalItems,omitempty"`

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

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

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

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

// ListDirectoryPeopleResponse: The response to a request for the
// authenticated user's domain directory.
type ListDirectoryPeopleResponse struct {
	// NextPageToken: A token, which can be sent as `page_token` to retrieve
	// the next page.
	// If this field is omitted, there are no subsequent pages.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// NextSyncToken: A token, which can be sent as `sync_token` to retrieve
	// changes since the
	// last request. Request must set `request_sync_token` to return the
	// sync
	// token.
	NextSyncToken string `json:"nextSyncToken,omitempty"`

	// People: The list of people in the domain directory.
	People []*Person `json:"people,omitempty"`

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

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

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

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

// ListOtherContactsResponse: The response to a request for the
// authenticated user's "Other contacts".
type ListOtherContactsResponse struct {
	// NextPageToken: A token, which can be sent as `page_token` to retrieve
	// the next page.
	// If this field is omitted, there are no subsequent pages.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// NextSyncToken: A token, which can be sent as `sync_token` to retrieve
	// changes since the
	// last request. Request must set `request_sync_token` to return the
	// sync
	// token.
	NextSyncToken string `json:"nextSyncToken,omitempty"`

	// OtherContacts: The list of "Other contacts" returned as Person
	// resources. "Other contacts"
	// support a limited subset of fields.
	// See
	// ListOtherContactsRequest.request_mask for more detailed information.
	OtherContacts []*Person `json:"otherContacts,omitempty"`

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

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

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

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

// Locale: A person's locale preference.
type Locale struct {
	// Metadata: Metadata about the locale.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The well-formed [IETF BCP
	// 47](https://tools.ietf.org/html/bcp47)
	// language tag representing the locale.
	Value string `json:"value,omitempty"`

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

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

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

// Membership: A person's membership in a group. Only contact group
// memberships can be
// modified.
type Membership struct {
	// ContactGroupMembership: The contact group membership.
	ContactGroupMembership *ContactGroupMembership `json:"contactGroupMembership,omitempty"`

	// DomainMembership: Output only. The domain membership.
	DomainMembership *DomainMembership `json:"domainMembership,omitempty"`

	// Metadata: Metadata about the membership.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

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

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

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

// ModifyContactGroupMembersRequest: A request to modify an existing
// contact group's members. Contacts can be
// removed from any group but they can only be added to a user group
// or
// "myContacts" or "starred" system groups.
type ModifyContactGroupMembersRequest struct {
	// ResourceNamesToAdd: Optional. The resource names of the contact
	// people to add in the form of
	// `people/{person_id}`.
	ResourceNamesToAdd []string `json:"resourceNamesToAdd,omitempty"`

	// ResourceNamesToRemove: Optional. The resource names of the contact
	// people to remove in the form of
	// `people/{person_id}`.
	ResourceNamesToRemove []string `json:"resourceNamesToRemove,omitempty"`

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

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

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

// ModifyContactGroupMembersResponse: The response to a modify contact
// group members request.
type ModifyContactGroupMembersResponse struct {
	// CanNotRemoveLastContactGroupResourceNames: The contact people
	// resource names that cannot be removed from their
	// last contact group.
	CanNotRemoveLastContactGroupResourceNames []string `json:"canNotRemoveLastContactGroupResourceNames,omitempty"`

	// NotFoundResourceNames: The contact people resource names that were
	// not found.
	NotFoundResourceNames []string `json:"notFoundResourceNames,omitempty"`

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

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

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

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

// Name: A person's name. If the name is a mononym, the family name is
// empty.
type Name struct {
	// DisplayName: Output only. The display name formatted according to the
	// locale specified by
	// the viewer's account or the `Accept-Language` HTTP header.
	DisplayName string `json:"displayName,omitempty"`

	// DisplayNameLastFirst: Output only. The display name with the last
	// name first formatted according to
	// the locale specified by the viewer's account or the
	// `Accept-Language` HTTP header.
	DisplayNameLastFirst string `json:"displayNameLastFirst,omitempty"`

	// FamilyName: The family name.
	FamilyName string `json:"familyName,omitempty"`

	// GivenName: The given name.
	GivenName string `json:"givenName,omitempty"`

	// HonorificPrefix: The honorific prefixes, such as `Mrs.` or `Dr.`
	HonorificPrefix string `json:"honorificPrefix,omitempty"`

	// HonorificSuffix: The honorific suffixes, such as `Jr.`
	HonorificSuffix string `json:"honorificSuffix,omitempty"`

	// Metadata: Metadata about the name.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// MiddleName: The middle name(s).
	MiddleName string `json:"middleName,omitempty"`

	// PhoneticFamilyName: The family name spelled as it sounds.
	PhoneticFamilyName string `json:"phoneticFamilyName,omitempty"`

	// PhoneticFullName: The full name spelled as it sounds.
	PhoneticFullName string `json:"phoneticFullName,omitempty"`

	// PhoneticGivenName: The given name spelled as it sounds.
	PhoneticGivenName string `json:"phoneticGivenName,omitempty"`

	// PhoneticHonorificPrefix: The honorific prefixes spelled as they
	// sound.
	PhoneticHonorificPrefix string `json:"phoneticHonorificPrefix,omitempty"`

	// PhoneticHonorificSuffix: The honorific suffixes spelled as they
	// sound.
	PhoneticHonorificSuffix string `json:"phoneticHonorificSuffix,omitempty"`

	// PhoneticMiddleName: The middle name(s) spelled as they sound.
	PhoneticMiddleName string `json:"phoneticMiddleName,omitempty"`

	// UnstructuredName: The free form name value.
	UnstructuredName string `json:"unstructuredName,omitempty"`

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

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

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

// Nickname: A person's nickname.
type Nickname struct {
	// Metadata: Metadata about the nickname.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Type: The type of the nickname.
	//
	// Possible values:
	//   "DEFAULT" - Generic nickname.
	//   "MAIDEN_NAME" - Maiden name or birth family name. Used when the
	// person's family name has
	// changed as a result of marriage.
	//   "INITIALS" - Initials.
	//   "GPLUS" - Google+ profile nickname.
	//   "OTHER_NAME" - A professional affiliation or other name; for
	// example, `Dr. Smith.`
	//   "ALTERNATE_NAME" - Alternate name person is known by.
	//   "SHORT_NAME" - A shorter version of the person's name.
	Type string `json:"type,omitempty"`

	// Value: The nickname.
	Value string `json:"value,omitempty"`

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

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

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

// Occupation: A person's occupation.
type Occupation struct {
	// Metadata: Metadata about the occupation.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The occupation; for example, `carpenter`.
	Value string `json:"value,omitempty"`

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

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

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

// Organization: A person's past or current organization. Overlapping
// date ranges are
// permitted.
type Organization struct {
	// Current: True if the organization is the person's current
	// organization;
	// false if the organization is a past organization.
	Current bool `json:"current,omitempty"`

	// Department: The person's department at the organization.
	Department string `json:"department,omitempty"`

	// Domain: The domain name associated with the organization; for
	// example,
	// `google.com`.
	Domain string `json:"domain,omitempty"`

	// EndDate: The end date when the person left the organization.
	EndDate *Date `json:"endDate,omitempty"`

	// FormattedType: Output only. The type of the organization translated
	// and formatted in the
	// viewer's account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// JobDescription: The person's job description at the organization.
	JobDescription string `json:"jobDescription,omitempty"`

	// Location: The location of the organization office the person works
	// at.
	Location string `json:"location,omitempty"`

	// Metadata: Metadata about the organization.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

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

	// PhoneticName: The phonetic name of the organization.
	PhoneticName string `json:"phoneticName,omitempty"`

	// StartDate: The start date when the person joined the organization.
	StartDate *Date `json:"startDate,omitempty"`

	// Symbol: The symbol associated with the organization; for example, a
	// stock ticker
	// symbol, abbreviation, or acronym.
	Symbol string `json:"symbol,omitempty"`

	// Title: The person's job title at the organization.
	Title string `json:"title,omitempty"`

	// Type: The type of the organization. The type can be custom or  one of
	// these
	// predefined values:
	//
	// * `work`
	// * `school`
	Type string `json:"type,omitempty"`

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

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

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

// Person: Information about a person merged from various data sources
// such as the
// authenticated user's contacts and profile data.
//
// Most fields can have multiple items. The items in a field have no
// guaranteed
// order, but each non-empty field is guaranteed to have exactly one
// field with
// `metadata.primary` set to true.
type Person struct {
	// Addresses: The person's street addresses.
	Addresses []*Address `json:"addresses,omitempty"`

	// AgeRange: Output only. **DEPRECATED** (Please use `person.ageRanges`
	// instead)
	//
	// The person's age range.
	//
	// Possible values:
	//   "AGE_RANGE_UNSPECIFIED" - Unspecified.
	//   "LESS_THAN_EIGHTEEN" - Younger than eighteen.
	//   "EIGHTEEN_TO_TWENTY" - Between eighteen and twenty.
	//   "TWENTY_ONE_OR_OLDER" - Twenty-one and older.
	AgeRange string `json:"ageRange,omitempty"`

	// AgeRanges: Output only. The person's age ranges.
	AgeRanges []*AgeRangeType `json:"ageRanges,omitempty"`

	// Biographies: The person's biographies.
	Biographies []*Biography `json:"biographies,omitempty"`

	// Birthdays: The person's birthdays.
	Birthdays []*Birthday `json:"birthdays,omitempty"`

	// BraggingRights: **DEPRECATED**: No data will be returned
	// The person's bragging rights.
	BraggingRights []*BraggingRights `json:"braggingRights,omitempty"`

	// CoverPhotos: Output only. The person's cover photos.
	CoverPhotos []*CoverPhoto `json:"coverPhotos,omitempty"`

	// EmailAddresses: The person's email addresses.
	EmailAddresses []*EmailAddress `json:"emailAddresses,omitempty"`

	// Etag: The [HTTP entity tag](https://en.wikipedia.org/wiki/HTTP_ETag)
	// of the
	// resource. Used for web cache validation.
	Etag string `json:"etag,omitempty"`

	// Events: The person's events.
	Events []*Event `json:"events,omitempty"`

	// FileAses: The person's file-ases.
	FileAses []*FileAs `json:"fileAses,omitempty"`

	// Genders: The person's genders.
	Genders []*Gender `json:"genders,omitempty"`

	// ImClients: The person's instant messaging clients.
	ImClients []*ImClient `json:"imClients,omitempty"`

	// Interests: The person's interests.
	Interests []*Interest `json:"interests,omitempty"`

	// Locales: The person's locale preferences.
	Locales []*Locale `json:"locales,omitempty"`

	// Memberships: The person's group memberships.
	Memberships []*Membership `json:"memberships,omitempty"`

	// Metadata: Output only. Metadata about the person.
	Metadata *PersonMetadata `json:"metadata,omitempty"`

	// Names: The person's names.
	Names []*Name `json:"names,omitempty"`

	// Nicknames: The person's nicknames.
	Nicknames []*Nickname `json:"nicknames,omitempty"`

	// Occupations: The person's occupations.
	Occupations []*Occupation `json:"occupations,omitempty"`

	// Organizations: The person's past or current organizations.
	Organizations []*Organization `json:"organizations,omitempty"`

	// PhoneNumbers: The person's phone numbers.
	PhoneNumbers []*PhoneNumber `json:"phoneNumbers,omitempty"`

	// Photos: Output only. The person's photos.
	Photos []*Photo `json:"photos,omitempty"`

	// Relations: The person's relations.
	Relations []*Relation `json:"relations,omitempty"`

	// RelationshipInterests: Output only. **DEPRECATED**: No data will be
	// returned
	// The person's relationship interests.
	RelationshipInterests []*RelationshipInterest `json:"relationshipInterests,omitempty"`

	// RelationshipStatuses: Output only. **DEPRECATED**: No data will be
	// returned
	// The person's relationship statuses.
	RelationshipStatuses []*RelationshipStatus `json:"relationshipStatuses,omitempty"`

	// Residences: The person's residences.
	Residences []*Residence `json:"residences,omitempty"`

	// ResourceName: The resource name for the person, assigned by the
	// server. An ASCII string
	// with a max length of 27 characters, in the form
	// of
	// `people/{person_id}`.
	ResourceName string `json:"resourceName,omitempty"`

	// SipAddresses: The person's SIP addresses.
	SipAddresses []*SipAddress `json:"sipAddresses,omitempty"`

	// Skills: The person's skills.
	Skills []*Skill `json:"skills,omitempty"`

	// Taglines: Output only. **DEPRECATED**: No data will be returned
	// The person's taglines.
	Taglines []*Tagline `json:"taglines,omitempty"`

	// Urls: The person's associated URLs.
	Urls []*Url `json:"urls,omitempty"`

	// UserDefined: The person's user defined data.
	UserDefined []*UserDefined `json:"userDefined,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 *Person) MarshalJSON() ([]byte, error) {
	type NoMethod Person
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PersonMetadata: The metadata about a person.
type PersonMetadata struct {
	// Deleted: Output only. True if the person resource has been deleted.
	// Populated only
	// for
	// [`connections.list`](/people/api/rest/v1/people.connections/list)
	// requests
	// that include a sync token.
	Deleted bool `json:"deleted,omitempty"`

	// LinkedPeopleResourceNames: Output only. Resource names of people
	// linked to this resource.
	LinkedPeopleResourceNames []string `json:"linkedPeopleResourceNames,omitempty"`

	// ObjectType: Output only. **DEPRECATED** (Please
	// use
	// `person.metadata.sources.profileMetadata.objectType` instead)
	//
	// The type of the person object.
	//
	// Possible values:
	//   "OBJECT_TYPE_UNSPECIFIED" - Unspecified.
	//   "PERSON" - Person.
	//   "PAGE" - [Google+ Page.](http://www.google.com/+/brands/)
	ObjectType string `json:"objectType,omitempty"`

	// PreviousResourceNames: Output only. Any former resource names this
	// person has had. Populated only
	// for
	// [`connections.list`](/people/api/rest/v1/people.connections/list)
	// requests
	// that include a sync token.
	//
	// The resource name may change when adding or removing fields that link
	// a
	// contact and profile such as a verified email, verified phone number,
	// or
	// profile URL.
	PreviousResourceNames []string `json:"previousResourceNames,omitempty"`

	// Sources: The sources of data for the person.
	Sources []*Source `json:"sources,omitempty"`

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

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

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

// PersonResponse: The response for a single person
type PersonResponse struct {
	// HttpStatusCode: **DEPRECATED** (Please use status instead)
	//
	// [HTTP 1.1 status
	// code]
	// (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
	HttpStatusCode int64 `json:"httpStatusCode,omitempty"`

	// Person: The person.
	Person *Person `json:"person,omitempty"`

	// RequestedResourceName: The original requested resource name. May be
	// different than the resource
	// name on the returned person.
	//
	// The resource name can change when adding or removing fields that link
	// a
	// contact and profile such as a verified email, verified phone number,
	// or a
	// profile URL.
	RequestedResourceName string `json:"requestedResourceName,omitempty"`

	// Status: The status of the response.
	Status *Status `json:"status,omitempty"`

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

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

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

// PhoneNumber: A person's phone number.
type PhoneNumber struct {
	// CanonicalForm: Output only. The canonicalized
	// [ITU-T
	// E.164](https://law.resource.org/pub/us/cfr/ibr/004/itu-t.E.164.
	// 1.2008.pdf)
	// form of the phone number.
	CanonicalForm string `json:"canonicalForm,omitempty"`

	// FormattedType: Output only. The type of the phone number translated
	// and formatted in the
	// viewer's account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// Metadata: Metadata about the phone number.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Type: The type of the phone number. The type can be custom or one of
	// these
	// predefined values:
	//
	// * `home`
	// * `work`
	// * `mobile`
	// * `homeFax`
	// * `workFax`
	// * `otherFax`
	// * `pager`
	// * `workMobile`
	// * `workPager`
	// * `main`
	// * `googleVoice`
	// * `other`
	Type string `json:"type,omitempty"`

	// Value: The phone number.
	Value string `json:"value,omitempty"`

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

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

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

// Photo: A person's photo. A picture shown next to the person's name
// to
// help others recognize the person.
type Photo struct {
	// Default: True if the photo is a default photo;
	// false if the photo is a user-provided photo.
	Default bool `json:"default,omitempty"`

	// Metadata: Metadata about the photo.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Url: The URL of the photo. You can change the desired size by
	// appending a query
	// parameter `sz={size}` at the end of the url, where {size} is the size
	// in
	// pixels.
	// Example:
	// https://lh3.googleusercontent.com/-T_wVWLlmg7w/AAAAAAAAAAI/AA
	// AAAAAABa8/00gzXvDBYqw/s100/photo.jpg?sz=50
	Url string `json:"url,omitempty"`

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

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

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

// ProfileMetadata: The metadata about a profile.
type ProfileMetadata struct {
	// ObjectType: Output only. The profile object type.
	//
	// Possible values:
	//   "OBJECT_TYPE_UNSPECIFIED" - Unspecified.
	//   "PERSON" - Person.
	//   "PAGE" - [Google+ Page.](http://www.google.com/+/brands/)
	ObjectType string `json:"objectType,omitempty"`

	// UserTypes: Output only. The user types.
	//
	// Possible values:
	//   "USER_TYPE_UNKNOWN" - The user type is not known.
	//   "GOOGLE_USER" - The user is a Google user.
	//   "GPLUS_USER" - The user is a Google+ user.
	//   "GOOGLE_APPS_USER" - The user is a G Suite user.
	UserTypes []string `json:"userTypes,omitempty"`

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

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

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

// Relation: A person's relation to another person.
type Relation struct {
	// FormattedType: Output only. The type of the relation translated and
	// formatted in the viewer's
	// account locale or the locale specified in the Accept-Language HTTP
	// header.
	FormattedType string `json:"formattedType,omitempty"`

	// Metadata: Metadata about the relation.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Person: The name of the other person this relation refers to.
	Person string `json:"person,omitempty"`

	// Type: The person's relation to the other person. The type can be
	// custom or one of
	// these predefined values:
	//
	// * `spouse`
	// * `child`
	// * `mother`
	// * `father`
	// * `parent`
	// * `brother`
	// * `sister`
	// * `friend`
	// * `relative`
	// * `domesticPartner`
	// * `manager`
	// * `assistant`
	// * `referredBy`
	// * `partner`
	Type string `json:"type,omitempty"`

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

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

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

// RelationshipInterest: **DEPRECATED**: No data will be returned
// A person's relationship interest .
type RelationshipInterest struct {
	// FormattedValue: Output only. The value of the relationship interest
	// translated and formatted
	// in the viewer's account locale or the locale specified in
	// the
	// Accept-Language HTTP header.
	FormattedValue string `json:"formattedValue,omitempty"`

	// Metadata: Metadata about the relationship interest.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The kind of relationship the person is looking for. The value
	// can be custom
	// or one of these predefined values:
	//
	// * `friend`
	// * `date`
	// * `relationship`
	// * `networking`
	Value string `json:"value,omitempty"`

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

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

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

// RelationshipStatus: **DEPRECATED**: No data will be returned
// A person's relationship status.
type RelationshipStatus struct {
	// FormattedValue: Output only. The value of the relationship status
	// translated and formatted in
	// the viewer's account locale or the `Accept-Language` HTTP header
	// locale.
	FormattedValue string `json:"formattedValue,omitempty"`

	// Metadata: Metadata about the relationship status.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The relationship status. The value can be custom or one of
	// these
	// predefined values:
	//
	// * `single`
	// * `inARelationship`
	// * `engaged`
	// * `married`
	// * `itsComplicated`
	// * `openRelationship`
	// * `widowed`
	// * `inDomesticPartnership`
	// * `inCivilUnion`
	Value string `json:"value,omitempty"`

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

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

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

// Residence: A person's past or current residence.
type Residence struct {
	// Current: True if the residence is the person's current
	// residence;
	// false if the residence is a past residence.
	Current bool `json:"current,omitempty"`

	// Metadata: Metadata about the residence.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The address of the residence.
	Value string `json:"value,omitempty"`

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

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

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

// SearchDirectoryPeopleResponse: The response to a request for people
// in the authenticated user's domain
// directory that match the specified query.
type SearchDirectoryPeopleResponse struct {
	// NextPageToken: A token, which can be sent as `page_token` to retrieve
	// the next page.
	// If this field is omitted, there are no subsequent pages.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// People: The list of people in the domain directory that match the
	// query.
	People []*Person `json:"people,omitempty"`

	// TotalSize: The total number of items in the list without pagination.
	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. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// SipAddress: A person's SIP address. Session Initial Protocol
// addresses are used for VoIP
// communications to make voice or video calls over the internet.
type SipAddress struct {
	// FormattedType: Output only. The type of the SIP address translated
	// and formatted in the
	// viewer's account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// Metadata: Metadata about the SIP address.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Type: The type of the SIP address. The type can be custom or or one
	// of these
	// predefined values:
	//
	// * `home`
	// * `work`
	// * `mobile`
	// * `other`
	Type string `json:"type,omitempty"`

	// Value: The SIP address in the
	// [RFC 3261 19.1](https://tools.ietf.org/html/rfc3261#section-19.1) SIP
	// URI
	// format.
	Value string `json:"value,omitempty"`

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

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

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

// Skill: A skill that the person has.
type Skill struct {
	// Metadata: Metadata about the skill.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The skill; for example, `underwater basket weaving`.
	Value string `json:"value,omitempty"`

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

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

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

// Source: The source of a field.
type Source struct {
	// Etag: **Only populated in `person.metadata.sources`.**
	//
	// The [HTTP entity tag](https://en.wikipedia.org/wiki/HTTP_ETag) of
	// the
	// source. Used for web cache validation.
	Etag string `json:"etag,omitempty"`

	// Id: The unique identifier within the source type generated by the
	// server.
	Id string `json:"id,omitempty"`

	// ProfileMetadata: Output only. **Only populated in
	// `person.metadata.sources`.**
	//
	// Metadata about a source of type PROFILE.
	ProfileMetadata *ProfileMetadata `json:"profileMetadata,omitempty"`

	// Type: The source type.
	//
	// Possible values:
	//   "SOURCE_TYPE_UNSPECIFIED" - Unspecified.
	//   "ACCOUNT" - [Google Account](https://accounts.google.com).
	//   "PROFILE" - [Google profile](https://profiles.google.com). You can
	// view the
	// profile
	// at
	// [https://profiles.google.com/](https://profiles.google.com/){id},
	// where
	// {id} is the source id.
	//   "DOMAIN_PROFILE" - [G Suite domain
	// profile](https://support.google.com/a/answer/1628008).
	//   "CONTACT" - [Google contact](https://contacts.google.com). You can
	// view the
	// contact
	// at
	// [https://contact.google.com/](https://contact.google.com/){id},
	// where
	// {id} is the source id.
	//   "OTHER_CONTACT" - [Google "Other
	// contact"](https://contacts.google.com/other).
	//   "DOMAIN_CONTACT" - [G Suite domain
	// shared
	// contact](https://support.google.com/a/answer/9281635).
	Type string `json:"type,omitempty"`

	// UpdateTime: Output only. **Only populated in
	// `person.metadata.sources`.**
	//
	// Last update timestamp of this source.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

func (s *Source) MarshalJSON() ([]byte, error) {
	type NoMethod Source
	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)
}

// Tagline: **DEPRECATED**: No data will be returned
// A brief one-line description of the person.
type Tagline struct {
	// Metadata: Metadata about the tagline.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The tagline.
	Value string `json:"value,omitempty"`

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

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

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

// UpdateContactGroupRequest: A request to update an existing user
// contact group. All updated fields will
// be replaced.
type UpdateContactGroupRequest struct {
	// ContactGroup: Required. The contact group to update.
	ContactGroup *ContactGroup `json:"contactGroup,omitempty"`

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

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

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

// UpdateContactPhotoRequest: A request to update an existing contact's
// photo.
// All requests must have a valid photo format: JPEG or PNG.
type UpdateContactPhotoRequest struct {
	// PersonFields: Optional. A field mask to restrict which fields on the
	// person are returned. Multiple
	// fields can be specified by separating them with commas. Defaults to
	// empty
	// if not set, which will skip the post mutate get. Valid values are:
	//
	// * addresses
	// * ageRanges
	// * biographies
	// * birthdays
	// * coverPhotos
	// * emailAddresses
	// * events
	// * genders
	// * imClients
	// * interests
	// * locales
	// * memberships
	// * metadata
	// * names
	// * nicknames
	// * occupations
	// * organizations
	// * phoneNumbers
	// * photos
	// * relations
	// * residences
	// * sipAddresses
	// * skills
	// * urls
	// * userDefined
	PersonFields string `json:"personFields,omitempty"`

	// PhotoBytes: Required. Raw photo bytes
	PhotoBytes string `json:"photoBytes,omitempty"`

	// Sources: Optional. A mask of what source types to return. Defaults
	// to
	// ReadSourceType.CONTACT and
	// ReadSourceType.PROFILE if not
	// set.
	//
	// Possible values:
	//   "READ_SOURCE_TYPE_UNSPECIFIED" - Unspecified.
	//   "READ_SOURCE_TYPE_PROFILE" -
	// Returns
	// SourceType.ACCOUNT,
	// SourceType.DOMAIN_PROFILE,
	// and
	// SourceType.
	// PROFILE.
	//   "READ_SOURCE_TYPE_CONTACT" - Returns
	// SourceType.CONTACT.
	//   "READ_SOURCE_TYPE_DOMAIN_CONTACT" -
	// Returns
	// SourceType.DOMAIN_CONTACT.
	Sources []string `json:"sources,omitempty"`

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

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

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

// UpdateContactPhotoResponse: The response for updating a contact's
// photo.
type UpdateContactPhotoResponse struct {
	// Person: The updated person, if person_fields is set in
	// the
	// UpdateContactPhotoRequest; otherwise this will be unset.
	Person *Person `json:"person,omitempty"`

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

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

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

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

// Url: A person's associated URLs.
type Url struct {
	// FormattedType: Output only. The type of the URL translated and
	// formatted in the viewer's
	// account locale or the `Accept-Language` HTTP header locale.
	FormattedType string `json:"formattedType,omitempty"`

	// Metadata: Metadata about the URL.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Type: The type of the URL. The type can be custom or one of these
	// predefined
	// values:
	//
	// * `home`
	// * `work`
	// * `blog`
	// * `profile`
	// * `homePage`
	// * `ftp`
	// * `reservations`
	// * `appInstallPage`: website for a Google+ application.
	// * `other`
	Type string `json:"type,omitempty"`

	// Value: The URL.
	Value string `json:"value,omitempty"`

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

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

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

// UserDefined: Arbitrary user data that is populated by the end users.
type UserDefined struct {
	// Key: The end user specified key of the user defined data.
	Key string `json:"key,omitempty"`

	// Metadata: Metadata about the user defined data.
	Metadata *FieldMetadata `json:"metadata,omitempty"`

	// Value: The end user specified value of the user defined data.
	Value string `json:"value,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 *UserDefined) MarshalJSON() ([]byte, error) {
	type NoMethod UserDefined
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "people.contactGroups.batchGet":

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

// BatchGet: Get a list of contact groups owned by the authenticated
// user by specifying
// a list of contact group resource names.
func (r *ContactGroupsService) BatchGet() *ContactGroupsBatchGetCall {
	c := &ContactGroupsBatchGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// MaxMembers sets the optional parameter "maxMembers": Specifies the
// maximum number of members to return for each group. Defaults
// to 0 if not set, which will return zero members.
func (c *ContactGroupsBatchGetCall) MaxMembers(maxMembers int64) *ContactGroupsBatchGetCall {
	c.urlParams_.Set("maxMembers", fmt.Sprint(maxMembers))
	return c
}

// ResourceNames sets the optional parameter "resourceNames": Required.
// The resource names of the contact groups to get.
func (c *ContactGroupsBatchGetCall) ResourceNames(resourceNames ...string) *ContactGroupsBatchGetCall {
	c.urlParams_.SetMulti("resourceNames", append([]string{}, resourceNames...))
	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 *ContactGroupsBatchGetCall) Fields(s ...googleapi.Field) *ContactGroupsBatchGetCall {
	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 *ContactGroupsBatchGetCall) IfNoneMatch(entityTag string) *ContactGroupsBatchGetCall {
	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 *ContactGroupsBatchGetCall) Context(ctx context.Context) *ContactGroupsBatchGetCall {
	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 *ContactGroupsBatchGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "people.contactGroups.batchGet" call.
// Exactly one of *BatchGetContactGroupsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchGetContactGroupsResponse.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 *ContactGroupsBatchGetCall) Do(opts ...googleapi.CallOption) (*BatchGetContactGroupsResponse, 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 := &BatchGetContactGroupsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get a list of contact groups owned by the authenticated user by specifying\na list of contact group resource names.",
	//   "flatPath": "v1/contactGroups:batchGet",
	//   "httpMethod": "GET",
	//   "id": "people.contactGroups.batchGet",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "maxMembers": {
	//       "description": "Optional. Specifies the maximum number of members to return for each group. Defaults\nto 0 if not set, which will return zero members.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "resourceNames": {
	//       "description": "Required. The resource names of the contact groups to get.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/contactGroups:batchGet",
	//   "response": {
	//     "$ref": "BatchGetContactGroupsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts",
	//     "https://www.googleapis.com/auth/contacts.readonly"
	//   ]
	// }

}

// method id "people.contactGroups.create":

type ContactGroupsCreateCall struct {
	s                         *Service
	createcontactgrouprequest *CreateContactGroupRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Create: Create a new contact group owned by the authenticated user.
func (r *ContactGroupsService) Create(createcontactgrouprequest *CreateContactGroupRequest) *ContactGroupsCreateCall {
	c := &ContactGroupsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.createcontactgrouprequest = createcontactgrouprequest
	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 *ContactGroupsCreateCall) Fields(s ...googleapi.Field) *ContactGroupsCreateCall {
	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 *ContactGroupsCreateCall) Context(ctx context.Context) *ContactGroupsCreateCall {
	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 *ContactGroupsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContactGroupsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	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.createcontactgrouprequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/contactGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.contactGroups.create" call.
// Exactly one of *ContactGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContactGroup.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 *ContactGroupsCreateCall) Do(opts ...googleapi.CallOption) (*ContactGroup, 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 := &ContactGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Create a new contact group owned by the authenticated user.",
	//   "flatPath": "v1/contactGroups",
	//   "httpMethod": "POST",
	//   "id": "people.contactGroups.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/contactGroups",
	//   "request": {
	//     "$ref": "CreateContactGroupRequest"
	//   },
	//   "response": {
	//     "$ref": "ContactGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.contactGroups.delete":

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

// Delete: Delete an existing contact group owned by the authenticated
// user by
// specifying a contact group resource name.
func (r *ContactGroupsService) Delete(resourceName string) *ContactGroupsDeleteCall {
	c := &ContactGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	return c
}

// DeleteContacts sets the optional parameter "deleteContacts": Set to
// true to also delete the contacts in the specified group.
func (c *ContactGroupsDeleteCall) DeleteContacts(deleteContacts bool) *ContactGroupsDeleteCall {
	c.urlParams_.Set("deleteContacts", fmt.Sprint(deleteContacts))
	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 *ContactGroupsDeleteCall) Fields(s ...googleapi.Field) *ContactGroupsDeleteCall {
	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 *ContactGroupsDeleteCall) Context(ctx context.Context) *ContactGroupsDeleteCall {
	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 *ContactGroupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContactGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.contactGroups.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 *ContactGroupsDeleteCall) 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": "Delete an existing contact group owned by the authenticated user by\nspecifying a contact group resource name.",
	//   "flatPath": "v1/contactGroups/{contactGroupsId}",
	//   "httpMethod": "DELETE",
	//   "id": "people.contactGroups.delete",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "deleteContacts": {
	//       "description": "Optional. Set to true to also delete the contacts in the specified group.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "resourceName": {
	//       "description": "Required. The resource name of the contact group to delete.",
	//       "location": "path",
	//       "pattern": "^contactGroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.contactGroups.get":

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

// Get: Get a specific contact group owned by the authenticated user by
// specifying
// a contact group resource name.
func (r *ContactGroupsService) Get(resourceName string) *ContactGroupsGetCall {
	c := &ContactGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	return c
}

// MaxMembers sets the optional parameter "maxMembers": Specifies the
// maximum number of members to return. Defaults to 0 if not
// set, which will return zero members.
func (c *ContactGroupsGetCall) MaxMembers(maxMembers int64) *ContactGroupsGetCall {
	c.urlParams_.Set("maxMembers", fmt.Sprint(maxMembers))
	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 *ContactGroupsGetCall) Fields(s ...googleapi.Field) *ContactGroupsGetCall {
	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 *ContactGroupsGetCall) IfNoneMatch(entityTag string) *ContactGroupsGetCall {
	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 *ContactGroupsGetCall) Context(ctx context.Context) *ContactGroupsGetCall {
	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 *ContactGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContactGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.contactGroups.get" call.
// Exactly one of *ContactGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContactGroup.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 *ContactGroupsGetCall) Do(opts ...googleapi.CallOption) (*ContactGroup, 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 := &ContactGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get a specific contact group owned by the authenticated user by specifying\na contact group resource name.",
	//   "flatPath": "v1/contactGroups/{contactGroupsId}",
	//   "httpMethod": "GET",
	//   "id": "people.contactGroups.get",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "maxMembers": {
	//       "description": "Optional. Specifies the maximum number of members to return. Defaults to 0 if not\nset, which will return zero members.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "resourceName": {
	//       "description": "Required. The resource name of the contact group to get.",
	//       "location": "path",
	//       "pattern": "^contactGroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}",
	//   "response": {
	//     "$ref": "ContactGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts",
	//     "https://www.googleapis.com/auth/contacts.readonly"
	//   ]
	// }

}

// method id "people.contactGroups.list":

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

// List: List all contact groups owned by the authenticated user.
// Members of the
// contact groups are not populated.
func (r *ContactGroupsService) List() *ContactGroupsListCall {
	c := &ContactGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of resources to return. Valid values are between 1 and
// 1000, inclusive. Defaults to 30 if not set or set to 0.
func (c *ContactGroupsListCall) PageSize(pageSize int64) *ContactGroupsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous call
// to
// [ListContactGroups](/people/api/rest/v1/contactgroups/list).
// Reques
// ts the next page of resources.
func (c *ContactGroupsListCall) PageToken(pageToken string) *ContactGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SyncToken sets the optional parameter "syncToken": A sync token,
// returned by a previous call to `contactgroups.list`.
// Only resources changed since the sync token was created will be
// returned.
func (c *ContactGroupsListCall) SyncToken(syncToken string) *ContactGroupsListCall {
	c.urlParams_.Set("syncToken", syncToken)
	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 *ContactGroupsListCall) Fields(s ...googleapi.Field) *ContactGroupsListCall {
	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 *ContactGroupsListCall) IfNoneMatch(entityTag string) *ContactGroupsListCall {
	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 *ContactGroupsListCall) Context(ctx context.Context) *ContactGroupsListCall {
	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 *ContactGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "people.contactGroups.list" call.
// Exactly one of *ListContactGroupsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListContactGroupsResponse.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 *ContactGroupsListCall) Do(opts ...googleapi.CallOption) (*ListContactGroupsResponse, 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 := &ListContactGroupsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List all contact groups owned by the authenticated user. Members of the\ncontact groups are not populated.",
	//   "flatPath": "v1/contactGroups",
	//   "httpMethod": "GET",
	//   "id": "people.contactGroups.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of resources to return. Valid values are between 1 and\n1000, inclusive. Defaults to 30 if not set or set to 0.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The next_page_token value returned from a previous call to\n[ListContactGroups](/people/api/rest/v1/contactgroups/list).\nRequests the next page of resources.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "syncToken": {
	//       "description": "Optional. A sync token, returned by a previous call to `contactgroups.list`.\nOnly resources changed since the sync token was created will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/contactGroups",
	//   "response": {
	//     "$ref": "ListContactGroupsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts",
	//     "https://www.googleapis.com/auth/contacts.readonly"
	//   ]
	// }

}

// 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 *ContactGroupsListCall) Pages(ctx context.Context, f func(*ListContactGroupsResponse) 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 "people.contactGroups.update":

type ContactGroupsUpdateCall struct {
	s                         *Service
	resourceName              string
	updatecontactgrouprequest *UpdateContactGroupRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Update: Update the name of an existing contact group owned by the
// authenticated
// user.
func (r *ContactGroupsService) Update(resourceName string, updatecontactgrouprequest *UpdateContactGroupRequest) *ContactGroupsUpdateCall {
	c := &ContactGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.updatecontactgrouprequest = updatecontactgrouprequest
	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 *ContactGroupsUpdateCall) Fields(s ...googleapi.Field) *ContactGroupsUpdateCall {
	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 *ContactGroupsUpdateCall) Context(ctx context.Context) *ContactGroupsUpdateCall {
	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 *ContactGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContactGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	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.updatecontactgrouprequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.contactGroups.update" call.
// Exactly one of *ContactGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContactGroup.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 *ContactGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*ContactGroup, 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 := &ContactGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Update the name of an existing contact group owned by the authenticated\nuser.",
	//   "flatPath": "v1/contactGroups/{contactGroupsId}",
	//   "httpMethod": "PUT",
	//   "id": "people.contactGroups.update",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "The resource name for the contact group, assigned by the server. An ASCII\nstring, in the form of `contactGroups/{contact_group_id}`.",
	//       "location": "path",
	//       "pattern": "^contactGroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}",
	//   "request": {
	//     "$ref": "UpdateContactGroupRequest"
	//   },
	//   "response": {
	//     "$ref": "ContactGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.contactGroups.members.modify":

type ContactGroupsMembersModifyCall struct {
	s                                *Service
	resourceName                     string
	modifycontactgroupmembersrequest *ModifyContactGroupMembersRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// Modify: Modify the members of a contact group owned by the
// authenticated user.
//
// The only system contact groups that can have members added
// are
// `contactGroups/myContacts` and `contactGroups/starred`. Other
// system
// contact groups are deprecated and can only have contacts removed.
func (r *ContactGroupsMembersService) Modify(resourceName string, modifycontactgroupmembersrequest *ModifyContactGroupMembersRequest) *ContactGroupsMembersModifyCall {
	c := &ContactGroupsMembersModifyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.modifycontactgroupmembersrequest = modifycontactgroupmembersrequest
	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 *ContactGroupsMembersModifyCall) Fields(s ...googleapi.Field) *ContactGroupsMembersModifyCall {
	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 *ContactGroupsMembersModifyCall) Context(ctx context.Context) *ContactGroupsMembersModifyCall {
	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 *ContactGroupsMembersModifyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContactGroupsMembersModifyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	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.modifycontactgroupmembersrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}/members:modify")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.contactGroups.members.modify" call.
// Exactly one of *ModifyContactGroupMembersResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ModifyContactGroupMembersResponse.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 *ContactGroupsMembersModifyCall) Do(opts ...googleapi.CallOption) (*ModifyContactGroupMembersResponse, 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 := &ModifyContactGroupMembersResponse{
		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": "Modify the members of a contact group owned by the authenticated user.\n\nThe only system contact groups that can have members added are\n`contactGroups/myContacts` and `contactGroups/starred`. Other system\ncontact groups are deprecated and can only have contacts removed.",
	//   "flatPath": "v1/contactGroups/{contactGroupsId}/members:modify",
	//   "httpMethod": "POST",
	//   "id": "people.contactGroups.members.modify",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Required. The resource name of the contact group to modify.",
	//       "location": "path",
	//       "pattern": "^contactGroups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}/members:modify",
	//   "request": {
	//     "$ref": "ModifyContactGroupMembersRequest"
	//   },
	//   "response": {
	//     "$ref": "ModifyContactGroupMembersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.otherContacts.copyOtherContactToMyContactsGroup":

type OtherContactsCopyOtherContactToMyContactsGroupCall struct {
	s                                        *Service
	resourceName                             string
	copyothercontacttomycontactsgrouprequest *CopyOtherContactToMyContactsGroupRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// CopyOtherContactToMyContactsGroup: Copies an "Other contact" to a new
// contact in the user's "myContacts" group
func (r *OtherContactsService) CopyOtherContactToMyContactsGroup(resourceName string, copyothercontacttomycontactsgrouprequest *CopyOtherContactToMyContactsGroupRequest) *OtherContactsCopyOtherContactToMyContactsGroupCall {
	c := &OtherContactsCopyOtherContactToMyContactsGroupCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.copyothercontacttomycontactsgrouprequest = copyothercontacttomycontactsgrouprequest
	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 *OtherContactsCopyOtherContactToMyContactsGroupCall) Fields(s ...googleapi.Field) *OtherContactsCopyOtherContactToMyContactsGroupCall {
	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 *OtherContactsCopyOtherContactToMyContactsGroupCall) Context(ctx context.Context) *OtherContactsCopyOtherContactToMyContactsGroupCall {
	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 *OtherContactsCopyOtherContactToMyContactsGroupCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OtherContactsCopyOtherContactToMyContactsGroupCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	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.copyothercontacttomycontactsgrouprequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}:copyOtherContactToMyContactsGroup")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.otherContacts.copyOtherContactToMyContactsGroup" call.
// Exactly one of *Person or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Person.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 *OtherContactsCopyOtherContactToMyContactsGroupCall) Do(opts ...googleapi.CallOption) (*Person, 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 := &Person{
		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": "Copies an \"Other contact\" to a new contact in the user's \"myContacts\" group",
	//   "flatPath": "v1/otherContacts/{otherContactsId}:copyOtherContactToMyContactsGroup",
	//   "httpMethod": "POST",
	//   "id": "people.otherContacts.copyOtherContactToMyContactsGroup",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Required. The resource name of the \"Other contact\" to copy.",
	//       "location": "path",
	//       "pattern": "^otherContacts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}:copyOtherContactToMyContactsGroup",
	//   "request": {
	//     "$ref": "CopyOtherContactToMyContactsGroupRequest"
	//   },
	//   "response": {
	//     "$ref": "Person"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.otherContacts.list":

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

// List: List all "Other contacts", that is contacts that are not in a
// contact
// group. "Other contacts" are typically auto created contacts
// from
// interactions.
func (r *OtherContactsService) List() *OtherContactsListCall {
	c := &OtherContactsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": The number of "Other
// contacts" to include in the response. Valid values are
// between 1 and 1000, inclusive. Defaults to 100 if not set or set to
// 0.
func (c *OtherContactsListCall) PageSize(pageSize int64) *OtherContactsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token,
// received from a previous `ListOtherContacts` call.
// Provide this to retrieve the subsequent page.
//
// When paginating, all other parameters provided to
// `ListOtherContacts`
// must match the call that provided the page token.
func (c *OtherContactsListCall) PageToken(pageToken string) *OtherContactsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": Required. A field
// mask to restrict which fields on each person are returned.
// Multiple
// fields can be specified by separating them with commas. Valid values
// are:
//
// * emailAddresses
// * names
// * phoneNumbers
func (c *OtherContactsListCall) ReadMask(readMask string) *OtherContactsListCall {
	c.urlParams_.Set("readMask", readMask)
	return c
}

// RequestSyncToken sets the optional parameter "requestSyncToken":
// Whether the response should include `next_sync_token`, which can be
// used to
// get all changes since the last request. For subsequent sync requests
// use
// the `sync_token` param instead. Initial sync requests that
// specify
// `request_sync_token` have an additional rate limit.
func (c *OtherContactsListCall) RequestSyncToken(requestSyncToken bool) *OtherContactsListCall {
	c.urlParams_.Set("requestSyncToken", fmt.Sprint(requestSyncToken))
	return c
}

// SyncToken sets the optional parameter "syncToken": A sync token,
// received from a previous `ListOtherContacts` call.
// Provide this to retrieve only the resources changed since the last
// request.
// Sync requests that specify `sync_token` have an additional rate
// limit.
//
// When syncing, all other parameters provided to
// `ListOtherContacts`
// must match the call that provided the sync token.
func (c *OtherContactsListCall) SyncToken(syncToken string) *OtherContactsListCall {
	c.urlParams_.Set("syncToken", syncToken)
	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 *OtherContactsListCall) Fields(s ...googleapi.Field) *OtherContactsListCall {
	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 *OtherContactsListCall) IfNoneMatch(entityTag string) *OtherContactsListCall {
	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 *OtherContactsListCall) Context(ctx context.Context) *OtherContactsListCall {
	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 *OtherContactsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "people.otherContacts.list" call.
// Exactly one of *ListOtherContactsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListOtherContactsResponse.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 *OtherContactsListCall) Do(opts ...googleapi.CallOption) (*ListOtherContactsResponse, 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 := &ListOtherContactsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List all \"Other contacts\", that is contacts that are not in a contact\ngroup. \"Other contacts\" are typically auto created contacts from\ninteractions.",
	//   "flatPath": "v1/otherContacts",
	//   "httpMethod": "GET",
	//   "id": "people.otherContacts.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The number of \"Other contacts\" to include in the response. Valid values are\nbetween 1 and 1000, inclusive. Defaults to 100 if not set or set to 0.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. A page token, received from a previous `ListOtherContacts` call.\nProvide this to retrieve the subsequent page.\n\nWhen paginating, all other parameters provided to `ListOtherContacts`\nmust match the call that provided the page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "Required. A field mask to restrict which fields on each person are returned. Multiple\nfields can be specified by separating them with commas. Valid values are:\n\n* emailAddresses\n* names\n* phoneNumbers",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestSyncToken": {
	//       "description": "Optional. Whether the response should include `next_sync_token`, which can be used to\nget all changes since the last request. For subsequent sync requests use\nthe `sync_token` param instead. Initial sync requests that specify\n`request_sync_token` have an additional rate limit.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "syncToken": {
	//       "description": "Optional. A sync token, received from a previous `ListOtherContacts` call.\nProvide this to retrieve only the resources changed since the last request.\nSync requests that specify `sync_token` have an additional rate limit.\n\nWhen syncing, all other parameters provided to `ListOtherContacts`\nmust match the call that provided the sync token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/otherContacts",
	//   "response": {
	//     "$ref": "ListOtherContactsResponse"
	//   }
	// }

}

// 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 *OtherContactsListCall) Pages(ctx context.Context, f func(*ListOtherContactsResponse) 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 "people.people.createContact":

type PeopleCreateContactCall struct {
	s          *Service
	person     *Person
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// CreateContact: Create a new contact and return the person resource
// for that contact.
func (r *PeopleService) CreateContact(person *Person) *PeopleCreateContactCall {
	c := &PeopleCreateContactCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.person = person
	return c
}

// PersonFields sets the optional parameter "personFields": Required. A
// field mask to restrict which fields on each person are returned.
// Multiple
// fields can be specified by separating them with commas. Defaults to
// all
// fields if not set. Valid values are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleCreateContactCall) PersonFields(personFields string) *PeopleCreateContactCall {
	c.urlParams_.Set("personFields", personFields)
	return c
}

// Sources sets the optional parameter "sources": A mask of what source
// types to return. Defaults to
// ReadSourceType.CONTACT and
// ReadSourceType.PROFILE if not
// set.
//
// Possible values:
//   "READ_SOURCE_TYPE_UNSPECIFIED"
//   "READ_SOURCE_TYPE_PROFILE"
//   "READ_SOURCE_TYPE_CONTACT"
//   "READ_SOURCE_TYPE_DOMAIN_CONTACT"
func (c *PeopleCreateContactCall) Sources(sources ...string) *PeopleCreateContactCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	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 *PeopleCreateContactCall) Fields(s ...googleapi.Field) *PeopleCreateContactCall {
	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 *PeopleCreateContactCall) Context(ctx context.Context) *PeopleCreateContactCall {
	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 *PeopleCreateContactCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PeopleCreateContactCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	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.person)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/people:createContact")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.people.createContact" call.
// Exactly one of *Person or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Person.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 *PeopleCreateContactCall) Do(opts ...googleapi.CallOption) (*Person, 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 := &Person{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Create a new contact and return the person resource for that contact.",
	//   "flatPath": "v1/people:createContact",
	//   "httpMethod": "POST",
	//   "id": "people.people.createContact",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "personFields": {
	//       "description": "Required. A field mask to restrict which fields on each person are returned. Multiple\nfields can be specified by separating them with commas. Defaults to all\nfields if not set. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sources": {
	//       "description": "Optional. A mask of what source types to return. Defaults to\nReadSourceType.CONTACT and\nReadSourceType.PROFILE if not\nset.",
	//       "enum": [
	//         "READ_SOURCE_TYPE_UNSPECIFIED",
	//         "READ_SOURCE_TYPE_PROFILE",
	//         "READ_SOURCE_TYPE_CONTACT",
	//         "READ_SOURCE_TYPE_DOMAIN_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/people:createContact",
	//   "request": {
	//     "$ref": "Person"
	//   },
	//   "response": {
	//     "$ref": "Person"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.people.deleteContact":

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

// DeleteContact: Delete a contact person. Any non-contact data will not
// be deleted.
func (r *PeopleService) DeleteContact(resourceName string) *PeopleDeleteContactCall {
	c := &PeopleDeleteContactCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	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 *PeopleDeleteContactCall) Fields(s ...googleapi.Field) *PeopleDeleteContactCall {
	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 *PeopleDeleteContactCall) Context(ctx context.Context) *PeopleDeleteContactCall {
	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 *PeopleDeleteContactCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PeopleDeleteContactCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}:deleteContact")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.people.deleteContact" 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 *PeopleDeleteContactCall) 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": "Delete a contact person. Any non-contact data will not be deleted.",
	//   "flatPath": "v1/people/{peopleId}:deleteContact",
	//   "httpMethod": "DELETE",
	//   "id": "people.people.deleteContact",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Required. The resource name of the contact to delete.",
	//       "location": "path",
	//       "pattern": "^people/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}:deleteContact",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.people.deleteContactPhoto":

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

// DeleteContactPhoto: Delete a contact's photo.
func (r *PeopleService) DeleteContactPhoto(resourceName string) *PeopleDeleteContactPhotoCall {
	c := &PeopleDeleteContactPhotoCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	return c
}

// PersonFields sets the optional parameter "personFields": A field mask
// to restrict which fields on the person are returned. Multiple
// fields can be specified by separating them with commas. Defaults to
// empty
// if not set, which will skip the post mutate get. Valid values are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleDeleteContactPhotoCall) PersonFields(personFields string) *PeopleDeleteContactPhotoCall {
	c.urlParams_.Set("personFields", personFields)
	return c
}

// Sources sets the optional parameter "sources": A mask of what source
// types to return. Defaults to
// ReadSourceType.CONTACT and
// ReadSourceType.PROFILE if not
// set.
//
// Possible values:
//   "READ_SOURCE_TYPE_UNSPECIFIED"
//   "READ_SOURCE_TYPE_PROFILE"
//   "READ_SOURCE_TYPE_CONTACT"
//   "READ_SOURCE_TYPE_DOMAIN_CONTACT"
func (c *PeopleDeleteContactPhotoCall) Sources(sources ...string) *PeopleDeleteContactPhotoCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	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 *PeopleDeleteContactPhotoCall) Fields(s ...googleapi.Field) *PeopleDeleteContactPhotoCall {
	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 *PeopleDeleteContactPhotoCall) Context(ctx context.Context) *PeopleDeleteContactPhotoCall {
	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 *PeopleDeleteContactPhotoCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PeopleDeleteContactPhotoCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}:deleteContactPhoto")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.people.deleteContactPhoto" call.
// Exactly one of *DeleteContactPhotoResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *DeleteContactPhotoResponse.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 *PeopleDeleteContactPhotoCall) Do(opts ...googleapi.CallOption) (*DeleteContactPhotoResponse, 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 := &DeleteContactPhotoResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Delete a contact's photo.",
	//   "flatPath": "v1/people/{peopleId}:deleteContactPhoto",
	//   "httpMethod": "DELETE",
	//   "id": "people.people.deleteContactPhoto",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "personFields": {
	//       "description": "Optional. A field mask to restrict which fields on the person are returned. Multiple\nfields can be specified by separating them with commas. Defaults to empty\nif not set, which will skip the post mutate get. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resourceName": {
	//       "description": "Required. The resource name of the contact whose photo will be deleted.",
	//       "location": "path",
	//       "pattern": "^people/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sources": {
	//       "description": "Optional. A mask of what source types to return. Defaults to\nReadSourceType.CONTACT and\nReadSourceType.PROFILE if not\nset.",
	//       "enum": [
	//         "READ_SOURCE_TYPE_UNSPECIFIED",
	//         "READ_SOURCE_TYPE_PROFILE",
	//         "READ_SOURCE_TYPE_CONTACT",
	//         "READ_SOURCE_TYPE_DOMAIN_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}:deleteContactPhoto",
	//   "response": {
	//     "$ref": "DeleteContactPhotoResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.people.get":

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

// Get: Provides information about a person by specifying a resource
// name. Use
// `people/me` to indicate the authenticated user.
//
// The request throws a 400 error if 'personFields' is not specified.
func (r *PeopleService) Get(resourceName string) *PeopleGetCall {
	c := &PeopleGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	return c
}

// PersonFields sets the optional parameter "personFields": Required. A
// field mask to restrict which fields on the person are returned.
// Multiple
// fields can be specified by separating them with commas. Valid values
// are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleGetCall) PersonFields(personFields string) *PeopleGetCall {
	c.urlParams_.Set("personFields", personFields)
	return c
}

// RequestMaskIncludeField sets the optional parameter
// "requestMask.includeField": Required. Comma-separated list of person
// fields to be included in the response. Each
// path should start with `person.`: for example, `person.names`
// or
// `person.photos`.
func (c *PeopleGetCall) RequestMaskIncludeField(requestMaskIncludeField string) *PeopleGetCall {
	c.urlParams_.Set("requestMask.includeField", requestMaskIncludeField)
	return c
}

// Sources sets the optional parameter "sources": A mask of what source
// types to return. Defaults
// to
// ReadSourceType.PROFILE
// and
// ReadSourceType.CONTACT
// if not set.
//
// Possible values:
//   "READ_SOURCE_TYPE_UNSPECIFIED"
//   "READ_SOURCE_TYPE_PROFILE"
//   "READ_SOURCE_TYPE_CONTACT"
//   "READ_SOURCE_TYPE_DOMAIN_CONTACT"
func (c *PeopleGetCall) Sources(sources ...string) *PeopleGetCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	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 *PeopleGetCall) Fields(s ...googleapi.Field) *PeopleGetCall {
	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 *PeopleGetCall) IfNoneMatch(entityTag string) *PeopleGetCall {
	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 *PeopleGetCall) Context(ctx context.Context) *PeopleGetCall {
	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 *PeopleGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PeopleGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.people.get" call.
// Exactly one of *Person or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Person.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 *PeopleGetCall) Do(opts ...googleapi.CallOption) (*Person, 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 := &Person{
		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": "Provides information about a person by specifying a resource name. Use\n`people/me` to indicate the authenticated user.\n\nThe request throws a 400 error if 'personFields' is not specified.",
	//   "flatPath": "v1/people/{peopleId}",
	//   "httpMethod": "GET",
	//   "id": "people.people.get",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "personFields": {
	//       "description": "Required. A field mask to restrict which fields on the person are returned. Multiple\nfields can be specified by separating them with commas. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMask.includeField": {
	//       "description": "Required. Comma-separated list of person fields to be included in the response. Each\npath should start with `person.`: for example, `person.names` or\n`person.photos`.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resourceName": {
	//       "description": "Required. The resource name of the person to provide information about.\n\n- To get information about the authenticated user, specify `people/me`.\n- To get information about a google account, specify\n `people/{account_id}`.\n- To get information about a contact, specify the resource name that\n  identifies the contact as returned by\n[`people.connections.list`](/people/api/rest/v1/people.connections/list).",
	//       "location": "path",
	//       "pattern": "^people/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sources": {
	//       "description": "Optional. A mask of what source types to return. Defaults to\nReadSourceType.PROFILE\nand\nReadSourceType.CONTACT\nif not set.",
	//       "enum": [
	//         "READ_SOURCE_TYPE_UNSPECIFIED",
	//         "READ_SOURCE_TYPE_PROFILE",
	//         "READ_SOURCE_TYPE_CONTACT",
	//         "READ_SOURCE_TYPE_DOMAIN_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}",
	//   "response": {
	//     "$ref": "Person"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts",
	//     "https://www.googleapis.com/auth/contacts.readonly",
	//     "https://www.googleapis.com/auth/directory.readonly",
	//     "https://www.googleapis.com/auth/user.addresses.read",
	//     "https://www.googleapis.com/auth/user.birthday.read",
	//     "https://www.googleapis.com/auth/user.emails.read",
	//     "https://www.googleapis.com/auth/user.gender.read",
	//     "https://www.googleapis.com/auth/user.organization.read",
	//     "https://www.googleapis.com/auth/user.phonenumbers.read",
	//     "https://www.googleapis.com/auth/userinfo.email",
	//     "https://www.googleapis.com/auth/userinfo.profile"
	//   ]
	// }

}

// method id "people.people.getBatchGet":

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

// GetBatchGet: Provides information about a list of specific people by
// specifying a list
// of requested resource names. Use `people/me` to indicate the
// authenticated
// user.
//
// The request throws a 400 error if 'personFields' is not specified.
func (r *PeopleService) GetBatchGet() *PeopleGetBatchGetCall {
	c := &PeopleGetBatchGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PersonFields sets the optional parameter "personFields": Required. A
// field mask to restrict which fields on each person are returned.
// Multiple
// fields can be specified by separating them with commas. Valid values
// are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleGetBatchGetCall) PersonFields(personFields string) *PeopleGetBatchGetCall {
	c.urlParams_.Set("personFields", personFields)
	return c
}

// RequestMaskIncludeField sets the optional parameter
// "requestMask.includeField": Required. Comma-separated list of person
// fields to be included in the response. Each
// path should start with `person.`: for example, `person.names`
// or
// `person.photos`.
func (c *PeopleGetBatchGetCall) RequestMaskIncludeField(requestMaskIncludeField string) *PeopleGetBatchGetCall {
	c.urlParams_.Set("requestMask.includeField", requestMaskIncludeField)
	return c
}

// ResourceNames sets the optional parameter "resourceNames": Required.
// The resource names of the people to provide information about.
//
// - To get information about the authenticated user, specify
// `people/me`.
// - To get information about a google account, specify
//   `people/{account_id}`.
// - To get information about a contact, specify the resource name that
//   identifies the contact as returned
// by
// [`people.connections.list`](/people/api/rest/v1/people.connections/
// list).
//
// You can include up to 50 resource names in one request.
func (c *PeopleGetBatchGetCall) ResourceNames(resourceNames ...string) *PeopleGetBatchGetCall {
	c.urlParams_.SetMulti("resourceNames", append([]string{}, resourceNames...))
	return c
}

// Sources sets the optional parameter "sources": A mask of what source
// types to return. Defaults
// to
// ReadSourceType.CONTACT
// and
// ReadSourceType.PROFILE
// if not set.
//
// Possible values:
//   "READ_SOURCE_TYPE_UNSPECIFIED"
//   "READ_SOURCE_TYPE_PROFILE"
//   "READ_SOURCE_TYPE_CONTACT"
//   "READ_SOURCE_TYPE_DOMAIN_CONTACT"
func (c *PeopleGetBatchGetCall) Sources(sources ...string) *PeopleGetBatchGetCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	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 *PeopleGetBatchGetCall) Fields(s ...googleapi.Field) *PeopleGetBatchGetCall {
	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 *PeopleGetBatchGetCall) IfNoneMatch(entityTag string) *PeopleGetBatchGetCall {
	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 *PeopleGetBatchGetCall) Context(ctx context.Context) *PeopleGetBatchGetCall {
	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 *PeopleGetBatchGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "people.people.getBatchGet" call.
// Exactly one of *GetPeopleResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GetPeopleResponse.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 *PeopleGetBatchGetCall) Do(opts ...googleapi.CallOption) (*GetPeopleResponse, 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 := &GetPeopleResponse{
		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": "Provides information about a list of specific people by specifying a list\nof requested resource names. Use `people/me` to indicate the authenticated\nuser.\n\nThe request throws a 400 error if 'personFields' is not specified.",
	//   "flatPath": "v1/people:batchGet",
	//   "httpMethod": "GET",
	//   "id": "people.people.getBatchGet",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "personFields": {
	//       "description": "Required. A field mask to restrict which fields on each person are returned. Multiple\nfields can be specified by separating them with commas. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMask.includeField": {
	//       "description": "Required. Comma-separated list of person fields to be included in the response. Each\npath should start with `person.`: for example, `person.names` or\n`person.photos`.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resourceNames": {
	//       "description": "Required. The resource names of the people to provide information about.\n\n- To get information about the authenticated user, specify `people/me`.\n- To get information about a google account, specify\n  `people/{account_id}`.\n- To get information about a contact, specify the resource name that\n  identifies the contact as returned by\n[`people.connections.list`](/people/api/rest/v1/people.connections/list).\n\nYou can include up to 50 resource names in one request.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sources": {
	//       "description": "Optional. A mask of what source types to return. Defaults to\nReadSourceType.CONTACT\nand\nReadSourceType.PROFILE\nif not set.",
	//       "enum": [
	//         "READ_SOURCE_TYPE_UNSPECIFIED",
	//         "READ_SOURCE_TYPE_PROFILE",
	//         "READ_SOURCE_TYPE_CONTACT",
	//         "READ_SOURCE_TYPE_DOMAIN_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/people:batchGet",
	//   "response": {
	//     "$ref": "GetPeopleResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts",
	//     "https://www.googleapis.com/auth/contacts.readonly",
	//     "https://www.googleapis.com/auth/directory.readonly",
	//     "https://www.googleapis.com/auth/user.addresses.read",
	//     "https://www.googleapis.com/auth/user.birthday.read",
	//     "https://www.googleapis.com/auth/user.emails.read",
	//     "https://www.googleapis.com/auth/user.gender.read",
	//     "https://www.googleapis.com/auth/user.organization.read",
	//     "https://www.googleapis.com/auth/user.phonenumbers.read",
	//     "https://www.googleapis.com/auth/userinfo.email",
	//     "https://www.googleapis.com/auth/userinfo.profile"
	//   ]
	// }

}

// method id "people.people.listDirectoryPeople":

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

// ListDirectoryPeople: Provides a list of domain profiles and domain
// contacts in the authenticated
// user's domain directory.
func (r *PeopleService) ListDirectoryPeople() *PeopleListDirectoryPeopleCall {
	c := &PeopleListDirectoryPeopleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// MergeSources sets the optional parameter "mergeSources": Additional
// data to merge into the directory sources if they are
// connected
// through verified join keys such as email addresses or phone numbers.
//
// Possible values:
//   "DIRECTORY_MERGE_SOURCE_TYPE_UNSPECIFIED"
//   "DIRECTORY_MERGE_SOURCE_TYPE_CONTACT"
func (c *PeopleListDirectoryPeopleCall) MergeSources(mergeSources ...string) *PeopleListDirectoryPeopleCall {
	c.urlParams_.SetMulti("mergeSources", append([]string{}, mergeSources...))
	return c
}

// PageSize sets the optional parameter "pageSize": The number of people
// to include in the response. Valid values are
// between 1 and 1000, inclusive. Defaults to 100 if not set or set to
// 0.
func (c *PeopleListDirectoryPeopleCall) PageSize(pageSize int64) *PeopleListDirectoryPeopleCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token,
// received from a previous `ListDirectoryPeople` call.
// Provide this to retrieve the subsequent page.
//
// When paginating, all other parameters provided to
// `ListDirectoryPeople`
// must match the call that provided the page token.
func (c *PeopleListDirectoryPeopleCall) PageToken(pageToken string) *PeopleListDirectoryPeopleCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": Required. A field
// mask to restrict which fields on each person are returned.
// Multiple
// fields can be specified by separating them with commas. Valid values
// are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleListDirectoryPeopleCall) ReadMask(readMask string) *PeopleListDirectoryPeopleCall {
	c.urlParams_.Set("readMask", readMask)
	return c
}

// RequestSyncToken sets the optional parameter "requestSyncToken":
// Whether the response should include `next_sync_token`, which can be
// used to
// get all changes since the last request. For subsequent sync requests
// use
// the `sync_token` param instead.
func (c *PeopleListDirectoryPeopleCall) RequestSyncToken(requestSyncToken bool) *PeopleListDirectoryPeopleCall {
	c.urlParams_.Set("requestSyncToken", fmt.Sprint(requestSyncToken))
	return c
}

// Sources sets the optional parameter "sources": Required. Directory
// sources to return.
//
// Possible values:
//   "DIRECTORY_SOURCE_TYPE_UNSPECIFIED"
//   "DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT"
//   "DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE"
func (c *PeopleListDirectoryPeopleCall) Sources(sources ...string) *PeopleListDirectoryPeopleCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	return c
}

// SyncToken sets the optional parameter "syncToken": A sync token,
// received from a previous `ListDirectoryPeople` call.
// Provide this to retrieve only the resources changed since the last
// request.
//
// When syncing, all other parameters provided to
// `ListDirectoryPeople`
// must match the call that provided the sync token.
func (c *PeopleListDirectoryPeopleCall) SyncToken(syncToken string) *PeopleListDirectoryPeopleCall {
	c.urlParams_.Set("syncToken", syncToken)
	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 *PeopleListDirectoryPeopleCall) Fields(s ...googleapi.Field) *PeopleListDirectoryPeopleCall {
	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 *PeopleListDirectoryPeopleCall) IfNoneMatch(entityTag string) *PeopleListDirectoryPeopleCall {
	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 *PeopleListDirectoryPeopleCall) Context(ctx context.Context) *PeopleListDirectoryPeopleCall {
	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 *PeopleListDirectoryPeopleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "people.people.listDirectoryPeople" call.
// Exactly one of *ListDirectoryPeopleResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListDirectoryPeopleResponse.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 *PeopleListDirectoryPeopleCall) Do(opts ...googleapi.CallOption) (*ListDirectoryPeopleResponse, 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 := &ListDirectoryPeopleResponse{
		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": "Provides a list of domain profiles and domain contacts in the authenticated\nuser's domain directory.",
	//   "flatPath": "v1/people:listDirectoryPeople",
	//   "httpMethod": "GET",
	//   "id": "people.people.listDirectoryPeople",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "mergeSources": {
	//       "description": "Optional. Additional data to merge into the directory sources if they are connected\nthrough verified join keys such as email addresses or phone numbers.",
	//       "enum": [
	//         "DIRECTORY_MERGE_SOURCE_TYPE_UNSPECIFIED",
	//         "DIRECTORY_MERGE_SOURCE_TYPE_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The number of people to include in the response. Valid values are\nbetween 1 and 1000, inclusive. Defaults to 100 if not set or set to 0.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. A page token, received from a previous `ListDirectoryPeople` call.\nProvide this to retrieve the subsequent page.\n\nWhen paginating, all other parameters provided to `ListDirectoryPeople`\nmust match the call that provided the page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "Required. A field mask to restrict which fields on each person are returned. Multiple\nfields can be specified by separating them with commas. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestSyncToken": {
	//       "description": "Optional. Whether the response should include `next_sync_token`, which can be used to\nget all changes since the last request. For subsequent sync requests use\nthe `sync_token` param instead.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "sources": {
	//       "description": "Required. Directory sources to return.",
	//       "enum": [
	//         "DIRECTORY_SOURCE_TYPE_UNSPECIFIED",
	//         "DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT",
	//         "DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "syncToken": {
	//       "description": "Optional. A sync token, received from a previous `ListDirectoryPeople` call.\nProvide this to retrieve only the resources changed since the last request.\n\nWhen syncing, all other parameters provided to `ListDirectoryPeople`\nmust match the call that provided the sync token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/people:listDirectoryPeople",
	//   "response": {
	//     "$ref": "ListDirectoryPeopleResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/directory.readonly"
	//   ]
	// }

}

// 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 *PeopleListDirectoryPeopleCall) Pages(ctx context.Context, f func(*ListDirectoryPeopleResponse) 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 "people.people.searchDirectoryPeople":

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

// SearchDirectoryPeople: Provides a list of domain profiles and domain
// contacts in the authenticated
// user's domain directory that match the search query.
func (r *PeopleService) SearchDirectoryPeople() *PeopleSearchDirectoryPeopleCall {
	c := &PeopleSearchDirectoryPeopleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// MergeSources sets the optional parameter "mergeSources": Additional
// data to merge into the directory sources if they are
// connected
// through verified join keys such as email addresses or phone numbers.
//
// Possible values:
//   "DIRECTORY_MERGE_SOURCE_TYPE_UNSPECIFIED"
//   "DIRECTORY_MERGE_SOURCE_TYPE_CONTACT"
func (c *PeopleSearchDirectoryPeopleCall) MergeSources(mergeSources ...string) *PeopleSearchDirectoryPeopleCall {
	c.urlParams_.SetMulti("mergeSources", append([]string{}, mergeSources...))
	return c
}

// PageSize sets the optional parameter "pageSize": The number of people
// to include in the response. Valid values are
// between 1 and 500, inclusive. Defaults to 100 if not set or set to 0.
func (c *PeopleSearchDirectoryPeopleCall) PageSize(pageSize int64) *PeopleSearchDirectoryPeopleCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token,
// received from a previous `SearchDirectoryPeople` call.
// Provide this to retrieve the subsequent page.
//
// When paginating, all other parameters provided to
// `SearchDirectoryPeople`
// must match the call that provided the page token.
func (c *PeopleSearchDirectoryPeopleCall) PageToken(pageToken string) *PeopleSearchDirectoryPeopleCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": Required. Prefix query
// that matches fields in the person. Does NOT use the
// read_mask for determining what fields to match.
func (c *PeopleSearchDirectoryPeopleCall) Query(query string) *PeopleSearchDirectoryPeopleCall {
	c.urlParams_.Set("query", query)
	return c
}

// ReadMask sets the optional parameter "readMask": Required. A field
// mask to restrict which fields on each person are returned.
// Multiple
// fields can be specified by separating them with commas. Valid values
// are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleSearchDirectoryPeopleCall) ReadMask(readMask string) *PeopleSearchDirectoryPeopleCall {
	c.urlParams_.Set("readMask", readMask)
	return c
}

// Sources sets the optional parameter "sources": Required. Directory
// sources to return.
//
// Possible values:
//   "DIRECTORY_SOURCE_TYPE_UNSPECIFIED"
//   "DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT"
//   "DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE"
func (c *PeopleSearchDirectoryPeopleCall) Sources(sources ...string) *PeopleSearchDirectoryPeopleCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	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 *PeopleSearchDirectoryPeopleCall) Fields(s ...googleapi.Field) *PeopleSearchDirectoryPeopleCall {
	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 *PeopleSearchDirectoryPeopleCall) IfNoneMatch(entityTag string) *PeopleSearchDirectoryPeopleCall {
	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 *PeopleSearchDirectoryPeopleCall) Context(ctx context.Context) *PeopleSearchDirectoryPeopleCall {
	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 *PeopleSearchDirectoryPeopleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "people.people.searchDirectoryPeople" call.
// Exactly one of *SearchDirectoryPeopleResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *SearchDirectoryPeopleResponse.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 *PeopleSearchDirectoryPeopleCall) Do(opts ...googleapi.CallOption) (*SearchDirectoryPeopleResponse, 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 := &SearchDirectoryPeopleResponse{
		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": "Provides a list of domain profiles and domain contacts in the authenticated\nuser's domain directory that match the search query.",
	//   "flatPath": "v1/people:searchDirectoryPeople",
	//   "httpMethod": "GET",
	//   "id": "people.people.searchDirectoryPeople",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "mergeSources": {
	//       "description": "Optional. Additional data to merge into the directory sources if they are connected\nthrough verified join keys such as email addresses or phone numbers.",
	//       "enum": [
	//         "DIRECTORY_MERGE_SOURCE_TYPE_UNSPECIFIED",
	//         "DIRECTORY_MERGE_SOURCE_TYPE_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The number of people to include in the response. Valid values are\nbetween 1 and 500, inclusive. Defaults to 100 if not set or set to 0.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. A page token, received from a previous `SearchDirectoryPeople` call.\nProvide this to retrieve the subsequent page.\n\nWhen paginating, all other parameters provided to `SearchDirectoryPeople`\nmust match the call that provided the page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "Required. Prefix query that matches fields in the person. Does NOT use the\nread_mask for determining what fields to match.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "Required. A field mask to restrict which fields on each person are returned. Multiple\nfields can be specified by separating them with commas. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sources": {
	//       "description": "Required. Directory sources to return.",
	//       "enum": [
	//         "DIRECTORY_SOURCE_TYPE_UNSPECIFIED",
	//         "DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT",
	//         "DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/people:searchDirectoryPeople",
	//   "response": {
	//     "$ref": "SearchDirectoryPeopleResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/directory.readonly"
	//   ]
	// }

}

// 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 *PeopleSearchDirectoryPeopleCall) Pages(ctx context.Context, f func(*SearchDirectoryPeopleResponse) 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 "people.people.updateContact":

type PeopleUpdateContactCall struct {
	s            *Service
	resourceName string
	person       *Person
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// UpdateContact: Update contact data for an existing contact person.
// Any non-contact data
// will not be modified.
//
// The request throws a 400 error if `updatePersonFields` is not
// specified.
//
// The request throws a 400 error if `person.metadata.sources` is
// not
// specified for the contact to be updated.
//
// The request throws a 400 error with an error with
// reason
// "failedPrecondition" if `person.metadata.sources.etag` is different
// than
// the contact's etag, which indicates the contact has changed since its
// data
// was read. Clients should get the latest person and re-apply their
// updates
// to the latest person.
func (r *PeopleService) UpdateContact(resourceName string, person *Person) *PeopleUpdateContactCall {
	c := &PeopleUpdateContactCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.person = person
	return c
}

// PersonFields sets the optional parameter "personFields": A field mask
// to restrict which fields on each person are returned. Multiple
// fields can be specified by separating them with commas. Defaults to
// all
// fields if not set. Valid values are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleUpdateContactCall) PersonFields(personFields string) *PeopleUpdateContactCall {
	c.urlParams_.Set("personFields", personFields)
	return c
}

// Sources sets the optional parameter "sources": A mask of what source
// types to return. Defaults to
// ReadSourceType.CONTACT and
// ReadSourceType.PROFILE if not
// set.
//
// Possible values:
//   "READ_SOURCE_TYPE_UNSPECIFIED"
//   "READ_SOURCE_TYPE_PROFILE"
//   "READ_SOURCE_TYPE_CONTACT"
//   "READ_SOURCE_TYPE_DOMAIN_CONTACT"
func (c *PeopleUpdateContactCall) Sources(sources ...string) *PeopleUpdateContactCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	return c
}

// UpdatePersonFields sets the optional parameter "updatePersonFields":
// Required. A field mask to restrict which fields on the person are
// updated. Multiple
// fields can be specified by separating them with commas.
// All updated fields will be replaced. Valid values are:
//
// * addresses
// * biographies
// * birthdays
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * relations
// * residences
// * sipAddresses
// * urls
// * userDefined
func (c *PeopleUpdateContactCall) UpdatePersonFields(updatePersonFields string) *PeopleUpdateContactCall {
	c.urlParams_.Set("updatePersonFields", updatePersonFields)
	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 *PeopleUpdateContactCall) Fields(s ...googleapi.Field) *PeopleUpdateContactCall {
	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 *PeopleUpdateContactCall) Context(ctx context.Context) *PeopleUpdateContactCall {
	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 *PeopleUpdateContactCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PeopleUpdateContactCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	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.person)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}:updateContact")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.people.updateContact" call.
// Exactly one of *Person or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Person.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 *PeopleUpdateContactCall) Do(opts ...googleapi.CallOption) (*Person, 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 := &Person{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Update contact data for an existing contact person. Any non-contact data\nwill not be modified.\n\nThe request throws a 400 error if `updatePersonFields` is not specified.\n\nThe request throws a 400 error if `person.metadata.sources` is not\nspecified for the contact to be updated.\n\nThe request throws a 400 error with an error with reason\n`\"failedPrecondition\"` if `person.metadata.sources.etag` is different than\nthe contact's etag, which indicates the contact has changed since its data\nwas read. Clients should get the latest person and re-apply their updates\nto the latest person.",
	//   "flatPath": "v1/people/{peopleId}:updateContact",
	//   "httpMethod": "PATCH",
	//   "id": "people.people.updateContact",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "personFields": {
	//       "description": "Optional. A field mask to restrict which fields on each person are returned. Multiple\nfields can be specified by separating them with commas. Defaults to all\nfields if not set. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "resourceName": {
	//       "description": "The resource name for the person, assigned by the server. An ASCII string\nwith a max length of 27 characters, in the form of\n`people/{person_id}`.",
	//       "location": "path",
	//       "pattern": "^people/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sources": {
	//       "description": "Optional. A mask of what source types to return. Defaults to\nReadSourceType.CONTACT and\nReadSourceType.PROFILE if not\nset.",
	//       "enum": [
	//         "READ_SOURCE_TYPE_UNSPECIFIED",
	//         "READ_SOURCE_TYPE_PROFILE",
	//         "READ_SOURCE_TYPE_CONTACT",
	//         "READ_SOURCE_TYPE_DOMAIN_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "updatePersonFields": {
	//       "description": "Required. A field mask to restrict which fields on the person are updated. Multiple\nfields can be specified by separating them with commas.\nAll updated fields will be replaced. Valid values are:\n\n* addresses\n* biographies\n* birthdays\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* relations\n* residences\n* sipAddresses\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}:updateContact",
	//   "request": {
	//     "$ref": "Person"
	//   },
	//   "response": {
	//     "$ref": "Person"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.people.updateContactPhoto":

type PeopleUpdateContactPhotoCall struct {
	s                         *Service
	resourceName              string
	updatecontactphotorequest *UpdateContactPhotoRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// UpdateContactPhoto: Update a contact's photo.
func (r *PeopleService) UpdateContactPhoto(resourceName string, updatecontactphotorequest *UpdateContactPhotoRequest) *PeopleUpdateContactPhotoCall {
	c := &PeopleUpdateContactPhotoCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.updatecontactphotorequest = updatecontactphotorequest
	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 *PeopleUpdateContactPhotoCall) Fields(s ...googleapi.Field) *PeopleUpdateContactPhotoCall {
	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 *PeopleUpdateContactPhotoCall) Context(ctx context.Context) *PeopleUpdateContactPhotoCall {
	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 *PeopleUpdateContactPhotoCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PeopleUpdateContactPhotoCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	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.updatecontactphotorequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}:updateContactPhoto")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.people.updateContactPhoto" call.
// Exactly one of *UpdateContactPhotoResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *UpdateContactPhotoResponse.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 *PeopleUpdateContactPhotoCall) Do(opts ...googleapi.CallOption) (*UpdateContactPhotoResponse, 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 := &UpdateContactPhotoResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Update a contact's photo.",
	//   "flatPath": "v1/people/{peopleId}:updateContactPhoto",
	//   "httpMethod": "PATCH",
	//   "id": "people.people.updateContactPhoto",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Required. Person resource name",
	//       "location": "path",
	//       "pattern": "^people/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}:updateContactPhoto",
	//   "request": {
	//     "$ref": "UpdateContactPhotoRequest"
	//   },
	//   "response": {
	//     "$ref": "UpdateContactPhotoResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts"
	//   ]
	// }

}

// method id "people.people.connections.list":

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

// List: Provides a list of the authenticated user's contacts.
//
// The request throws a 400 error if 'personFields' is not specified.
func (r *PeopleConnectionsService) List(resourceName string) *PeopleConnectionsListCall {
	c := &PeopleConnectionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	return c
}

// PageSize sets the optional parameter "pageSize": The number of
// connections to include in the response. Valid values are
// between 1 and 1000, inclusive. Defaults to 100 if not set or set to
// 0.
func (c *PeopleConnectionsListCall) PageSize(pageSize int64) *PeopleConnectionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token,
// received from a previous `ListConnections` call.
// Provide this to retrieve the subsequent page.
//
// When paginating, all other parameters provided to
// `ListConnections`
// must match the call that provided the page token.
func (c *PeopleConnectionsListCall) PageToken(pageToken string) *PeopleConnectionsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PersonFields sets the optional parameter "personFields": Required. A
// field mask to restrict which fields on each person are returned.
// Multiple
// fields can be specified by separating them with commas. Valid values
// are:
//
// * addresses
// * ageRanges
// * biographies
// * birthdays
// * coverPhotos
// * emailAddresses
// * events
// * genders
// * imClients
// * interests
// * locales
// * memberships
// * metadata
// * names
// * nicknames
// * occupations
// * organizations
// * phoneNumbers
// * photos
// * relations
// * residences
// * sipAddresses
// * skills
// * urls
// * userDefined
func (c *PeopleConnectionsListCall) PersonFields(personFields string) *PeopleConnectionsListCall {
	c.urlParams_.Set("personFields", personFields)
	return c
}

// RequestMaskIncludeField sets the optional parameter
// "requestMask.includeField": Required. Comma-separated list of person
// fields to be included in the response. Each
// path should start with `person.`: for example, `person.names`
// or
// `person.photos`.
func (c *PeopleConnectionsListCall) RequestMaskIncludeField(requestMaskIncludeField string) *PeopleConnectionsListCall {
	c.urlParams_.Set("requestMask.includeField", requestMaskIncludeField)
	return c
}

// RequestSyncToken sets the optional parameter "requestSyncToken":
// Whether the response should include `next_sync_token`, which can be
// used to
// get all changes since the last request. For subsequent sync requests
// use
// the `sync_token` param instead. Initial sync requests that
// specify
// `request_sync_token` have an additional rate limit.
func (c *PeopleConnectionsListCall) RequestSyncToken(requestSyncToken bool) *PeopleConnectionsListCall {
	c.urlParams_.Set("requestSyncToken", fmt.Sprint(requestSyncToken))
	return c
}

// SortOrder sets the optional parameter "sortOrder": The order in which
// the connections should be sorted. Defaults
// to
// `LAST_MODIFIED_ASCENDING`.
//
// Possible values:
//   "LAST_MODIFIED_ASCENDING"
//   "LAST_MODIFIED_DESCENDING"
//   "FIRST_NAME_ASCENDING"
//   "LAST_NAME_ASCENDING"
func (c *PeopleConnectionsListCall) SortOrder(sortOrder string) *PeopleConnectionsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Sources sets the optional parameter "sources": A mask of what source
// types to return. Defaults
// to
// ReadSourceType.CONTACT
// and
// ReadSourceType.PROFILE if not
// set.
//
// Possible values:
//   "READ_SOURCE_TYPE_UNSPECIFIED"
//   "READ_SOURCE_TYPE_PROFILE"
//   "READ_SOURCE_TYPE_CONTACT"
//   "READ_SOURCE_TYPE_DOMAIN_CONTACT"
func (c *PeopleConnectionsListCall) Sources(sources ...string) *PeopleConnectionsListCall {
	c.urlParams_.SetMulti("sources", append([]string{}, sources...))
	return c
}

// SyncToken sets the optional parameter "syncToken": A sync token,
// received from a previous `ListConnections` call.
// Provide this to retrieve only the resources changed since the last
// request.
// Sync requests that specify `sync_token` have an additional rate
// limit.
//
// When syncing, all other parameters provided to `ListConnections`
// must match the call that provided the sync token.
func (c *PeopleConnectionsListCall) SyncToken(syncToken string) *PeopleConnectionsListCall {
	c.urlParams_.Set("syncToken", syncToken)
	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 *PeopleConnectionsListCall) Fields(s ...googleapi.Field) *PeopleConnectionsListCall {
	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 *PeopleConnectionsListCall) IfNoneMatch(entityTag string) *PeopleConnectionsListCall {
	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 *PeopleConnectionsListCall) Context(ctx context.Context) *PeopleConnectionsListCall {
	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 *PeopleConnectionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PeopleConnectionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200616")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resourceName}/connections")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "people.people.connections.list" call.
// Exactly one of *ListConnectionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListConnectionsResponse.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 *PeopleConnectionsListCall) Do(opts ...googleapi.CallOption) (*ListConnectionsResponse, 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 := &ListConnectionsResponse{
		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": "Provides a list of the authenticated user's contacts.\n\nThe request throws a 400 error if 'personFields' is not specified.",
	//   "flatPath": "v1/people/{peopleId}/connections",
	//   "httpMethod": "GET",
	//   "id": "people.people.connections.list",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The number of connections to include in the response. Valid values are\nbetween 1 and 1000, inclusive. Defaults to 100 if not set or set to 0.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. A page token, received from a previous `ListConnections` call.\nProvide this to retrieve the subsequent page.\n\nWhen paginating, all other parameters provided to `ListConnections`\nmust match the call that provided the page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "personFields": {
	//       "description": "Required. A field mask to restrict which fields on each person are returned. Multiple\nfields can be specified by separating them with commas. Valid values are:\n\n* addresses\n* ageRanges\n* biographies\n* birthdays\n* coverPhotos\n* emailAddresses\n* events\n* genders\n* imClients\n* interests\n* locales\n* memberships\n* metadata\n* names\n* nicknames\n* occupations\n* organizations\n* phoneNumbers\n* photos\n* relations\n* residences\n* sipAddresses\n* skills\n* urls\n* userDefined",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMask.includeField": {
	//       "description": "Required. Comma-separated list of person fields to be included in the response. Each\npath should start with `person.`: for example, `person.names` or\n`person.photos`.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestSyncToken": {
	//       "description": "Optional. Whether the response should include `next_sync_token`, which can be used to\nget all changes since the last request. For subsequent sync requests use\nthe `sync_token` param instead. Initial sync requests that specify\n`request_sync_token` have an additional rate limit.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "resourceName": {
	//       "description": "Required. The resource name to return connections for. Only `people/me` is valid.",
	//       "location": "path",
	//       "pattern": "^people/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Optional. The order in which the connections should be sorted. Defaults to\n`LAST_MODIFIED_ASCENDING`.",
	//       "enum": [
	//         "LAST_MODIFIED_ASCENDING",
	//         "LAST_MODIFIED_DESCENDING",
	//         "FIRST_NAME_ASCENDING",
	//         "LAST_NAME_ASCENDING"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sources": {
	//       "description": "Optional. A mask of what source types to return. Defaults to\nReadSourceType.CONTACT\nand\nReadSourceType.PROFILE if not\nset.",
	//       "enum": [
	//         "READ_SOURCE_TYPE_UNSPECIFIED",
	//         "READ_SOURCE_TYPE_PROFILE",
	//         "READ_SOURCE_TYPE_CONTACT",
	//         "READ_SOURCE_TYPE_DOMAIN_CONTACT"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "syncToken": {
	//       "description": "Optional. A sync token, received from a previous `ListConnections` call.\nProvide this to retrieve only the resources changed since the last request.\nSync requests that specify `sync_token` have an additional rate limit.\n\nWhen syncing, all other parameters provided to `ListConnections`\nmust match the call that provided the sync token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+resourceName}/connections",
	//   "response": {
	//     "$ref": "ListConnectionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts",
	//     "https://www.googleapis.com/auth/contacts.readonly"
	//   ]
	// }

}

// 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 *PeopleConnectionsListCall) Pages(ctx context.Context, f func(*ListConnectionsResponse) 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)
	}
}
