// Copyright 2019 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.22.0
// 	protoc        v3.12.2
// source: google/type/timeofday.proto

package timeofday

import (
	reflect "reflect"
	sync "sync"

	proto "github.com/golang/protobuf/proto"
	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)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

// Represents a time of day. The date and time zone are either not significant
// or are specified elsewhere. An API may choose to allow leap seconds. Related
// types are [google.type.Date][google.type.Date] and `google.protobuf.Timestamp`.
type TimeOfDay struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Hours of day in 24 hour format. Should be from 0 to 23. An API may choose
	// to allow the value "24:00:00" for scenarios like business closing time.
	Hours int32 `protobuf:"varint,1,opt,name=hours,proto3" json:"hours,omitempty"`
	// Minutes of hour of day. Must be from 0 to 59.
	Minutes int32 `protobuf:"varint,2,opt,name=minutes,proto3" json:"minutes,omitempty"`
	// Seconds of minutes of the time. Must normally be from 0 to 59. An API may
	// allow the value 60 if it allows leap-seconds.
	Seconds int32 `protobuf:"varint,3,opt,name=seconds,proto3" json:"seconds,omitempty"`
	// Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999.
	Nanos int32 `protobuf:"varint,4,opt,name=nanos,proto3" json:"nanos,omitempty"`
}

func (x *TimeOfDay) Reset() {
	*x = TimeOfDay{}
	if protoimpl.UnsafeEnabled {
		mi := &file_google_type_timeofday_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *TimeOfDay) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*TimeOfDay) ProtoMessage() {}

func (x *TimeOfDay) ProtoReflect() protoreflect.Message {
	mi := &file_google_type_timeofday_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use TimeOfDay.ProtoReflect.Descriptor instead.
func (*TimeOfDay) Descriptor() ([]byte, []int) {
	return file_google_type_timeofday_proto_rawDescGZIP(), []int{0}
}

func (x *TimeOfDay) GetHours() int32 {
	if x != nil {
		return x.Hours
	}
	return 0
}

func (x *TimeOfDay) GetMinutes() int32 {
	if x != nil {
		return x.Minutes
	}
	return 0
}

func (x *TimeOfDay) GetSeconds() int32 {
	if x != nil {
		return x.Seconds
	}
	return 0
}

func (x *TimeOfDay) GetNanos() int32 {
	if x != nil {
		return x.Nanos
	}
	return 0
}

var File_google_type_timeofday_proto protoreflect.FileDescriptor

var file_google_type_timeofday_proto_rawDesc = []byte{
	0x0a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x74, 0x69,
	0x6d, 0x65, 0x6f, 0x66, 0x64, 0x61, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x67,
	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x54, 0x69,
	0x6d, 0x65, 0x4f, 0x66, 0x44, 0x61, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x68, 0x6f, 0x75, 0x72, 0x73,
	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x12, 0x18, 0x0a,
	0x07, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07,
	0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e,
	0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64,
	0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
	0x52, 0x05, 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x42, 0x6c, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x67,
	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x42, 0x0e, 0x54, 0x69, 0x6d, 0x65,
	0x4f, 0x66, 0x44, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x6f,
	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f,
	0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61,
	0x70, 0x69, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x66, 0x64,
	0x61, 0x79, 0x3b, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x66, 0x64, 0x61, 0x79, 0xf8, 0x01, 0x01, 0xa2,
	0x02, 0x03, 0x47, 0x54, 0x50, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_google_type_timeofday_proto_rawDescOnce sync.Once
	file_google_type_timeofday_proto_rawDescData = file_google_type_timeofday_proto_rawDesc
)

func file_google_type_timeofday_proto_rawDescGZIP() []byte {
	file_google_type_timeofday_proto_rawDescOnce.Do(func() {
		file_google_type_timeofday_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_type_timeofday_proto_rawDescData)
	})
	return file_google_type_timeofday_proto_rawDescData
}

var file_google_type_timeofday_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_google_type_timeofday_proto_goTypes = []interface{}{
	(*TimeOfDay)(nil), // 0: google.type.TimeOfDay
}
var file_google_type_timeofday_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_type_timeofday_proto_init() }
func file_google_type_timeofday_proto_init() {
	if File_google_type_timeofday_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_google_type_timeofday_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*TimeOfDay); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_google_type_timeofday_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_google_type_timeofday_proto_goTypes,
		DependencyIndexes: file_google_type_timeofday_proto_depIdxs,
		MessageInfos:      file_google_type_timeofday_proto_msgTypes,
	}.Build()
	File_google_type_timeofday_proto = out.File
	file_google_type_timeofday_proto_rawDesc = nil
	file_google_type_timeofday_proto_goTypes = nil
	file_google_type_timeofday_proto_depIdxs = nil
}
