From 616b5d798a818d976b0bbb2ab2b1ce8c4fa6ac0e Mon Sep 17 00:00:00 2001
From: Vijay Pai <vpai@google.com>
Date: Fri, 17 Aug 2018 13:38:48 -0700
Subject: [PATCH] Cast an index to size_t to avoid sign-conversion warning

---
 doc/cpp/pending_api_cleanups.md            |  3 ++
 include/grpcpp/impl/codegen/service_type.h | 37 ++++++++++++++--------
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/doc/cpp/pending_api_cleanups.md b/doc/cpp/pending_api_cleanups.md
index fa19b52002f..5c231eda2c8 100644
--- a/doc/cpp/pending_api_cleanups.md
+++ b/doc/cpp/pending_api_cleanups.md
@@ -17,3 +17,6 @@ number:
   `include/grpc++/impl/codegen/client_context.h` (commit `9477724`)
 - remove directory `include/grpc++` and all headers in it
   (commit `eb06572`)
+- make all `Request` and `Mark` methods in `grpc::Service` take a
+  `size_t` argument for `index` rather than `int` (since that is only
+  used as a vector index)
diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h
index a0bbd659e28..9f1a0521689 100644
--- a/include/grpcpp/impl/codegen/service_type.h
+++ b/include/grpcpp/impl/codegen/service_type.h
@@ -93,14 +93,19 @@ class Service {
                          internal::ServerAsyncStreamingInterface* stream,
                          CompletionQueue* call_cq,
                          ServerCompletionQueue* notification_cq, void* tag) {
-    server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+    // Typecast the index to size_t for indexing into a vector
+    // while preserving the API that existed before a compiler
+    // warning was first seen (grpc/grpc#11664)
+    size_t idx = static_cast<size_t>(index);
+    server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
                               notification_cq, tag, request);
   }
   void RequestAsyncClientStreaming(
       int index, ServerContext* context,
       internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
       ServerCompletionQueue* notification_cq, void* tag) {
-    server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+    size_t idx = static_cast<size_t>(index);
+    server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
                               notification_cq, tag);
   }
   template <class Message>
@@ -108,14 +113,16 @@ class Service {
       int index, ServerContext* context, Message* request,
       internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
       ServerCompletionQueue* notification_cq, void* tag) {
-    server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+    size_t idx = static_cast<size_t>(index);
+    server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
                               notification_cq, tag, request);
   }
   void RequestAsyncBidiStreaming(
       int index, ServerContext* context,
       internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
       ServerCompletionQueue* notification_cq, void* tag) {
-    server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+    size_t idx = static_cast<size_t>(index);
+    server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
                               notification_cq, tag);
   }
 
@@ -126,46 +133,50 @@ class Service {
   void MarkMethodAsync(int index) {
     // This does not have to be a hard error, however no one has approached us
     // with a use case yet. Please file an issue if you believe you have one.
+    size_t idx = static_cast<size_t>(index);
     GPR_CODEGEN_ASSERT(
-        methods_[index].get() != nullptr &&
+        methods_[idx].get() != nullptr &&
         "Cannot mark the method as 'async' because it has already been "
         "marked as 'generic'.");
-    methods_[index]->SetServerAsyncType(
+    methods_[idx]->SetServerAsyncType(
         internal::RpcServiceMethod::AsyncType::ASYNC);
   }
 
   void MarkMethodRaw(int index) {
     // This does not have to be a hard error, however no one has approached us
     // with a use case yet. Please file an issue if you believe you have one.
-    GPR_CODEGEN_ASSERT(methods_[index].get() != nullptr &&
+    size_t idx = static_cast<size_t>(index);
+    GPR_CODEGEN_ASSERT(methods_[idx].get() != nullptr &&
                        "Cannot mark the method as 'raw' because it has already "
                        "been marked as 'generic'.");
-    methods_[index]->SetServerAsyncType(
+    methods_[idx]->SetServerAsyncType(
         internal::RpcServiceMethod::AsyncType::RAW);
   }
 
   void MarkMethodGeneric(int index) {
     // This does not have to be a hard error, however no one has approached us
     // with a use case yet. Please file an issue if you believe you have one.
+    size_t idx = static_cast<size_t>(index);
     GPR_CODEGEN_ASSERT(
-        methods_[index]->handler() != nullptr &&
+        methods_[idx]->handler() != nullptr &&
         "Cannot mark the method as 'generic' because it has already been "
         "marked as 'async' or 'raw'.");
-    methods_[index].reset();
+    methods_[idx].reset();
   }
 
   void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
     // This does not have to be a hard error, however no one has approached us
     // with a use case yet. Please file an issue if you believe you have one.
-    GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
+    size_t idx = static_cast<size_t>(index);
+    GPR_CODEGEN_ASSERT(methods_[idx] && methods_[idx]->handler() &&
                        "Cannot mark an async or generic method Streamed");
-    methods_[index]->SetHandler(streamed_method);
+    methods_[idx]->SetHandler(streamed_method);
 
     // From the server's point of view, streamed unary is a special
     // case of BIDI_STREAMING that has 1 read and 1 write, in that order,
     // and split server-side streaming is BIDI_STREAMING with 1 read and
     // any number of writes, in that order.
-    methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
+    methods_[idx]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
   }
 
  private: