// Code generated by protoc-gen-go.
// source: rpcreplay.proto
// DO NOT EDIT!

/*
Package rpcreplay is a generated protocol buffer package.

It is generated from these files:
	rpcreplay.proto

It has these top-level messages:
	Entry
*/
package rpcreplay

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/any"

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type Entry_Kind int32

const (
	Entry_TYPE_UNSPECIFIED Entry_Kind = 0
	// A unary request.
	// method: the full name of the method
	// message: the request proto
	// is_error: false
	// ref_index: 0
	Entry_REQUEST Entry_Kind = 1
	// A unary response.
	// method: the full name of the method
	// message:
	//   if is_error: a google.rpc.Status proto
	//   else:        the response proto
	// ref_index: index in the sequence of Entries of matching request (1-based)
	Entry_RESPONSE Entry_Kind = 2
	// A method that creates a stream.
	// method: the full name of the method
	// message:
	//   if is_error: a google.rpc.Status proto
	//   else:        nil
	// ref_index: 0
	Entry_CREATE_STREAM Entry_Kind = 3
	// A call to Send on the client returned by a stream-creating method.
	// method: unset
	// message: the proto being sent
	// is_error: false
	// ref_index: index of matching CREATE_STREAM entry (1-based)
	Entry_SEND Entry_Kind = 4
	// A call to Recv on the client returned by a stream-creating method.
	// method: unset
	// message:
	//   if is_error: a google.rpc.Status proto, or nil on EOF
	//   else:        the received message
	// ref_index: index of matching CREATE_STREAM entry
	Entry_RECV Entry_Kind = 5
)

var Entry_Kind_name = map[int32]string{
	0: "TYPE_UNSPECIFIED",
	1: "REQUEST",
	2: "RESPONSE",
	3: "CREATE_STREAM",
	4: "SEND",
	5: "RECV",
}
var Entry_Kind_value = map[string]int32{
	"TYPE_UNSPECIFIED": 0,
	"REQUEST":          1,
	"RESPONSE":         2,
	"CREATE_STREAM":    3,
	"SEND":             4,
	"RECV":             5,
}

func (x Entry_Kind) String() string {
	return proto.EnumName(Entry_Kind_name, int32(x))
}
func (Entry_Kind) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} }

// An Entry represents a single RPC activity, typically a request or response.
type Entry struct {
	Kind     Entry_Kind           `protobuf:"varint,1,opt,name=kind,enum=rpcreplay.Entry_Kind" json:"kind,omitempty"`
	Method   string               `protobuf:"bytes,2,opt,name=method" json:"method,omitempty"`
	Message  *google_protobuf.Any `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"`
	IsError  bool                 `protobuf:"varint,4,opt,name=is_error,json=isError" json:"is_error,omitempty"`
	RefIndex int32                `protobuf:"varint,5,opt,name=ref_index,json=refIndex" json:"ref_index,omitempty"`
}

func (m *Entry) Reset()                    { *m = Entry{} }
func (m *Entry) String() string            { return proto.CompactTextString(m) }
func (*Entry) ProtoMessage()               {}
func (*Entry) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

func (m *Entry) GetKind() Entry_Kind {
	if m != nil {
		return m.Kind
	}
	return Entry_TYPE_UNSPECIFIED
}

func (m *Entry) GetMethod() string {
	if m != nil {
		return m.Method
	}
	return ""
}

func (m *Entry) GetMessage() *google_protobuf.Any {
	if m != nil {
		return m.Message
	}
	return nil
}

func (m *Entry) GetIsError() bool {
	if m != nil {
		return m.IsError
	}
	return false
}

func (m *Entry) GetRefIndex() int32 {
	if m != nil {
		return m.RefIndex
	}
	return 0
}

func init() {
	proto.RegisterType((*Entry)(nil), "rpcreplay.Entry")
	proto.RegisterEnum("rpcreplay.Entry_Kind", Entry_Kind_name, Entry_Kind_value)
}

func init() { proto.RegisterFile("rpcreplay.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
	// 289 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x44, 0x8e, 0xdf, 0x4e, 0xc2, 0x30,
	0x14, 0xc6, 0x2d, 0x6c, 0x30, 0x0e, 0xfe, 0xa9, 0x0d, 0x9a, 0xa1, 0x37, 0x0b, 0x57, 0xf3, 0xa6,
	0x24, 0xf8, 0x04, 0x04, 0x8e, 0x09, 0x31, 0x22, 0xb6, 0xc3, 0xc4, 0x1b, 0x17, 0x70, 0x05, 0x17,
	0xa1, 0x25, 0xdd, 0x4c, 0xdc, 0x6b, 0xf8, 0xc4, 0x66, 0x13, 0xf4, 0xae, 0xbf, 0x7e, 0xbf, 0x9c,
	0xef, 0x83, 0x33, 0xbb, 0x7b, 0xb3, 0x6a, 0xb7, 0x59, 0x14, 0x7c, 0x67, 0x4d, 0x6e, 0x58, 0xeb,
	0xef, 0xe3, 0xaa, 0xbb, 0x36, 0x66, 0xbd, 0x51, 0xfd, 0x2a, 0x58, 0x7e, 0xae, 0xfa, 0x0b, 0xbd,
	0xb7, 0x7a, 0xdf, 0x35, 0x70, 0x51, 0xe7, 0xb6, 0x60, 0x37, 0xe0, 0x7c, 0xa4, 0x3a, 0xf1, 0x49,
	0x40, 0xc2, 0xd3, 0xc1, 0x05, 0xff, 0xbf, 0x57, 0xe5, 0xfc, 0x3e, 0xd5, 0x89, 0xa8, 0x14, 0x76,
	0x09, 0x8d, 0xad, 0xca, 0xdf, 0x4d, 0xe2, 0xd7, 0x02, 0x12, 0xb6, 0xc4, 0x9e, 0x18, 0x87, 0xe6,
	0x56, 0x65, 0xd9, 0x62, 0xad, 0xfc, 0x7a, 0x40, 0xc2, 0xf6, 0xa0, 0xc3, 0x7f, 0x9b, 0xf9, 0xa1,
	0x99, 0x0f, 0x75, 0x21, 0x0e, 0x12, 0xeb, 0x82, 0x97, 0x66, 0xb1, 0xb2, 0xd6, 0x58, 0xdf, 0x09,
	0x48, 0xe8, 0x89, 0x66, 0x9a, 0x61, 0x89, 0xec, 0x1a, 0x5a, 0x56, 0xad, 0xe2, 0x54, 0x27, 0xea,
	0xcb, 0x77, 0x03, 0x12, 0xba, 0xc2, 0xb3, 0x6a, 0x35, 0x29, 0xb9, 0xf7, 0x0a, 0x4e, 0xb9, 0x86,
	0x75, 0x80, 0x46, 0x2f, 0x33, 0x8c, 0xe7, 0x53, 0x39, 0xc3, 0xd1, 0xe4, 0x6e, 0x82, 0x63, 0x7a,
	0xc4, 0xda, 0xd0, 0x14, 0xf8, 0x34, 0x47, 0x19, 0x51, 0xc2, 0x8e, 0xc1, 0x13, 0x28, 0x67, 0x8f,
	0x53, 0x89, 0xb4, 0xc6, 0xce, 0xe1, 0x64, 0x24, 0x70, 0x18, 0x61, 0x2c, 0x23, 0x81, 0xc3, 0x07,
	0x5a, 0x67, 0x1e, 0x38, 0x12, 0xa7, 0x63, 0xea, 0x94, 0x2f, 0x81, 0xa3, 0x67, 0xea, 0x2e, 0x1b,
	0xd5, 0xdc, 0xdb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe7, 0x9b, 0x9d, 0x4f, 0x54, 0x01, 0x00,
	0x00,
}
