From dcc841e8eb84fb4e098a69c685dcf491124a6954 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Fri, 18 Oct 2024 12:46:30 -0400 Subject: proto: add Post service for Mimi Announce Signed-off-by: Xe Iaso --- proto/external/jsonfeed/jsonfeed.pb.go | 2 +- proto/mi/mi.pb.go | 2 +- proto/mi/mi_grpc.pb.go | 65 +++- proto/mimi/announce.proto | 8 + proto/mimi/announce/announce.pb.go | 121 ++++++- proto/mimi/announce/announce.twirp.go | 511 +++++++++++++++++++++++++++- proto/mimi/announce/announce_grpc.pb.go | 129 ++++++- proto/mimi/statuspage/statuspage.pb.go | 2 +- proto/mimi/statuspage/statuspage_grpc.pb.go | 27 +- proto/sanguisuga/sanguisuga.pb.go | 2 +- proto/sanguisuga/sanguisuga_grpc.pb.go | 46 ++- proto/uplodr/uplodr.pb.go | 2 +- proto/uplodr/uplodr_grpc.pb.go | 85 ++--- 13 files changed, 873 insertions(+), 129 deletions(-) diff --git a/proto/external/jsonfeed/jsonfeed.pb.go b/proto/external/jsonfeed/jsonfeed.pb.go index d88710d..ca8cfca 100644 --- a/proto/external/jsonfeed/jsonfeed.pb.go +++ b/proto/external/jsonfeed/jsonfeed.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v5.27.1 +// protoc v5.27.3 // source: jsonfeed.proto package jsonfeed diff --git a/proto/mi/mi.pb.go b/proto/mi/mi.pb.go index 0ec8169..336db5c 100644 --- a/proto/mi/mi.pb.go +++ b/proto/mi/mi.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v5.27.1 +// protoc v5.27.3 // source: mi.proto package mi diff --git a/proto/mi/mi_grpc.pb.go b/proto/mi/mi_grpc.pb.go index d9b3756..f826e91 100644 --- a/proto/mi/mi_grpc.pb.go +++ b/proto/mi/mi_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v5.27.1 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 // source: mi.proto package mi @@ -16,8 +16,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( SwitchTracker_Members_FullMethodName = "/within.website.x.mi.SwitchTracker/Members" @@ -98,7 +98,7 @@ func (c *switchTrackerClient) ListSwitches(ctx context.Context, in *ListSwitches // SwitchTrackerServer is the server API for SwitchTracker service. // All implementations must embed UnimplementedSwitchTrackerServer -// for forward compatibility +// for forward compatibility. type SwitchTrackerServer interface { Members(context.Context, *emptypb.Empty) (*MembersResp, error) WhoIsFront(context.Context, *emptypb.Empty) (*FrontChange, error) @@ -108,9 +108,12 @@ type SwitchTrackerServer interface { mustEmbedUnimplementedSwitchTrackerServer() } -// UnimplementedSwitchTrackerServer must be embedded to have forward compatible implementations. -type UnimplementedSwitchTrackerServer struct { -} +// UnimplementedSwitchTrackerServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedSwitchTrackerServer struct{} func (UnimplementedSwitchTrackerServer) Members(context.Context, *emptypb.Empty) (*MembersResp, error) { return nil, status.Errorf(codes.Unimplemented, "method Members not implemented") @@ -128,6 +131,7 @@ func (UnimplementedSwitchTrackerServer) ListSwitches(context.Context, *ListSwitc return nil, status.Errorf(codes.Unimplemented, "method ListSwitches not implemented") } func (UnimplementedSwitchTrackerServer) mustEmbedUnimplementedSwitchTrackerServer() {} +func (UnimplementedSwitchTrackerServer) testEmbeddedByValue() {} // UnsafeSwitchTrackerServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to SwitchTrackerServer will @@ -137,6 +141,13 @@ type UnsafeSwitchTrackerServer interface { } func RegisterSwitchTrackerServer(s grpc.ServiceRegistrar, srv SwitchTrackerServer) { + // If the following call pancis, it indicates UnimplementedSwitchTrackerServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&SwitchTracker_ServiceDesc, srv) } @@ -293,20 +304,24 @@ func (c *pOSSEClient) RefreshBlog(ctx context.Context, in *emptypb.Empty, opts . // POSSEServer is the server API for POSSE service. // All implementations must embed UnimplementedPOSSEServer -// for forward compatibility +// for forward compatibility. type POSSEServer interface { RefreshBlog(context.Context, *emptypb.Empty) (*emptypb.Empty, error) mustEmbedUnimplementedPOSSEServer() } -// UnimplementedPOSSEServer must be embedded to have forward compatible implementations. -type UnimplementedPOSSEServer struct { -} +// UnimplementedPOSSEServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedPOSSEServer struct{} func (UnimplementedPOSSEServer) RefreshBlog(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method RefreshBlog not implemented") } func (UnimplementedPOSSEServer) mustEmbedUnimplementedPOSSEServer() {} +func (UnimplementedPOSSEServer) testEmbeddedByValue() {} // UnsafePOSSEServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to POSSEServer will @@ -316,6 +331,13 @@ type UnsafePOSSEServer interface { } func RegisterPOSSEServer(s grpc.ServiceRegistrar, srv POSSEServer) { + // If the following call pancis, it indicates UnimplementedPOSSEServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&POSSE_ServiceDesc, srv) } @@ -413,7 +435,7 @@ func (c *eventsClient) Remove(ctx context.Context, in *Event, opts ...grpc.CallO // EventsServer is the server API for Events service. // All implementations must embed UnimplementedEventsServer -// for forward compatibility +// for forward compatibility. // // Events lets users fetch the current feed of events that Xe will be attending. type EventsServer interface { @@ -426,9 +448,12 @@ type EventsServer interface { mustEmbedUnimplementedEventsServer() } -// UnimplementedEventsServer must be embedded to have forward compatible implementations. -type UnimplementedEventsServer struct { -} +// UnimplementedEventsServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedEventsServer struct{} func (UnimplementedEventsServer) Get(context.Context, *emptypb.Empty) (*EventFeed, error) { return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") @@ -440,6 +465,7 @@ func (UnimplementedEventsServer) Remove(context.Context, *Event) (*emptypb.Empty return nil, status.Errorf(codes.Unimplemented, "method Remove not implemented") } func (UnimplementedEventsServer) mustEmbedUnimplementedEventsServer() {} +func (UnimplementedEventsServer) testEmbeddedByValue() {} // UnsafeEventsServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to EventsServer will @@ -449,6 +475,13 @@ type UnsafeEventsServer interface { } func RegisterEventsServer(s grpc.ServiceRegistrar, srv EventsServer) { + // If the following call pancis, it indicates UnimplementedEventsServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Events_ServiceDesc, srv) } diff --git a/proto/mimi/announce.proto b/proto/mimi/announce.proto index b1a0374..953b4a2 100644 --- a/proto/mimi/announce.proto +++ b/proto/mimi/announce.proto @@ -5,6 +5,14 @@ option go_package = "within.website/x/proto/mimi/announce"; import "google/protobuf/empty.proto"; import "external/jsonfeed.proto"; +message StatusUpdate { + string body = 1; +} + service Announce { rpc Announce(jsonfeed.Item) returns (google.protobuf.Empty) {} +} + +service Post { + rpc Post(StatusUpdate) returns (google.protobuf.Empty) {} } \ No newline at end of file diff --git a/proto/mimi/announce/announce.pb.go b/proto/mimi/announce/announce.pb.go index 8bcb173..9e83678 100644 --- a/proto/mimi/announce/announce.pb.go +++ b/proto/mimi/announce/announce.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v5.27.1 +// protoc v5.27.3 // source: announce.proto package announce @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" + sync "sync" jsonfeed "within.website/x/proto/external/jsonfeed" ) @@ -21,6 +22,53 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type StatusUpdate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body string `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` +} + +func (x *StatusUpdate) Reset() { + *x = StatusUpdate{} + if protoimpl.UnsafeEnabled { + mi := &file_announce_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatusUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusUpdate) ProtoMessage() {} + +func (x *StatusUpdate) ProtoReflect() protoreflect.Message { + mi := &file_announce_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 StatusUpdate.ProtoReflect.Descriptor instead. +func (*StatusUpdate) Descriptor() ([]byte, []int) { + return file_announce_proto_rawDescGZIP(), []int{0} +} + +func (x *StatusUpdate) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + var File_announce_proto protoreflect.FileDescriptor var file_announce_proto_rawDesc = []byte{ @@ -30,25 +78,49 @@ var file_announce_proto_rawDesc = []byte{ 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, 0x1a, 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x66, 0x65, 0x65, 0x64, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x40, 0x0a, 0x08, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, - 0x63, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x12, 0x0e, - 0x2e, 0x6a, 0x73, 0x6f, 0x6e, 0x66, 0x65, 0x65, 0x64, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x26, 0x5a, 0x24, 0x77, 0x69, 0x74, 0x68, - 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x78, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x6d, 0x69, 0x6d, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x32, 0x40, 0x0a, 0x08, 0x41, 0x6e, + 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, + 0x63, 0x65, 0x12, 0x0e, 0x2e, 0x6a, 0x73, 0x6f, 0x6e, 0x66, 0x65, 0x65, 0x64, 0x2e, 0x49, 0x74, + 0x65, 0x6d, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x32, 0x56, 0x0a, 0x04, + 0x50, 0x6f, 0x73, 0x74, 0x12, 0x4e, 0x0a, 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x2c, 0x2e, 0x77, + 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x78, 0x2e, + 0x6d, 0x69, 0x6d, 0x69, 0x2e, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x00, 0x42, 0x26, 0x5a, 0x24, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2e, 0x77, + 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2f, 0x78, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, + 0x69, 0x6d, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } +var ( + file_announce_proto_rawDescOnce sync.Once + file_announce_proto_rawDescData = file_announce_proto_rawDesc +) + +func file_announce_proto_rawDescGZIP() []byte { + file_announce_proto_rawDescOnce.Do(func() { + file_announce_proto_rawDescData = protoimpl.X.CompressGZIP(file_announce_proto_rawDescData) + }) + return file_announce_proto_rawDescData +} + +var file_announce_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_announce_proto_goTypes = []any{ - (*jsonfeed.Item)(nil), // 0: jsonfeed.Item - (*emptypb.Empty)(nil), // 1: google.protobuf.Empty + (*StatusUpdate)(nil), // 0: within.website.x.mimi.announce.StatusUpdate + (*jsonfeed.Item)(nil), // 1: jsonfeed.Item + (*emptypb.Empty)(nil), // 2: google.protobuf.Empty } var file_announce_proto_depIdxs = []int32{ - 0, // 0: within.website.x.mimi.announce.Announce.Announce:input_type -> jsonfeed.Item - 1, // 1: within.website.x.mimi.announce.Announce.Announce:output_type -> google.protobuf.Empty - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type + 1, // 0: within.website.x.mimi.announce.Announce.Announce:input_type -> jsonfeed.Item + 0, // 1: within.website.x.mimi.announce.Post.Post:input_type -> within.website.x.mimi.announce.StatusUpdate + 2, // 2: within.website.x.mimi.announce.Announce.Announce:output_type -> google.protobuf.Empty + 2, // 3: within.website.x.mimi.announce.Post.Post:output_type -> google.protobuf.Empty + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] 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 @@ -59,18 +131,33 @@ func file_announce_proto_init() { if File_announce_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_announce_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*StatusUpdate); 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_announce_proto_rawDesc, NumEnums: 0, - NumMessages: 0, + NumMessages: 1, NumExtensions: 0, - NumServices: 1, + NumServices: 2, }, GoTypes: file_announce_proto_goTypes, DependencyIndexes: file_announce_proto_depIdxs, + MessageInfos: file_announce_proto_msgTypes, }.Build() File_announce_proto = out.File file_announce_proto_rawDesc = nil diff --git a/proto/mimi/announce/announce.twirp.go b/proto/mimi/announce/announce.twirp.go index b049adf..9186537 100644 --- a/proto/mimi/announce/announce.twirp.go +++ b/proto/mimi/announce/announce.twirp.go @@ -524,6 +524,500 @@ func (s *announceServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "within.website.x.mimi.announce", "Announce") } +// ============== +// Post Interface +// ============== + +type Post interface { + Post(context.Context, *StatusUpdate) (*google_protobuf.Empty, error) +} + +// ==================== +// Post Protobuf Client +// ==================== + +type postProtobufClient struct { + client HTTPClient + urls [1]string + interceptor twirp.Interceptor + opts twirp.ClientOptions +} + +// NewPostProtobufClient creates a Protobuf client that implements the Post interface. +// It communicates using Protobuf and can be configured with a custom HTTPClient. +func NewPostProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Post { + if c, ok := client.(*http.Client); ok { + client = withoutRedirects(c) + } + + clientOpts := twirp.ClientOptions{} + for _, o := range opts { + o(&clientOpts) + } + + // Using ReadOpt allows backwards and forwards compatibility with new options in the future + literalURLs := false + _ = clientOpts.ReadOpt("literalURLs", &literalURLs) + var pathPrefix string + if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { + pathPrefix = "/twirp" // default prefix + } + + // Build method URLs: []/./ + serviceURL := sanitizeBaseURL(baseURL) + serviceURL += baseServicePath(pathPrefix, "within.website.x.mimi.announce", "Post") + urls := [1]string{ + serviceURL + "Post", + } + + return &postProtobufClient{ + client: client, + urls: urls, + interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), + opts: clientOpts, + } +} + +func (c *postProtobufClient) Post(ctx context.Context, in *StatusUpdate) (*google_protobuf.Empty, error) { + ctx = ctxsetters.WithPackageName(ctx, "within.website.x.mimi.announce") + ctx = ctxsetters.WithServiceName(ctx, "Post") + ctx = ctxsetters.WithMethodName(ctx, "Post") + caller := c.callPost + if c.interceptor != nil { + caller = func(ctx context.Context, req *StatusUpdate) (*google_protobuf.Empty, error) { + resp, err := c.interceptor( + func(ctx context.Context, req interface{}) (interface{}, error) { + typedReq, ok := req.(*StatusUpdate) + if !ok { + return nil, twirp.InternalError("failed type assertion req.(*StatusUpdate) when calling interceptor") + } + return c.callPost(ctx, typedReq) + }, + )(ctx, req) + if resp != nil { + typedResp, ok := resp.(*google_protobuf.Empty) + if !ok { + return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor") + } + return typedResp, err + } + return nil, err + } + } + return caller(ctx, in) +} + +func (c *postProtobufClient) callPost(ctx context.Context, in *StatusUpdate) (*google_protobuf.Empty, error) { + out := new(google_protobuf.Empty) + ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) + if err != nil { + twerr, ok := err.(twirp.Error) + if !ok { + twerr = twirp.InternalErrorWith(err) + } + callClientError(ctx, c.opts.Hooks, twerr) + return nil, err + } + + callClientResponseReceived(ctx, c.opts.Hooks) + + return out, nil +} + +// ================ +// Post JSON Client +// ================ + +type postJSONClient struct { + client HTTPClient + urls [1]string + interceptor twirp.Interceptor + opts twirp.ClientOptions +} + +// NewPostJSONClient creates a JSON client that implements the Post interface. +// It communicates using JSON and can be configured with a custom HTTPClient. +func NewPostJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Post { + if c, ok := client.(*http.Client); ok { + client = withoutRedirects(c) + } + + clientOpts := twirp.ClientOptions{} + for _, o := range opts { + o(&clientOpts) + } + + // Using ReadOpt allows backwards and forwards compatibility with new options in the future + literalURLs := false + _ = clientOpts.ReadOpt("literalURLs", &literalURLs) + var pathPrefix string + if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { + pathPrefix = "/twirp" // default prefix + } + + // Build method URLs: []/./ + serviceURL := sanitizeBaseURL(baseURL) + serviceURL += baseServicePath(pathPrefix, "within.website.x.mimi.announce", "Post") + urls := [1]string{ + serviceURL + "Post", + } + + return &postJSONClient{ + client: client, + urls: urls, + interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), + opts: clientOpts, + } +} + +func (c *postJSONClient) Post(ctx context.Context, in *StatusUpdate) (*google_protobuf.Empty, error) { + ctx = ctxsetters.WithPackageName(ctx, "within.website.x.mimi.announce") + ctx = ctxsetters.WithServiceName(ctx, "Post") + ctx = ctxsetters.WithMethodName(ctx, "Post") + caller := c.callPost + if c.interceptor != nil { + caller = func(ctx context.Context, req *StatusUpdate) (*google_protobuf.Empty, error) { + resp, err := c.interceptor( + func(ctx context.Context, req interface{}) (interface{}, error) { + typedReq, ok := req.(*StatusUpdate) + if !ok { + return nil, twirp.InternalError("failed type assertion req.(*StatusUpdate) when calling interceptor") + } + return c.callPost(ctx, typedReq) + }, + )(ctx, req) + if resp != nil { + typedResp, ok := resp.(*google_protobuf.Empty) + if !ok { + return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor") + } + return typedResp, err + } + return nil, err + } + } + return caller(ctx, in) +} + +func (c *postJSONClient) callPost(ctx context.Context, in *StatusUpdate) (*google_protobuf.Empty, error) { + out := new(google_protobuf.Empty) + ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) + if err != nil { + twerr, ok := err.(twirp.Error) + if !ok { + twerr = twirp.InternalErrorWith(err) + } + callClientError(ctx, c.opts.Hooks, twerr) + return nil, err + } + + callClientResponseReceived(ctx, c.opts.Hooks) + + return out, nil +} + +// =================== +// Post Server Handler +// =================== + +type postServer struct { + Post + interceptor twirp.Interceptor + hooks *twirp.ServerHooks + pathPrefix string // prefix for routing + jsonSkipDefaults bool // do not include unpopulated fields (default values) in the response + jsonCamelCase bool // JSON fields are serialized as lowerCamelCase rather than keeping the original proto names +} + +// NewPostServer builds a TwirpServer that can be used as an http.Handler to handle +// HTTP requests that are routed to the right method in the provided svc implementation. +// The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks). +func NewPostServer(svc Post, opts ...interface{}) TwirpServer { + serverOpts := newServerOpts(opts) + + // Using ReadOpt allows backwards and forwards compatibility with new options in the future + jsonSkipDefaults := false + _ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults) + jsonCamelCase := false + _ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase) + var pathPrefix string + if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { + pathPrefix = "/twirp" // default prefix + } + + return &postServer{ + Post: svc, + hooks: serverOpts.Hooks, + interceptor: twirp.ChainInterceptors(serverOpts.Interceptors...), + pathPrefix: pathPrefix, + jsonSkipDefaults: jsonSkipDefaults, + jsonCamelCase: jsonCamelCase, + } +} + +// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks. +// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err) +func (s *postServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) { + writeError(ctx, resp, err, s.hooks) +} + +// handleRequestBodyError is used to handle error when the twirp server cannot read request +func (s *postServer) handleRequestBodyError(ctx context.Context, resp http.ResponseWriter, msg string, err error) { + if context.Canceled == ctx.Err() { + s.writeError(ctx, resp, twirp.NewError(twirp.Canceled, "failed to read request: context canceled")) + return + } + if context.DeadlineExceeded == ctx.Err() { + s.writeError(ctx, resp, twirp.NewError(twirp.DeadlineExceeded, "failed to read request: deadline exceeded")) + return + } + s.writeError(ctx, resp, twirp.WrapError(malformedRequestError(msg), err)) +} + +// PostPathPrefix is a convenience constant that may identify URL paths. +// Should be used with caution, it only matches routes generated by Twirp Go clients, +// with the default "/twirp" prefix and default CamelCase service and method names. +// More info: https://twitchtv.github.io/twirp/docs/routing.html +const PostPathPrefix = "/twirp/within.website.x.mimi.announce.Post/" + +func (s *postServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + ctx := req.Context() + ctx = ctxsetters.WithPackageName(ctx, "within.website.x.mimi.announce") + ctx = ctxsetters.WithServiceName(ctx, "Post") + ctx = ctxsetters.WithResponseWriter(ctx, resp) + + var err error + ctx, err = callRequestReceived(ctx, s.hooks) + if err != nil { + s.writeError(ctx, resp, err) + return + } + + if req.Method != "POST" { + msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method) + s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) + return + } + + // Verify path format: []/./ + prefix, pkgService, method := parseTwirpPath(req.URL.Path) + if pkgService != "within.website.x.mimi.announce.Post" { + msg := fmt.Sprintf("no handler for path %q", req.URL.Path) + s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) + return + } + if prefix != s.pathPrefix { + msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path) + s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) + return + } + + switch method { + case "Post": + s.servePost(ctx, resp, req) + return + default: + msg := fmt.Sprintf("no handler for path %q", req.URL.Path) + s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) + return + } +} + +func (s *postServer) servePost(ctx context.Context, resp http.ResponseWriter, req *http.Request) { + header := req.Header.Get("Content-Type") + i := strings.Index(header, ";") + if i == -1 { + i = len(header) + } + switch strings.TrimSpace(strings.ToLower(header[:i])) { + case "application/json": + s.servePostJSON(ctx, resp, req) + case "application/protobuf": + s.servePostProtobuf(ctx, resp, req) + default: + msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) + twerr := badRouteError(msg, req.Method, req.URL.Path) + s.writeError(ctx, resp, twerr) + } +} + +func (s *postServer) servePostJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { + var err error + ctx = ctxsetters.WithMethodName(ctx, "Post") + ctx, err = callRequestRouted(ctx, s.hooks) + if err != nil { + s.writeError(ctx, resp, err) + return + } + + d := json.NewDecoder(req.Body) + rawReqBody := json.RawMessage{} + if err := d.Decode(&rawReqBody); err != nil { + s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) + return + } + reqContent := new(StatusUpdate) + unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} + if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { + s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) + return + } + + handler := s.Post.Post + if s.interceptor != nil { + handler = func(ctx context.Context, req *StatusUpdate) (*google_protobuf.Empty, error) { + resp, err := s.interceptor( + func(ctx context.Context, req interface{}) (interface{}, error) { + typedReq, ok := req.(*StatusUpdate) + if !ok { + return nil, twirp.InternalError("failed type assertion req.(*StatusUpdate) when calling interceptor") + } + return s.Post.Post(ctx, typedReq) + }, + )(ctx, req) + if resp != nil { + typedResp, ok := resp.(*google_protobuf.Empty) + if !ok { + return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor") + } + return typedResp, err + } + return nil, err + } + } + + // Call service method + var respContent *google_protobuf.Empty + func() { + defer ensurePanicResponses(ctx, resp, s.hooks) + respContent, err = handler(ctx, reqContent) + }() + + if err != nil { + s.writeError(ctx, resp, err) + return + } + if respContent == nil { + s.writeError(ctx, resp, twirp.InternalError("received a nil *google_protobuf.Empty and nil error while calling Post. nil responses are not supported")) + return + } + + ctx = callResponsePrepared(ctx, s.hooks) + + marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} + respBytes, err := marshaler.Marshal(respContent) + if err != nil { + s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) + return + } + + ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) + resp.Header().Set("Content-Type", "application/json") + resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) + resp.WriteHeader(http.StatusOK) + + if n, err := resp.Write(respBytes); err != nil { + msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) + twerr := twirp.NewError(twirp.Unknown, msg) + ctx = callError(ctx, s.hooks, twerr) + } + callResponseSent(ctx, s.hooks) +} + +func (s *postServer) servePostProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { + var err error + ctx = ctxsetters.WithMethodName(ctx, "Post") + ctx, err = callRequestRouted(ctx, s.hooks) + if err != nil { + s.writeError(ctx, resp, err) + return + } + + buf, err := io.ReadAll(req.Body) + if err != nil { + s.handleRequestBodyError(ctx, resp, "failed to read request body", err) + return + } + reqContent := new(StatusUpdate) + if err = proto.Unmarshal(buf, reqContent); err != nil { + s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) + return + } + + handler := s.Post.Post + if s.interceptor != nil { + handler = func(ctx context.Context, req *StatusUpdate) (*google_protobuf.Empty, error) { + resp, err := s.interceptor( + func(ctx context.Context, req interface{}) (interface{}, error) { + typedReq, ok := req.(*StatusUpdate) + if !ok { + return nil, twirp.InternalError("failed type assertion req.(*StatusUpdate) when calling interceptor") + } + return s.Post.Post(ctx, typedReq) + }, + )(ctx, req) + if resp != nil { + typedResp, ok := resp.(*google_protobuf.Empty) + if !ok { + return nil, twirp.InternalError("failed type assertion resp.(*google_protobuf.Empty) when calling interceptor") + } + return typedResp, err + } + return nil, err + } + } + + // Call service method + var respContent *google_protobuf.Empty + func() { + defer ensurePanicResponses(ctx, resp, s.hooks) + respContent, err = handler(ctx, reqContent) + }() + + if err != nil { + s.writeError(ctx, resp, err) + return + } + if respContent == nil { + s.writeError(ctx, resp, twirp.InternalError("received a nil *google_protobuf.Empty and nil error while calling Post. nil responses are not supported")) + return + } + + ctx = callResponsePrepared(ctx, s.hooks) + + respBytes, err := proto.Marshal(respContent) + if err != nil { + s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) + return + } + + ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) + resp.Header().Set("Content-Type", "application/protobuf") + resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) + resp.WriteHeader(http.StatusOK) + if n, err := resp.Write(respBytes); err != nil { + msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) + twerr := twirp.NewError(twirp.Unknown, msg) + ctx = callError(ctx, s.hooks, twerr) + } + callResponseSent(ctx, s.hooks) +} + +func (s *postServer) ServiceDescriptor() ([]byte, int) { + return twirpFileDescriptor0, 1 +} + +func (s *postServer) ProtocGenTwirpVersion() string { + return "v8.1.3" +} + +// PathPrefix returns the base service path, in the form: "//./" +// that is everything in a Twirp route except for the . This can be used for routing, +// for example to identify the requests that are targeted to this service in a mux. +func (s *postServer) PathPrefix() string { + return baseServicePath(s.pathPrefix, "within.website.x.mimi.announce", "Post") +} + // ===== // Utils // ===== @@ -1090,16 +1584,19 @@ func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error) } var twirpFileDescriptor0 = []byte{ - // 164 bytes of a gzipped FileDescriptorProto + // 219 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0xcc, 0xcb, 0xcb, 0x2f, 0xcd, 0x4b, 0x4e, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x2b, 0xcf, 0x2c, 0xc9, 0xc8, 0xcc, 0xd3, 0x2b, 0x4f, 0x4d, 0x2a, 0xce, 0x2c, 0x49, 0xd5, 0xab, 0xd0, 0xcb, 0xcd, 0xcc, 0xcd, 0xd4, 0x83, 0xa9, 0x92, 0x92, 0x4e, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x07, 0xab, 0x4e, 0x2a, 0x4d, 0xd3, 0x4f, 0xcd, 0x2d, 0x28, 0xa9, 0x84, 0x68, 0x96, 0x12, 0x4f, 0xad, 0x28, 0x49, - 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0xcf, 0x2a, 0xce, 0xcf, 0x4b, 0x4b, 0x4d, 0x4d, 0x81, 0x48, 0x18, - 0x39, 0x70, 0x71, 0x38, 0x42, 0x4d, 0x10, 0x32, 0x41, 0x62, 0xf3, 0xe9, 0xc1, 0x15, 0x7a, 0x96, - 0xa4, 0xe6, 0x4a, 0x89, 0xe9, 0x41, 0x8c, 0xd7, 0x83, 0x19, 0xaf, 0xe7, 0x0a, 0x32, 0x5e, 0x89, - 0xc1, 0x49, 0x2d, 0x4a, 0x05, 0xd5, 0x65, 0xfa, 0x15, 0x10, 0x37, 0xe8, 0x83, 0xdc, 0xa7, 0x0f, - 0x73, 0x5f, 0x12, 0x1b, 0x58, 0xd0, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xd3, 0xe2, 0x49, 0x3b, - 0xd8, 0x00, 0x00, 0x00, + 0x2d, 0xca, 0x4b, 0xcc, 0xd1, 0xcf, 0x2a, 0xce, 0xcf, 0x4b, 0x4b, 0x4d, 0x4d, 0x81, 0x48, 0x28, + 0x29, 0x71, 0xf1, 0x04, 0x97, 0x24, 0x96, 0x94, 0x16, 0x87, 0x16, 0xa4, 0x24, 0x96, 0xa4, 0x0a, + 0x09, 0x71, 0xb1, 0x24, 0xe5, 0xa7, 0x54, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x06, 0x81, 0xd9, + 0x46, 0x0e, 0x5c, 0x1c, 0x8e, 0x50, 0x5b, 0x84, 0x4c, 0x90, 0xd8, 0x7c, 0x7a, 0x70, 0xc3, 0x3c, + 0x4b, 0x52, 0x73, 0xa5, 0xc4, 0xf4, 0x20, 0x4e, 0xd0, 0x83, 0x39, 0x41, 0xcf, 0x15, 0xe4, 0x04, + 0x25, 0x06, 0xa3, 0x30, 0x2e, 0x96, 0x80, 0xfc, 0xe2, 0x12, 0x21, 0x3f, 0x28, 0xad, 0xa3, 0x87, + 0xdf, 0x33, 0x7a, 0xc8, 0x6e, 0xc2, 0x6d, 0xae, 0x93, 0x5a, 0x94, 0x0a, 0xaa, 0x41, 0xfa, 0x15, + 0x10, 0xff, 0xeb, 0x83, 0x8c, 0xd3, 0x87, 0x19, 0x97, 0xc4, 0x06, 0x16, 0x34, 0x06, 0x04, 0x00, + 0x00, 0xff, 0xff, 0x1d, 0x73, 0x3d, 0xac, 0x54, 0x01, 0x00, 0x00, } diff --git a/proto/mimi/announce/announce_grpc.pb.go b/proto/mimi/announce/announce_grpc.pb.go index dab960c..0ff34a3 100644 --- a/proto/mimi/announce/announce_grpc.pb.go +++ b/proto/mimi/announce/announce_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v5.27.1 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 // source: announce.proto package announce @@ -17,8 +17,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Announce_Announce_FullMethodName = "/within.website.x.mimi.announce.Announce/Announce" @@ -51,20 +51,24 @@ func (c *announceClient) Announce(ctx context.Context, in *jsonfeed.Item, opts . // AnnounceServer is the server API for Announce service. // All implementations must embed UnimplementedAnnounceServer -// for forward compatibility +// for forward compatibility. type AnnounceServer interface { Announce(context.Context, *jsonfeed.Item) (*emptypb.Empty, error) mustEmbedUnimplementedAnnounceServer() } -// UnimplementedAnnounceServer must be embedded to have forward compatible implementations. -type UnimplementedAnnounceServer struct { -} +// UnimplementedAnnounceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAnnounceServer struct{} func (UnimplementedAnnounceServer) Announce(context.Context, *jsonfeed.Item) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Announce not implemented") } func (UnimplementedAnnounceServer) mustEmbedUnimplementedAnnounceServer() {} +func (UnimplementedAnnounceServer) testEmbeddedByValue() {} // UnsafeAnnounceServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to AnnounceServer will @@ -74,6 +78,13 @@ type UnsafeAnnounceServer interface { } func RegisterAnnounceServer(s grpc.ServiceRegistrar, srv AnnounceServer) { + // If the following call pancis, it indicates UnimplementedAnnounceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Announce_ServiceDesc, srv) } @@ -110,3 +121,105 @@ var Announce_ServiceDesc = grpc.ServiceDesc{ Streams: []grpc.StreamDesc{}, Metadata: "announce.proto", } + +const ( + Post_Post_FullMethodName = "/within.website.x.mimi.announce.Post/Post" +) + +// PostClient is the client API for Post 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 PostClient interface { + Post(ctx context.Context, in *StatusUpdate, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type postClient struct { + cc grpc.ClientConnInterface +} + +func NewPostClient(cc grpc.ClientConnInterface) PostClient { + return &postClient{cc} +} + +func (c *postClient) Post(ctx context.Context, in *StatusUpdate, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, Post_Post_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PostServer is the server API for Post service. +// All implementations must embed UnimplementedPostServer +// for forward compatibility. +type PostServer interface { + Post(context.Context, *StatusUpdate) (*emptypb.Empty, error) + mustEmbedUnimplementedPostServer() +} + +// UnimplementedPostServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedPostServer struct{} + +func (UnimplementedPostServer) Post(context.Context, *StatusUpdate) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Post not implemented") +} +func (UnimplementedPostServer) mustEmbedUnimplementedPostServer() {} +func (UnimplementedPostServer) testEmbeddedByValue() {} + +// UnsafePostServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PostServer will +// result in compilation errors. +type UnsafePostServer interface { + mustEmbedUnimplementedPostServer() +} + +func RegisterPostServer(s grpc.ServiceRegistrar, srv PostServer) { + // If the following call pancis, it indicates UnimplementedPostServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Post_ServiceDesc, srv) +} + +func _Post_Post_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatusUpdate) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PostServer).Post(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Post_Post_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PostServer).Post(ctx, req.(*StatusUpdate)) + } + return interceptor(ctx, in, info, handler) +} + +// Post_ServiceDesc is the grpc.ServiceDesc for Post service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Post_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "within.website.x.mimi.announce.Post", + HandlerType: (*PostServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Post", + Handler: _Post_Post_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "announce.proto", +} diff --git a/proto/mimi/statuspage/statuspage.pb.go b/proto/mimi/statuspage/statuspage.pb.go index 8dd6d59..e5e453c 100644 --- a/proto/mimi/statuspage/statuspage.pb.go +++ b/proto/mimi/statuspage/statuspage.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v5.27.1 +// protoc v5.27.3 // source: statuspage.proto package statuspage diff --git a/proto/mimi/statuspage/statuspage_grpc.pb.go b/proto/mimi/statuspage/statuspage_grpc.pb.go index f45a56a..cc8939a 100644 --- a/proto/mimi/statuspage/statuspage_grpc.pb.go +++ b/proto/mimi/statuspage/statuspage_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v5.27.1 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 // source: statuspage.proto package statuspage @@ -16,8 +16,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Update_Poke_FullMethodName = "/within.website.x.mimi.statuspage.Update/Poke" @@ -50,20 +50,24 @@ func (c *updateClient) Poke(ctx context.Context, in *StatusUpdate, opts ...grpc. // UpdateServer is the server API for Update service. // All implementations must embed UnimplementedUpdateServer -// for forward compatibility +// for forward compatibility. type UpdateServer interface { Poke(context.Context, *StatusUpdate) (*emptypb.Empty, error) mustEmbedUnimplementedUpdateServer() } -// UnimplementedUpdateServer must be embedded to have forward compatible implementations. -type UnimplementedUpdateServer struct { -} +// UnimplementedUpdateServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedUpdateServer struct{} func (UnimplementedUpdateServer) Poke(context.Context, *StatusUpdate) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Poke not implemented") } func (UnimplementedUpdateServer) mustEmbedUnimplementedUpdateServer() {} +func (UnimplementedUpdateServer) testEmbeddedByValue() {} // UnsafeUpdateServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to UpdateServer will @@ -73,6 +77,13 @@ type UnsafeUpdateServer interface { } func RegisterUpdateServer(s grpc.ServiceRegistrar, srv UpdateServer) { + // If the following call pancis, it indicates UnimplementedUpdateServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Update_ServiceDesc, srv) } diff --git a/proto/sanguisuga/sanguisuga.pb.go b/proto/sanguisuga/sanguisuga.pb.go index 0d3305d..9439c65 100644 --- a/proto/sanguisuga/sanguisuga.pb.go +++ b/proto/sanguisuga/sanguisuga.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v5.27.1 +// protoc v5.27.3 // source: sanguisuga.proto package sanguisuga diff --git a/proto/sanguisuga/sanguisuga_grpc.pb.go b/proto/sanguisuga/sanguisuga_grpc.pb.go index b83044f..c795580 100644 --- a/proto/sanguisuga/sanguisuga_grpc.pb.go +++ b/proto/sanguisuga/sanguisuga_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v5.27.1 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 // source: sanguisuga.proto package sanguisuga @@ -16,8 +16,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( TV_List_FullMethodName = "/within.website.x.sanguisuga.TV/List" @@ -86,7 +86,7 @@ func (c *tVClient) Snatches(ctx context.Context, in *emptypb.Empty, opts ...grpc // TVServer is the server API for TV service. // All implementations must embed UnimplementedTVServer -// for forward compatibility +// for forward compatibility. type TVServer interface { List(context.Context, *emptypb.Empty) (*Shows, error) Track(context.Context, *Show) (*emptypb.Empty, error) @@ -95,9 +95,12 @@ type TVServer interface { mustEmbedUnimplementedTVServer() } -// UnimplementedTVServer must be embedded to have forward compatible implementations. -type UnimplementedTVServer struct { -} +// UnimplementedTVServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedTVServer struct{} func (UnimplementedTVServer) List(context.Context, *emptypb.Empty) (*Shows, error) { return nil, status.Errorf(codes.Unimplemented, "method List not implemented") @@ -112,6 +115,7 @@ func (UnimplementedTVServer) Snatches(context.Context, *emptypb.Empty) (*TVSnatc return nil, status.Errorf(codes.Unimplemented, "method Snatches not implemented") } func (UnimplementedTVServer) mustEmbedUnimplementedTVServer() {} +func (UnimplementedTVServer) testEmbeddedByValue() {} // UnsafeTVServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to TVServer will @@ -121,6 +125,13 @@ type UnsafeTVServer interface { } func RegisterTVServer(s grpc.ServiceRegistrar, srv TVServer) { + // If the following call pancis, it indicates UnimplementedTVServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&TV_ServiceDesc, srv) } @@ -291,7 +302,7 @@ func (c *animeClient) Snatches(ctx context.Context, in *emptypb.Empty, opts ...g // AnimeServer is the server API for Anime service. // All implementations must embed UnimplementedAnimeServer -// for forward compatibility +// for forward compatibility. type AnimeServer interface { List(context.Context, *emptypb.Empty) (*Shows, error) Track(context.Context, *Show) (*emptypb.Empty, error) @@ -300,9 +311,12 @@ type AnimeServer interface { mustEmbedUnimplementedAnimeServer() } -// UnimplementedAnimeServer must be embedded to have forward compatible implementations. -type UnimplementedAnimeServer struct { -} +// UnimplementedAnimeServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAnimeServer struct{} func (UnimplementedAnimeServer) List(context.Context, *emptypb.Empty) (*Shows, error) { return nil, status.Errorf(codes.Unimplemented, "method List not implemented") @@ -317,6 +331,7 @@ func (UnimplementedAnimeServer) Snatches(context.Context, *emptypb.Empty) (*Anim return nil, status.Errorf(codes.Unimplemented, "method Snatches not implemented") } func (UnimplementedAnimeServer) mustEmbedUnimplementedAnimeServer() {} +func (UnimplementedAnimeServer) testEmbeddedByValue() {} // UnsafeAnimeServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to AnimeServer will @@ -326,6 +341,13 @@ type UnsafeAnimeServer interface { } func RegisterAnimeServer(s grpc.ServiceRegistrar, srv AnimeServer) { + // If the following call pancis, it indicates UnimplementedAnimeServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Anime_ServiceDesc, srv) } diff --git a/proto/uplodr/uplodr.pb.go b/proto/uplodr/uplodr.pb.go index 7337571..f43f8a0 100644 --- a/proto/uplodr/uplodr.pb.go +++ b/proto/uplodr/uplodr.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v5.27.1 +// protoc v5.27.3 // source: uplodr.proto package uplodr diff --git a/proto/uplodr/uplodr_grpc.pb.go b/proto/uplodr/uplodr_grpc.pb.go index 0f00edb..eef856b 100644 --- a/proto/uplodr/uplodr_grpc.pb.go +++ b/proto/uplodr/uplodr_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.4.0 -// - protoc v5.27.1 +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 // source: uplodr.proto package uplodr @@ -15,8 +15,8 @@ import ( // 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.62.0 or later. -const _ = grpc.SupportPackageIsVersion8 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( Image_Ping_FullMethodName = "/within.website.x.xedn.uplodr.Image/Ping" @@ -30,7 +30,7 @@ const ( type ImageClient interface { Ping(ctx context.Context, in *Echo, opts ...grpc.CallOption) (*Echo, error) Upload(ctx context.Context, in *UploadReq, opts ...grpc.CallOption) (*UploadResp, error) - Stream(ctx context.Context, opts ...grpc.CallOption) (Image_StreamClient, error) + Stream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[UploadReq, UploadResp], error) } type imageClient struct { @@ -61,51 +61,35 @@ func (c *imageClient) Upload(ctx context.Context, in *UploadReq, opts ...grpc.Ca return out, nil } -func (c *imageClient) Stream(ctx context.Context, opts ...grpc.CallOption) (Image_StreamClient, error) { +func (c *imageClient) Stream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[UploadReq, UploadResp], error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) stream, err := c.cc.NewStream(ctx, &Image_ServiceDesc.Streams[0], Image_Stream_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &imageStreamClient{ClientStream: stream} + x := &grpc.GenericClientStream[UploadReq, UploadResp]{ClientStream: stream} return x, nil } -type Image_StreamClient interface { - Send(*UploadReq) error - Recv() (*UploadResp, error) - grpc.ClientStream -} - -type imageStreamClient struct { - grpc.ClientStream -} - -func (x *imageStreamClient) Send(m *UploadReq) error { - return x.ClientStream.SendMsg(m) -} - -func (x *imageStreamClient) Recv() (*UploadResp, error) { - m := new(UploadResp) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Image_StreamClient = grpc.BidiStreamingClient[UploadReq, UploadResp] // ImageServer is the server API for Image service. // All implementations must embed UnimplementedImageServer -// for forward compatibility +// for forward compatibility. type ImageServer interface { Ping(context.Context, *Echo) (*Echo, error) Upload(context.Context, *UploadReq) (*UploadResp, error) - Stream(Image_StreamServer) error + Stream(grpc.BidiStreamingServer[UploadReq, UploadResp]) error mustEmbedUnimplementedImageServer() } -// UnimplementedImageServer must be embedded to have forward compatible implementations. -type UnimplementedImageServer struct { -} +// UnimplementedImageServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedImageServer struct{} func (UnimplementedImageServer) Ping(context.Context, *Echo) (*Echo, error) { return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") @@ -113,10 +97,11 @@ func (UnimplementedImageServer) Ping(context.Context, *Echo) (*Echo, error) { func (UnimplementedImageServer) Upload(context.Context, *UploadReq) (*UploadResp, error) { return nil, status.Errorf(codes.Unimplemented, "method Upload not implemented") } -func (UnimplementedImageServer) Stream(Image_StreamServer) error { +func (UnimplementedImageServer) Stream(grpc.BidiStreamingServer[UploadReq, UploadResp]) error { return status.Errorf(codes.Unimplemented, "method Stream not implemented") } func (UnimplementedImageServer) mustEmbedUnimplementedImageServer() {} +func (UnimplementedImageServer) testEmbeddedByValue() {} // UnsafeImageServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ImageServer will @@ -126,6 +111,13 @@ type UnsafeImageServer interface { } func RegisterImageServer(s grpc.ServiceRegistrar, srv ImageServer) { + // If the following call pancis, it indicates UnimplementedImageServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } s.RegisterService(&Image_ServiceDesc, srv) } @@ -166,30 +158,11 @@ func _Image_Upload_Handler(srv interface{}, ctx context.Context, dec func(interf } func _Image_Stream_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ImageServer).Stream(&imageStreamServer{ServerStream: stream}) -} - -type Image_StreamServer interface { - Send(*UploadResp) error - Recv() (*UploadReq, error) - grpc.ServerStream -} - -type imageStreamServer struct { - grpc.ServerStream + return srv.(ImageServer).Stream(&grpc.GenericServerStream[UploadReq, UploadResp]{ServerStream: stream}) } -func (x *imageStreamServer) Send(m *UploadResp) error { - return x.ServerStream.SendMsg(m) -} - -func (x *imageStreamServer) Recv() (*UploadReq, error) { - m := new(UploadReq) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type Image_StreamServer = grpc.BidiStreamingServer[UploadReq, UploadResp] // Image_ServiceDesc is the grpc.ServiceDesc for Image service. // It's only intended for direct use with grpc.RegisterService, -- cgit v1.2.3