diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml new file mode 100644 index 0000000..868873e --- /dev/null +++ b/.github/workflows/go.yaml @@ -0,0 +1,67 @@ +name: Go + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.20' + cache-dependency-path: go.sum + + - name: Build + run: go build -o ./bin/ -v ./... + + - name: Test + run: go test -v ./... + + linter: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: '1.20' + cache: false + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Require: The version of golangci-lint to use. + # When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version. + # When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. + version: v1.53 + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # + # Note: By default, the `.golangci.yml` file should be at the root of the repository. + # The location of the configuration file can be changed by using `--config=` + args: --timeout=30m --config=./.golangci.pipeline.yaml --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true, then all caching functionality will be completely disabled, + # takes precedence over all other caching options. + # skip-cache: true + + # Optional: if set to true, then the action won't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true, then the action won't cache or restore ~/.cache/go-build. + # skip-build-cache: true + + # Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'. + # install-mode: "goinstall" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3a1ebf --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +/bin/ \ No newline at end of file diff --git a/.golangci.pipeline.yaml b/.golangci.pipeline.yaml new file mode 100644 index 0000000..e69de29 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..da95a52 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +LOCAL_BIN:=$(CURDIR)/bin + +install-golangci-lint: + GOBIN=$(LOCAL_BIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.53.3 + +lint: + GOBIN=$(LOCAL_BIN) golangci-lint run ./... --config .golangci.pipeline.yaml + +install-deps: + GOBIN=$(LOCAL_BIN) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 + GOBIN=$(LOCAL_BIN) go install -mod=mod google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 + +get-deps: + go get -u google.golang.org/protobuf/cmd/protoc-gen-go + go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc + + +generate: + make generate-chat-api + +generate-chat-api: + mkdir -p pkg/chat_v1 + protoc --proto_path api/chat_v1 \ + --go_out=pkg/chat_v1 --go_opt=paths=source_relative \ + --plugin=protoc-gen-go=bin/protoc-gen-go \ + --go-grpc_out=pkg/chat_v1 --go-grpc_opt=paths=source_relative \ + --plugin=protoc-gen-go-grpc=bin/protoc-gen-go-grpc \ + api/chat_v1/chat_api.proto \ No newline at end of file diff --git a/api/chat_v1/chat_api.proto b/api/chat_v1/chat_api.proto new file mode 100644 index 0000000..445f603 --- /dev/null +++ b/api/chat_v1/chat_api.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; + +package chat_v1; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/empty.proto"; + +option go_package = "github.com/AndreiMartynenko/chat-server/grpc/pkg/chat_v1;chat_v1"; + +service ChatAPIServices { + rpc Create (CreateNewChatRequest) returns (CreateNewChatResponse); + rpc Delete (DeleteChatRequest) returns (DeleteChatResponse); + rpc SendMessage (SendMessageRequest) returns (SendMessageResponse); +} + +// Create NewChat Request +message CreateNewChatRequest { + repeated string usernames = 1; +} + +// Create NewChat Response +message CreateNewChatResponse { + int64 id = 1; +} + +// Delete Chat Request +message DeleteChatRequest { + int64 id = 1; +} + +message DeleteChatResponse { + google.protobuf.Empty delete_response = 1; +} + +// SendMessage Request +message SendMessageRequest { + string from = 1; + string text = 2; + google.protobuf.Timestamp timestamp = 3; +} + +// SendMessage Response +message SendMessageResponse { + google.protobuf.Empty send_message_response = 1; +} + diff --git a/cmd/grpc_client/main.go b/cmd/grpc_client/main.go new file mode 100644 index 0000000..2e6f8a4 --- /dev/null +++ b/cmd/grpc_client/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "context" + "log" + "time" + + "github.com/AndreiMartynenko/chat-server/pkg/chat_v1" + "github.com/fatih/color" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + address = "localhost:50051" +) + +var usernames = []string{"Bill", "Jack"} + +func main() { + conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + log.Fatalf("failed toconnect to server: %v", err) + } + defer conn.Close() + + c := chat_v1.NewChatAPIServicesClient(conn) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + r, err := c.Create(ctx, &chat_v1.CreateNewChatRequest{Usernames: usernames}) + if err != nil { + log.Fatalf("failed to get user by id: %v", err) + } + log.Printf("New chat created with ID: %d", r.Id) + log.Printf(color.RedString("chat info: \n"), color.GreenString("%+v", r.Id)) + +} diff --git a/cmd/grpc_server/main.go b/cmd/grpc_server/main.go new file mode 100644 index 0000000..f40eb6e --- /dev/null +++ b/cmd/grpc_server/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "context" + "fmt" + "log" + "net" + + "github.com/AndreiMartynenko/chat-server/pkg/chat_v1" + "github.com/brianvoe/gofakeit" + "github.com/golang/protobuf/ptypes/empty" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" +) + +const grpcPort = 50051 + +type server struct { + chat_v1.UnimplementedChatAPIServicesServer +} + +func (srv *server) Create(ctx context.Context, req *chat_v1.CreateNewChatRequest) (*chat_v1.CreateNewChatResponse, error) { + log.Printf("Create New Chat request received: %v", req) + + //For testing purposes + // response := &chat_v1.CreateNewChatResponse{ + // Id: 1345, + // } + // return response, nil + return &chat_v1.CreateNewChatResponse{ + Id: gofakeit.Int64(), + }, nil + +} + +func (srv *server) Delete(ctx context.Context, req *chat_v1.DeleteChatRequest) (*chat_v1.DeleteChatResponse, error) { + log.Printf("Delete Chat request received: %v", req) + + return &chat_v1.DeleteChatResponse{DeleteResponse: &empty.Empty{}}, nil + +} + +func (srv *server) SendMessage(ctx context.Context, req *chat_v1.SendMessageRequest) (*chat_v1.SendMessageResponse, error) { + log.Printf("SendMessageRequest received: %v", req) + + return &chat_v1.SendMessageResponse{SendMessageResponse: &empty.Empty{}}, nil +} + +func main() { + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", grpcPort)) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + + srv := grpc.NewServer() + + /* + Reflection in this context allows gRPC clients to query information + about the gRPC server's services dynamically at runtime. + It enables tools like gRPC's command-line interface (grpc_cli) + and gRPC's web-based GUI (grpcui) to inspect the server's + services and make RPC calls without needing to know + the specifics of each service beforehand. + */ + reflection.Register(srv) + chat_v1.RegisterChatAPIServicesServer(srv, &server{}) + + log.Printf("server listening at %v", lis.Addr()) + + if err = srv.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } + +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..63eb5bf --- /dev/null +++ b/go.mod @@ -0,0 +1,20 @@ +module github.com/AndreiMartynenko/chat-server + +go 1.20 + +require ( + github.com/brianvoe/gofakeit v3.18.0+incompatible + github.com/fatih/color v1.16.0 + github.com/golang/protobuf v1.5.3 + google.golang.org/grpc v1.61.1 + google.golang.org/protobuf v1.32.0 +) + +require ( + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/net v0.18.0 // indirect + golang.org/x/sys v0.14.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..12bf634 --- /dev/null +++ b/go.sum @@ -0,0 +1,31 @@ +github.com/brianvoe/gofakeit v3.18.0+incompatible h1:wDOmHc9DLG4nRjUVVaxA+CEglKOW72Y5+4WNxUIkjM8= +github.com/brianvoe/gofakeit v3.18.0+incompatible/go.mod h1:kfwdRA90vvNhPutZWfH7WPaDzUjz+CZFqG+rPkOjGOc= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= diff --git a/pkg/chat_v1/chat_api.pb.go b/pkg/chat_v1/chat_api.pb.go new file mode 100644 index 0000000..8c9b024 --- /dev/null +++ b/pkg/chat_v1/chat_api.pb.go @@ -0,0 +1,523 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v4.25.2 +// source: chat_api.proto + +package chat_v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +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) +) + +// Create NewChat Request +type CreateNewChatRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Usernames []string `protobuf:"bytes,1,rep,name=usernames,proto3" json:"usernames,omitempty"` +} + +func (x *CreateNewChatRequest) Reset() { + *x = CreateNewChatRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNewChatRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNewChatRequest) ProtoMessage() {} + +func (x *CreateNewChatRequest) ProtoReflect() protoreflect.Message { + mi := &file_chat_api_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 CreateNewChatRequest.ProtoReflect.Descriptor instead. +func (*CreateNewChatRequest) Descriptor() ([]byte, []int) { + return file_chat_api_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateNewChatRequest) GetUsernames() []string { + if x != nil { + return x.Usernames + } + return nil +} + +// Create NewChat Response +type CreateNewChatResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *CreateNewChatResponse) Reset() { + *x = CreateNewChatResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateNewChatResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateNewChatResponse) ProtoMessage() {} + +func (x *CreateNewChatResponse) ProtoReflect() protoreflect.Message { + mi := &file_chat_api_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 CreateNewChatResponse.ProtoReflect.Descriptor instead. +func (*CreateNewChatResponse) Descriptor() ([]byte, []int) { + return file_chat_api_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateNewChatResponse) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +// Delete Chat Request +type DeleteChatRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteChatRequest) Reset() { + *x = DeleteChatRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteChatRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteChatRequest) ProtoMessage() {} + +func (x *DeleteChatRequest) ProtoReflect() protoreflect.Message { + mi := &file_chat_api_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 DeleteChatRequest.ProtoReflect.Descriptor instead. +func (*DeleteChatRequest) Descriptor() ([]byte, []int) { + return file_chat_api_proto_rawDescGZIP(), []int{2} +} + +func (x *DeleteChatRequest) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type DeleteChatResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeleteResponse *emptypb.Empty `protobuf:"bytes,1,opt,name=delete_response,json=deleteResponse,proto3" json:"delete_response,omitempty"` +} + +func (x *DeleteChatResponse) Reset() { + *x = DeleteChatResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteChatResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteChatResponse) ProtoMessage() {} + +func (x *DeleteChatResponse) ProtoReflect() protoreflect.Message { + mi := &file_chat_api_proto_msgTypes[3] + 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 DeleteChatResponse.ProtoReflect.Descriptor instead. +func (*DeleteChatResponse) Descriptor() ([]byte, []int) { + return file_chat_api_proto_rawDescGZIP(), []int{3} +} + +func (x *DeleteChatResponse) GetDeleteResponse() *emptypb.Empty { + if x != nil { + return x.DeleteResponse + } + return nil +} + +// SendMessage Request +type SendMessageRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` + Text string `protobuf:"bytes,2,opt,name=text,proto3" json:"text,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (x *SendMessageRequest) Reset() { + *x = SendMessageRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendMessageRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendMessageRequest) ProtoMessage() {} + +func (x *SendMessageRequest) ProtoReflect() protoreflect.Message { + mi := &file_chat_api_proto_msgTypes[4] + 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 SendMessageRequest.ProtoReflect.Descriptor instead. +func (*SendMessageRequest) Descriptor() ([]byte, []int) { + return file_chat_api_proto_rawDescGZIP(), []int{4} +} + +func (x *SendMessageRequest) GetFrom() string { + if x != nil { + return x.From + } + return "" +} + +func (x *SendMessageRequest) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +func (x *SendMessageRequest) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +// SendMessage Response +type SendMessageResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SendMessageResponse *emptypb.Empty `protobuf:"bytes,1,opt,name=send_message_response,json=sendMessageResponse,proto3" json:"send_message_response,omitempty"` +} + +func (x *SendMessageResponse) Reset() { + *x = SendMessageResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_chat_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendMessageResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendMessageResponse) ProtoMessage() {} + +func (x *SendMessageResponse) ProtoReflect() protoreflect.Message { + mi := &file_chat_api_proto_msgTypes[5] + 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 SendMessageResponse.ProtoReflect.Descriptor instead. +func (*SendMessageResponse) Descriptor() ([]byte, []int) { + return file_chat_api_proto_rawDescGZIP(), []int{5} +} + +func (x *SendMessageResponse) GetSendMessageResponse() *emptypb.Empty { + if x != nil { + return x.SendMessageResponse + } + return nil +} + +var File_chat_api_proto protoreflect.FileDescriptor + +var file_chat_api_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x07, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 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, 0x34, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x4e, 0x65, 0x77, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x27, 0x0a, + 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x23, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x55, 0x0a, 0x12, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3f, 0x0a, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x52, 0x0e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x76, 0x0a, 0x12, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, + 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x61, 0x0a, 0x13, 0x53, 0x65, + 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x4a, 0x0a, 0x15, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x13, 0x73, 0x65, 0x6e, 0x64, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe7, 0x01, + 0x0a, 0x0f, 0x43, 0x68, 0x61, 0x74, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x12, 0x47, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x63, 0x68, + 0x61, 0x74, 0x5f, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x43, + 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x68, 0x61, + 0x74, 0x5f, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x65, 0x77, 0x43, 0x68, + 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, + 0x0b, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x2e, 0x63, + 0x68, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x63, 0x68, 0x61, 0x74, + 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x6e, 0x64, 0x72, 0x65, 0x69, 0x4d, 0x61, 0x72, 0x74, + 0x79, 0x6e, 0x65, 0x6e, 0x6b, 0x6f, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x63, 0x68, 0x61, 0x74, + 0x5f, 0x76, 0x31, 0x3b, 0x63, 0x68, 0x61, 0x74, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_chat_api_proto_rawDescOnce sync.Once + file_chat_api_proto_rawDescData = file_chat_api_proto_rawDesc +) + +func file_chat_api_proto_rawDescGZIP() []byte { + file_chat_api_proto_rawDescOnce.Do(func() { + file_chat_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_chat_api_proto_rawDescData) + }) + return file_chat_api_proto_rawDescData +} + +var file_chat_api_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_chat_api_proto_goTypes = []interface{}{ + (*CreateNewChatRequest)(nil), // 0: chat_v1.CreateNewChatRequest + (*CreateNewChatResponse)(nil), // 1: chat_v1.CreateNewChatResponse + (*DeleteChatRequest)(nil), // 2: chat_v1.DeleteChatRequest + (*DeleteChatResponse)(nil), // 3: chat_v1.DeleteChatResponse + (*SendMessageRequest)(nil), // 4: chat_v1.SendMessageRequest + (*SendMessageResponse)(nil), // 5: chat_v1.SendMessageResponse + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp +} +var file_chat_api_proto_depIdxs = []int32{ + 6, // 0: chat_v1.DeleteChatResponse.delete_response:type_name -> google.protobuf.Empty + 7, // 1: chat_v1.SendMessageRequest.timestamp:type_name -> google.protobuf.Timestamp + 6, // 2: chat_v1.SendMessageResponse.send_message_response:type_name -> google.protobuf.Empty + 0, // 3: chat_v1.ChatAPIServices.Create:input_type -> chat_v1.CreateNewChatRequest + 2, // 4: chat_v1.ChatAPIServices.Delete:input_type -> chat_v1.DeleteChatRequest + 4, // 5: chat_v1.ChatAPIServices.SendMessage:input_type -> chat_v1.SendMessageRequest + 1, // 6: chat_v1.ChatAPIServices.Create:output_type -> chat_v1.CreateNewChatResponse + 3, // 7: chat_v1.ChatAPIServices.Delete:output_type -> chat_v1.DeleteChatResponse + 5, // 8: chat_v1.ChatAPIServices.SendMessage:output_type -> chat_v1.SendMessageResponse + 6, // [6:9] is the sub-list for method output_type + 3, // [3:6] 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_chat_api_proto_init() } +func file_chat_api_proto_init() { + if File_chat_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_chat_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNewChatRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateNewChatResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteChatRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteChatResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendMessageRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_chat_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendMessageResponse); 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_chat_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_chat_api_proto_goTypes, + DependencyIndexes: file_chat_api_proto_depIdxs, + MessageInfos: file_chat_api_proto_msgTypes, + }.Build() + File_chat_api_proto = out.File + file_chat_api_proto_rawDesc = nil + file_chat_api_proto_goTypes = nil + file_chat_api_proto_depIdxs = nil +} diff --git a/pkg/chat_v1/chat_api_grpc.pb.go b/pkg/chat_v1/chat_api_grpc.pb.go new file mode 100644 index 0000000..9bf820c --- /dev/null +++ b/pkg/chat_v1/chat_api_grpc.pb.go @@ -0,0 +1,177 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v4.25.2 +// source: chat_api.proto + +package chat_v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ChatAPIServicesClient is the client API for ChatAPIServices service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ChatAPIServicesClient interface { + Create(ctx context.Context, in *CreateNewChatRequest, opts ...grpc.CallOption) (*CreateNewChatResponse, error) + Delete(ctx context.Context, in *DeleteChatRequest, opts ...grpc.CallOption) (*DeleteChatResponse, error) + SendMessage(ctx context.Context, in *SendMessageRequest, opts ...grpc.CallOption) (*SendMessageResponse, error) +} + +type chatAPIServicesClient struct { + cc grpc.ClientConnInterface +} + +func NewChatAPIServicesClient(cc grpc.ClientConnInterface) ChatAPIServicesClient { + return &chatAPIServicesClient{cc} +} + +func (c *chatAPIServicesClient) Create(ctx context.Context, in *CreateNewChatRequest, opts ...grpc.CallOption) (*CreateNewChatResponse, error) { + out := new(CreateNewChatResponse) + err := c.cc.Invoke(ctx, "/chat_v1.ChatAPIServices/Create", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *chatAPIServicesClient) Delete(ctx context.Context, in *DeleteChatRequest, opts ...grpc.CallOption) (*DeleteChatResponse, error) { + out := new(DeleteChatResponse) + err := c.cc.Invoke(ctx, "/chat_v1.ChatAPIServices/Delete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *chatAPIServicesClient) SendMessage(ctx context.Context, in *SendMessageRequest, opts ...grpc.CallOption) (*SendMessageResponse, error) { + out := new(SendMessageResponse) + err := c.cc.Invoke(ctx, "/chat_v1.ChatAPIServices/SendMessage", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ChatAPIServicesServer is the server API for ChatAPIServices service. +// All implementations must embed UnimplementedChatAPIServicesServer +// for forward compatibility +type ChatAPIServicesServer interface { + Create(context.Context, *CreateNewChatRequest) (*CreateNewChatResponse, error) + Delete(context.Context, *DeleteChatRequest) (*DeleteChatResponse, error) + SendMessage(context.Context, *SendMessageRequest) (*SendMessageResponse, error) + mustEmbedUnimplementedChatAPIServicesServer() +} + +// UnimplementedChatAPIServicesServer must be embedded to have forward compatible implementations. +type UnimplementedChatAPIServicesServer struct { +} + +func (UnimplementedChatAPIServicesServer) Create(context.Context, *CreateNewChatRequest) (*CreateNewChatResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") +} +func (UnimplementedChatAPIServicesServer) Delete(context.Context, *DeleteChatRequest) (*DeleteChatResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (UnimplementedChatAPIServicesServer) SendMessage(context.Context, *SendMessageRequest) (*SendMessageResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendMessage not implemented") +} +func (UnimplementedChatAPIServicesServer) mustEmbedUnimplementedChatAPIServicesServer() {} + +// UnsafeChatAPIServicesServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ChatAPIServicesServer will +// result in compilation errors. +type UnsafeChatAPIServicesServer interface { + mustEmbedUnimplementedChatAPIServicesServer() +} + +func RegisterChatAPIServicesServer(s grpc.ServiceRegistrar, srv ChatAPIServicesServer) { + s.RegisterService(&ChatAPIServices_ServiceDesc, srv) +} + +func _ChatAPIServices_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateNewChatRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChatAPIServicesServer).Create(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/chat_v1.ChatAPIServices/Create", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChatAPIServicesServer).Create(ctx, req.(*CreateNewChatRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChatAPIServices_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteChatRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChatAPIServicesServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/chat_v1.ChatAPIServices/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChatAPIServicesServer).Delete(ctx, req.(*DeleteChatRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ChatAPIServices_SendMessage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SendMessageRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChatAPIServicesServer).SendMessage(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/chat_v1.ChatAPIServices/SendMessage", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChatAPIServicesServer).SendMessage(ctx, req.(*SendMessageRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ChatAPIServices_ServiceDesc is the grpc.ServiceDesc for ChatAPIServices service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ChatAPIServices_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "chat_v1.ChatAPIServices", + HandlerType: (*ChatAPIServicesServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Create", + Handler: _ChatAPIServices_Create_Handler, + }, + { + MethodName: "Delete", + Handler: _ChatAPIServices_Delete_Handler, + }, + { + MethodName: "SendMessage", + Handler: _ChatAPIServices_SendMessage_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "chat_api.proto", +}