// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.33.0
// 	protoc        v4.25.3
// source: google/chat/v1/history_state.proto

package chatpb

import (
	reflect "reflect"
	sync "sync"

	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// The history state for messages and spaces. Specifies how long messages and
// conversation threads are kept after creation.
type HistoryState int32

const (
	// Default value. Do not use.
	HistoryState_HISTORY_STATE_UNSPECIFIED HistoryState = 0
	// History off. [Messages and threads are kept for 24
	// hours](https://support.google.com/chat/answer/7664687).
	HistoryState_HISTORY_OFF HistoryState = 1
	// History on. The organization's [Vault retention
	// rules](https://support.google.com/vault/answer/7657597) specify for
	// how long messages and threads are kept.
	HistoryState_HISTORY_ON HistoryState = 2
)

// Enum value maps for HistoryState.
var (
	HistoryState_name = map[int32]string{
		0: "HISTORY_STATE_UNSPECIFIED",
		1: "HISTORY_OFF",
		2: "HISTORY_ON",
	}
	HistoryState_value = map[string]int32{
		"HISTORY_STATE_UNSPECIFIED": 0,
		"HISTORY_OFF":               1,
		"HISTORY_ON":                2,
	}
)

func (x HistoryState) Enum() *HistoryState {
	p := new(HistoryState)
	*p = x
	return p
}

func (x HistoryState) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (HistoryState) Descriptor() protoreflect.EnumDescriptor {
	return file_google_chat_v1_history_state_proto_enumTypes[0].Descriptor()
}

func (HistoryState) Type() protoreflect.EnumType {
	return &file_google_chat_v1_history_state_proto_enumTypes[0]
}

func (x HistoryState) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use HistoryState.Descriptor instead.
func (HistoryState) EnumDescriptor() ([]byte, []int) {
	return file_google_chat_v1_history_state_proto_rawDescGZIP(), []int{0}
}

var File_google_chat_v1_history_state_proto protoreflect.FileDescriptor

var file_google_chat_v1_history_state_proto_rawDesc = []byte{
	0x0a, 0x22, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2f, 0x76, 0x31,
	0x2f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x68, 0x61,
	0x74, 0x2e, 0x76, 0x31, 0x2a, 0x4e, 0x0a, 0x0c, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53,
	0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x52, 0x59, 0x5f,
	0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
	0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x4f,
	0x46, 0x46, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x52, 0x59, 0x5f,
	0x4f, 0x4e, 0x10, 0x02, 0x42, 0x9c, 0x01, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f,
	0x67, 0x6c, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x11, 0x48, 0x69, 0x73,
	0x74, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
	0x5a, 0x2c, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63,
	0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x76, 0x31,
	0x2f, 0x63, 0x68, 0x61, 0x74, 0x70, 0x62, 0x3b, 0x63, 0x68, 0x61, 0x74, 0x70, 0x62, 0xaa, 0x02,
	0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x73, 0x2e, 0x43, 0x68, 0x61,
	0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x5c, 0x41, 0x70,
	0x70, 0x73, 0x5c, 0x43, 0x68, 0x61, 0x74, 0x5c, 0x56, 0x31, 0xea, 0x02, 0x16, 0x47, 0x6f, 0x6f,
	0x67, 0x6c, 0x65, 0x3a, 0x3a, 0x41, 0x70, 0x70, 0x73, 0x3a, 0x3a, 0x43, 0x68, 0x61, 0x74, 0x3a,
	0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_google_chat_v1_history_state_proto_rawDescOnce sync.Once
	file_google_chat_v1_history_state_proto_rawDescData = file_google_chat_v1_history_state_proto_rawDesc
)

func file_google_chat_v1_history_state_proto_rawDescGZIP() []byte {
	file_google_chat_v1_history_state_proto_rawDescOnce.Do(func() {
		file_google_chat_v1_history_state_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_chat_v1_history_state_proto_rawDescData)
	})
	return file_google_chat_v1_history_state_proto_rawDescData
}

var file_google_chat_v1_history_state_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_google_chat_v1_history_state_proto_goTypes = []interface{}{
	(HistoryState)(0), // 0: google.chat.v1.HistoryState
}
var file_google_chat_v1_history_state_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_google_chat_v1_history_state_proto_init() }
func file_google_chat_v1_history_state_proto_init() {
	if File_google_chat_v1_history_state_proto != nil {
		return
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_google_chat_v1_history_state_proto_rawDesc,
			NumEnums:      1,
			NumMessages:   0,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_google_chat_v1_history_state_proto_goTypes,
		DependencyIndexes: file_google_chat_v1_history_state_proto_depIdxs,
		EnumInfos:         file_google_chat_v1_history_state_proto_enumTypes,
	}.Build()
	File_google_chat_v1_history_state_proto = out.File
	file_google_chat_v1_history_state_proto_rawDesc = nil
	file_google_chat_v1_history_state_proto_goTypes = nil
	file_google_chat_v1_history_state_proto_depIdxs = nil
}
