// Copyright 2024 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.26.0
// 	protoc        v4.24.4
// source: google/watcher/v1/watch.proto

package watcher

import (
	context "context"
	reflect "reflect"
	sync "sync"

	_ "google.golang.org/genproto/googleapis/api/annotations"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	anypb "google.golang.org/protobuf/types/known/anypb"
	_ "google.golang.org/protobuf/types/known/emptypb"
)

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)
)

// A reported value can be in one of the following states:
type Change_State int32

const (
	// The element exists and its full value is included in data.
	Change_EXISTS Change_State = 0
	// The element does not exist.
	Change_DOES_NOT_EXIST Change_State = 1
	// Element may or may not exist. Used only for initial state delivery when
	// the client is not interested in fetching the initial state. See the
	// "Initial State" section above.
	Change_INITIAL_STATE_SKIPPED Change_State = 2
	// The element may exist, but some error has occurred. More information is
	// available in the data field - the value is a serialized Status
	// proto (from [google.rpc.Status][])
	Change_ERROR Change_State = 3
)

// Enum value maps for Change_State.
var (
	Change_State_name = map[int32]string{
		0: "EXISTS",
		1: "DOES_NOT_EXIST",
		2: "INITIAL_STATE_SKIPPED",
		3: "ERROR",
	}
	Change_State_value = map[string]int32{
		"EXISTS":                0,
		"DOES_NOT_EXIST":        1,
		"INITIAL_STATE_SKIPPED": 2,
		"ERROR":                 3,
	}
)

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

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

func (Change_State) Descriptor() protoreflect.EnumDescriptor {
	return file_google_watcher_v1_watch_proto_enumTypes[0].Descriptor()
}

func (Change_State) Type() protoreflect.EnumType {
	return &file_google_watcher_v1_watch_proto_enumTypes[0]
}

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

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

// The message used by the client to register interest in an entity.
type Request struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// The `target` value **must** be a valid URL path pointing to an entity
	// to watch. Note that the service name **must** be
	// removed from the target field (e.g., the target field must say
	// "/foo/bar", not "myservice.googleapis.com/foo/bar"). A client is
	// also allowed to pass system-specific parameters in the URL that
	// are only obeyed by some implementations. Some parameters will be
	// implementation-specific. However, some have predefined meaning
	// and are listed here:
	//
	//   - recursive = true|false [default=false]
	//     If set to true, indicates that the client wants to watch all elements
	//     of entities in the subtree rooted at the entity's name in `target`. For
	//     descendants that are not the immediate children of the target, the
	//     `Change.element` will contain slashes.
	//
	//     Note that some namespaces and entities will not support recursive
	//     watching. When watching such an entity, a client must not set recursive
	//     to true. Otherwise, it will receive an `UNIMPLEMENTED` error.
	//
	// Normal URL encoding must be used inside `target`.  For example, if a query
	// parameter name or value, or the non-query parameter portion of `target`
	// contains a special character, it must be %-encoded.  We recommend that
	// clients and servers use their runtime's URL library to produce and consume
	// target values.
	Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"`
	// The `resume_marker` specifies how much of the existing underlying state is
	// delivered to the client when the watch request is received by the
	// system. The client can set this marker in one of the following ways to get
	// different semantics:
	//
	//   - Parameter is not specified or has the value "".
	//     Semantics: Fetch initial state.
	//     The client wants the entity's initial state to be delivered. See the
	//     description in "Initial State".
	//
	//   - Parameter is set to the string "now" (UTF-8 encoding).
	//     Semantics: Fetch new changes only.
	//     The client just wants to get the changes received by the system after
	//     the watch point. The system may deliver changes from before the watch
	//     point as well.
	//
	//   - Parameter is set to a value received in an earlier
	//     `Change.resume_marker` field while watching the same entity.
	//     Semantics: Resume from a specific point.
	//     The client wants to receive the changes from a specific point; this
	//     value must correspond to a value received in the `Change.resume_marker`
	//     field. The system may deliver changes from before the `resume_marker`
	//     as well. If the system cannot resume the stream from this point (e.g.,
	//     if it is too far behind in the stream), it can raise the
	//     `FAILED_PRECONDITION` error.
	//
	// An implementation MUST support an unspecified parameter and the
	// empty string "" marker (initial state fetching) and the "now" marker.
	// It need not support resuming from a specific point.
	ResumeMarker []byte `protobuf:"bytes,2,opt,name=resume_marker,json=resumeMarker,proto3" json:"resume_marker,omitempty"`
}

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

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

func (*Request) ProtoMessage() {}

func (x *Request) ProtoReflect() protoreflect.Message {
	mi := &file_google_watcher_v1_watch_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 Request.ProtoReflect.Descriptor instead.
func (*Request) Descriptor() ([]byte, []int) {
	return file_google_watcher_v1_watch_proto_rawDescGZIP(), []int{0}
}

func (x *Request) GetTarget() string {
	if x != nil {
		return x.Target
	}
	return ""
}

func (x *Request) GetResumeMarker() []byte {
	if x != nil {
		return x.ResumeMarker
	}
	return nil
}

// A batch of Change messages.
type ChangeBatch struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// A list of Change messages.
	Changes []*Change `protobuf:"bytes,1,rep,name=changes,proto3" json:"changes,omitempty"`
}

func (x *ChangeBatch) Reset() {
	*x = ChangeBatch{}
	if protoimpl.UnsafeEnabled {
		mi := &file_google_watcher_v1_watch_proto_msgTypes[1]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*ChangeBatch) ProtoMessage() {}

func (x *ChangeBatch) ProtoReflect() protoreflect.Message {
	mi := &file_google_watcher_v1_watch_proto_msgTypes[1]
	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 ChangeBatch.ProtoReflect.Descriptor instead.
func (*ChangeBatch) Descriptor() ([]byte, []int) {
	return file_google_watcher_v1_watch_proto_rawDescGZIP(), []int{1}
}

func (x *ChangeBatch) GetChanges() []*Change {
	if x != nil {
		return x.Changes
	}
	return nil
}

// A Change indicates the most recent state of an element.
type Change struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Name of the element, interpreted relative to the entity's actual
	// name. "" refers to the entity itself. The element name is a valid
	// UTF-8 string.
	Element string `protobuf:"bytes,1,opt,name=element,proto3" json:"element,omitempty"`
	// The state of the `element`.
	State Change_State `protobuf:"varint,2,opt,name=state,proto3,enum=google.watcher.v1.Change_State" json:"state,omitempty"`
	// The actual change data. This field is present only when `state() == EXISTS`
	// or `state() == ERROR`. Please see
	// [google.protobuf.Any][google.protobuf.Any] about how to use the Any type.
	Data *anypb.Any `protobuf:"bytes,6,opt,name=data,proto3" json:"data,omitempty"`
	// If present, provides a compact representation of all the messages that have
	// been received by the caller for the given entity, e.g., it could be a
	// sequence number or a multi-part timestamp/version vector. This marker can
	// be provided in the Request message, allowing the caller to resume the
	// stream watching at a specific point without fetching the initial state.
	ResumeMarker []byte `protobuf:"bytes,4,opt,name=resume_marker,json=resumeMarker,proto3" json:"resume_marker,omitempty"`
	// If true, this Change is followed by more Changes that are in the same group
	// as this Change.
	Continued bool `protobuf:"varint,5,opt,name=continued,proto3" json:"continued,omitempty"`
}

func (x *Change) Reset() {
	*x = Change{}
	if protoimpl.UnsafeEnabled {
		mi := &file_google_watcher_v1_watch_proto_msgTypes[2]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

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

func (*Change) ProtoMessage() {}

func (x *Change) ProtoReflect() protoreflect.Message {
	mi := &file_google_watcher_v1_watch_proto_msgTypes[2]
	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 Change.ProtoReflect.Descriptor instead.
func (*Change) Descriptor() ([]byte, []int) {
	return file_google_watcher_v1_watch_proto_rawDescGZIP(), []int{2}
}

func (x *Change) GetElement() string {
	if x != nil {
		return x.Element
	}
	return ""
}

func (x *Change) GetState() Change_State {
	if x != nil {
		return x.State
	}
	return Change_EXISTS
}

func (x *Change) GetData() *anypb.Any {
	if x != nil {
		return x.Data
	}
	return nil
}

func (x *Change) GetResumeMarker() []byte {
	if x != nil {
		return x.ResumeMarker
	}
	return nil
}

func (x *Change) GetContinued() bool {
	if x != nil {
		return x.Continued
	}
	return false
}

var File_google_watcher_v1_watch_proto protoreflect.FileDescriptor

var file_google_watcher_v1_watch_proto_rawDesc = []byte{
	0x0a, 0x1d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72,
	0x2f, 0x76, 0x31, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
	0x11, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e,
	0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61,
	0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
	0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
	0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f,
	0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70,
	0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x46, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75,
	0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20,
	0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x72,
	0x65, 0x73, 0x75, 0x6d, 0x65, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
	0x28, 0x0c, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x72,
	0x22, 0x42, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12,
	0x33, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
	0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65,
	0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x07, 0x63, 0x68, 0x61,
	0x6e, 0x67, 0x65, 0x73, 0x22, 0x95, 0x02, 0x0a, 0x06, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12,
	0x18, 0x0a, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
	0x52, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61,
	0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
	0x65, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61,
	0x6e, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
	0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
	0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65,
	0x73, 0x75, 0x6d, 0x65, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
	0x0c, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x72, 0x12,
	0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01,
	0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x64, 0x22, 0x4d, 0x0a,
	0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53,
	0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x4f, 0x45, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45,
	0x58, 0x49, 0x53, 0x54, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41,
	0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10,
	0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x32, 0x63, 0x0a, 0x07,
	0x57, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68,
	0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65,
	0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67,
	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31,
	0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x22, 0x11, 0x82, 0xd3,
	0xe4, 0x93, 0x02, 0x0b, 0x12, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30,
	0x01, 0x42, 0x5f, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
	0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x57, 0x61, 0x74, 0x63,
	0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x38, 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,
	0x77, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x77, 0x61, 0x74, 0x63, 0x68,
	0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_google_watcher_v1_watch_proto_rawDescOnce sync.Once
	file_google_watcher_v1_watch_proto_rawDescData = file_google_watcher_v1_watch_proto_rawDesc
)

func file_google_watcher_v1_watch_proto_rawDescGZIP() []byte {
	file_google_watcher_v1_watch_proto_rawDescOnce.Do(func() {
		file_google_watcher_v1_watch_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_watcher_v1_watch_proto_rawDescData)
	})
	return file_google_watcher_v1_watch_proto_rawDescData
}

var file_google_watcher_v1_watch_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_google_watcher_v1_watch_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_google_watcher_v1_watch_proto_goTypes = []interface{}{
	(Change_State)(0),   // 0: google.watcher.v1.Change.State
	(*Request)(nil),     // 1: google.watcher.v1.Request
	(*ChangeBatch)(nil), // 2: google.watcher.v1.ChangeBatch
	(*Change)(nil),      // 3: google.watcher.v1.Change
	(*anypb.Any)(nil),   // 4: google.protobuf.Any
}
var file_google_watcher_v1_watch_proto_depIdxs = []int32{
	3, // 0: google.watcher.v1.ChangeBatch.changes:type_name -> google.watcher.v1.Change
	0, // 1: google.watcher.v1.Change.state:type_name -> google.watcher.v1.Change.State
	4, // 2: google.watcher.v1.Change.data:type_name -> google.protobuf.Any
	1, // 3: google.watcher.v1.Watcher.Watch:input_type -> google.watcher.v1.Request
	2, // 4: google.watcher.v1.Watcher.Watch:output_type -> google.watcher.v1.ChangeBatch
	4, // [4:5] is the sub-list for method output_type
	3, // [3:4] is the sub-list for method input_type
	3, // [3:3] is the sub-list for extension type_name
	3, // [3:3] is the sub-list for extension extendee
	0, // [0:3] is the sub-list for field type_name
}

func init() { file_google_watcher_v1_watch_proto_init() }
func file_google_watcher_v1_watch_proto_init() {
	if File_google_watcher_v1_watch_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_google_watcher_v1_watch_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Request); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_google_watcher_v1_watch_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*ChangeBatch); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_google_watcher_v1_watch_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Change); 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_watcher_v1_watch_proto_rawDesc,
			NumEnums:      1,
			NumMessages:   3,
			NumExtensions: 0,
			NumServices:   1,
		},
		GoTypes:           file_google_watcher_v1_watch_proto_goTypes,
		DependencyIndexes: file_google_watcher_v1_watch_proto_depIdxs,
		EnumInfos:         file_google_watcher_v1_watch_proto_enumTypes,
		MessageInfos:      file_google_watcher_v1_watch_proto_msgTypes,
	}.Build()
	File_google_watcher_v1_watch_proto = out.File
	file_google_watcher_v1_watch_proto_rawDesc = nil
	file_google_watcher_v1_watch_proto_goTypes = nil
	file_google_watcher_v1_watch_proto_depIdxs = nil
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6

// WatcherClient is the client API for Watcher service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type WatcherClient interface {
	// Start a streaming RPC to get watch information from the server.
	Watch(ctx context.Context, in *Request, opts ...grpc.CallOption) (Watcher_WatchClient, error)
}

type watcherClient struct {
	cc grpc.ClientConnInterface
}

func NewWatcherClient(cc grpc.ClientConnInterface) WatcherClient {
	return &watcherClient{cc}
}

func (c *watcherClient) Watch(ctx context.Context, in *Request, opts ...grpc.CallOption) (Watcher_WatchClient, error) {
	stream, err := c.cc.NewStream(ctx, &_Watcher_serviceDesc.Streams[0], "/google.watcher.v1.Watcher/Watch", opts...)
	if err != nil {
		return nil, err
	}
	x := &watcherWatchClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type Watcher_WatchClient interface {
	Recv() (*ChangeBatch, error)
	grpc.ClientStream
}

type watcherWatchClient struct {
	grpc.ClientStream
}

func (x *watcherWatchClient) Recv() (*ChangeBatch, error) {
	m := new(ChangeBatch)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// WatcherServer is the server API for Watcher service.
type WatcherServer interface {
	// Start a streaming RPC to get watch information from the server.
	Watch(*Request, Watcher_WatchServer) error
}

// UnimplementedWatcherServer can be embedded to have forward compatible implementations.
type UnimplementedWatcherServer struct {
}

func (*UnimplementedWatcherServer) Watch(*Request, Watcher_WatchServer) error {
	return status.Errorf(codes.Unimplemented, "method Watch not implemented")
}

func RegisterWatcherServer(s *grpc.Server, srv WatcherServer) {
	s.RegisterService(&_Watcher_serviceDesc, srv)
}

func _Watcher_Watch_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(Request)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(WatcherServer).Watch(m, &watcherWatchServer{stream})
}

type Watcher_WatchServer interface {
	Send(*ChangeBatch) error
	grpc.ServerStream
}

type watcherWatchServer struct {
	grpc.ServerStream
}

func (x *watcherWatchServer) Send(m *ChangeBatch) error {
	return x.ServerStream.SendMsg(m)
}

var _Watcher_serviceDesc = grpc.ServiceDesc{
	ServiceName: "google.watcher.v1.Watcher",
	HandlerType: (*WatcherServer)(nil),
	Methods:     []grpc.MethodDesc{},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "Watch",
			Handler:       _Watcher_Watch_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "google/watcher/v1/watch.proto",
}
