// 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/"
const mtlsBasePath = "https://people.mtls.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 contact info automatically saved in your "Other
	// contacts"
	ContactsOtherReadonlyScope = "https://www.googleapis.com/auth/contacts.other.readonly"

	// 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.other.readonly",
		"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))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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",
	//     "https://www.googleapis.com/auth/contacts.other.readonly"
	//   ]
	// }

}

// 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/20200625")
	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"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/contacts.other.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 *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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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/20200625")
	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)
	}
}
