aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/channel/call_op_string.c51
-rw-r--r--src/core/channel/census_filter.c24
-rw-r--r--src/core/channel/channel_stack.c57
-rw-r--r--src/core/channel/channel_stack.h31
-rw-r--r--src/core/channel/client_channel.c99
-rw-r--r--src/core/channel/connected_channel.c77
-rw-r--r--src/core/channel/http_client_filter.c77
-rw-r--r--src/core/channel/http_server_filter.c240
-rw-r--r--src/core/channel/metadata_buffer.c149
-rw-r--r--src/core/channel/metadata_buffer.h70
-rw-r--r--src/core/security/auth.c61
-rw-r--r--src/core/surface/call.c225
-rw-r--r--src/core/surface/call.h25
-rw-r--r--src/core/surface/channel.c52
-rw-r--r--src/core/surface/client.c28
-rw-r--r--src/core/surface/lame_client.c42
-rw-r--r--src/core/surface/server.c40
-rw-r--r--src/core/transport/chttp2/stream_encoder.c42
-rw-r--r--src/core/transport/chttp2_transport.c106
-rw-r--r--src/core/transport/metadata.c2
-rw-r--r--src/core/transport/stream_op.c198
-rw-r--r--src/core/transport/stream_op.h54
-rw-r--r--src/cpp/util/byte_buffer.cc1
-rw-r--r--src/csharp/Grpc.Examples.MathServer/MathServer.cs2
-rw-r--r--src/objective-c/GRPCClient/private/GRPCChannel.h5
-rw-r--r--src/objective-c/GRPCClient/private/GRPCChannel.m41
-rw-r--r--src/objective-c/GRPCClient/private/GRPCSecureChannel.h38
-rw-r--r--src/objective-c/GRPCClient/private/GRPCSecureChannel.m52
-rw-r--r--src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.h38
-rw-r--r--src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m44
-rw-r--r--src/objective-c/examples/Sample/Podfile3
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.h103
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.m179
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.h578
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.m2256
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec17
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h81
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m27
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/empty.proto46
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/messages.proto135
-rw-r--r--src/objective-c/examples/Sample/RemoteTestClient/test.proto74
-rw-r--r--src/objective-c/examples/Sample/RouteGuideClient/Route_guide.pb.h (renamed from src/objective-c/examples/Sample/protos/Route_guide.pb.h)0
-rw-r--r--src/objective-c/examples/Sample/RouteGuideClient/Route_guide.pb.m (renamed from src/objective-c/examples/Sample/protos/Route_guide.pb.m)0
-rw-r--r--src/objective-c/examples/Sample/RouteGuideClient/Route_guide.podspec (renamed from src/objective-c/examples/Sample/protos/Route_guide.podspec)2
-rw-r--r--src/objective-c/examples/Sample/RouteGuideClient/route_guide.proto (renamed from src/objective-c/examples/Sample/protos/route_guide.proto)0
-rw-r--r--src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj1556
-rw-r--r--src/objective-c/examples/Sample/Sample/AppDelegate.h1
-rw-r--r--src/objective-c/examples/Sample/Sample/AppDelegate.m25
-rw-r--r--src/objective-c/examples/Sample/Sample/ViewController.h3
-rw-r--r--src/objective-c/examples/Sample/Sample/ViewController.m22
-rw-r--r--src/objective-c/examples/Sample/SampleTests/RemoteTests.m144
-rw-r--r--src/objective-c/examples/Sample/SampleTests/SampleTests.m6
-rw-r--r--src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php1
-rw-r--r--src/python/src/grpc/_adapter/_low_test.py5
54 files changed, 5234 insertions, 2001 deletions
diff --git a/src/core/channel/call_op_string.c b/src/core/channel/call_op_string.c
index 08f2e95deb..5f7e1be268 100644
--- a/src/core/channel/call_op_string.c
+++ b/src/core/channel/call_op_string.c
@@ -43,12 +43,27 @@
static void put_metadata(gpr_strvec *b, grpc_mdelem *md) {
gpr_strvec_add(b, gpr_strdup(" key="));
- gpr_strvec_add(b, gpr_hexdump((char *)GPR_SLICE_START_PTR(md->key->slice),
- GPR_SLICE_LENGTH(md->key->slice), GPR_HEXDUMP_PLAINTEXT));
+ gpr_strvec_add(
+ b, gpr_hexdump((char *)GPR_SLICE_START_PTR(md->key->slice),
+ GPR_SLICE_LENGTH(md->key->slice), GPR_HEXDUMP_PLAINTEXT));
gpr_strvec_add(b, gpr_strdup(" value="));
gpr_strvec_add(b, gpr_hexdump((char *)GPR_SLICE_START_PTR(md->value->slice),
- GPR_SLICE_LENGTH(md->value->slice), GPR_HEXDUMP_PLAINTEXT));
+ GPR_SLICE_LENGTH(md->value->slice),
+ GPR_HEXDUMP_PLAINTEXT));
+}
+
+static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) {
+ grpc_linked_mdelem *m;
+ for (m = md.list.head; m != NULL; m = m->next) {
+ put_metadata(b, m->md);
+ }
+ if (gpr_time_cmp(md.deadline, gpr_inf_future) != 0) {
+ char *tmp;
+ gpr_asprintf(&tmp, " deadline=%d.%09d", md.deadline.tv_sec,
+ md.deadline.tv_nsec);
+ gpr_strvec_add(b, tmp);
+ }
}
char *grpc_call_op_string(grpc_call_op *op) {
@@ -69,16 +84,7 @@ char *grpc_call_op_string(grpc_call_op *op) {
switch (op->type) {
case GRPC_SEND_METADATA:
gpr_strvec_add(&b, gpr_strdup("SEND_METADATA"));
- put_metadata(&b, op->data.metadata);
- break;
- case GRPC_SEND_DEADLINE:
- gpr_asprintf(&tmp, "SEND_DEADLINE %d.%09d", op->data.deadline.tv_sec,
- op->data.deadline.tv_nsec);
- gpr_strvec_add(&b, tmp);
- break;
- case GRPC_SEND_START:
- gpr_asprintf(&tmp, "SEND_START pollset=%p", op->data.start.pollset);
- gpr_strvec_add(&b, tmp);
+ put_metadata_list(&b, op->data.metadata);
break;
case GRPC_SEND_MESSAGE:
gpr_strvec_add(&b, gpr_strdup("SEND_MESSAGE"));
@@ -94,15 +100,7 @@ char *grpc_call_op_string(grpc_call_op *op) {
break;
case GRPC_RECV_METADATA:
gpr_strvec_add(&b, gpr_strdup("RECV_METADATA"));
- put_metadata(&b, op->data.metadata);
- break;
- case GRPC_RECV_DEADLINE:
- gpr_asprintf(&tmp, "RECV_DEADLINE %d.%09d", op->data.deadline.tv_sec,
- op->data.deadline.tv_nsec);
- gpr_strvec_add(&b, tmp);
- break;
- case GRPC_RECV_END_OF_INITIAL_METADATA:
- gpr_strvec_add(&b, gpr_strdup("RECV_END_OF_INITIAL_METADATA"));
+ put_metadata_list(&b, op->data.metadata);
break;
case GRPC_RECV_MESSAGE:
gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE"));
@@ -113,12 +111,21 @@ char *grpc_call_op_string(grpc_call_op *op) {
case GRPC_RECV_FINISH:
gpr_strvec_add(&b, gpr_strdup("RECV_FINISH"));
break;
+ case GRPC_RECV_SYNTHETIC_STATUS:
+ gpr_asprintf(&tmp, "RECV_SYNTHETIC_STATUS status=%d message='%s'",
+ op->data.synthetic_status.status,
+ op->data.synthetic_status.message);
+ gpr_strvec_add(&b, tmp);
+ break;
case GRPC_CANCEL_OP:
gpr_strvec_add(&b, gpr_strdup("CANCEL_OP"));
break;
}
gpr_asprintf(&tmp, " flags=0x%08x", op->flags);
gpr_strvec_add(&b, tmp);
+ if (op->bind_pollset) {
+ gpr_strvec_add(&b, gpr_strdup("bind_pollset"));
+ }
out = gpr_strvec_flatten(&b, NULL);
gpr_strvec_destroy(&b);
diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c
index ba7b7ba59c..9c0c20af22 100644
--- a/src/core/channel/census_filter.c
+++ b/src/core/channel/census_filter.c
@@ -62,11 +62,13 @@ static void init_rpc_stats(census_rpc_stats* stats) {
static void extract_and_annotate_method_tag(grpc_call_op* op, call_data* calld,
channel_data* chand) {
- if (op->data.metadata->key == chand->path_str) {
- gpr_log(GPR_DEBUG,
- (const char*)GPR_SLICE_START_PTR(op->data.metadata->value->slice));
- census_add_method_tag(calld->op_id, (const char*)GPR_SLICE_START_PTR(
- op->data.metadata->value->slice));
+ grpc_linked_mdelem* m;
+ for (m = op->data.metadata.list.head; m != NULL; m = m->next) {
+ if (m->md->key == chand->path_str) {
+ gpr_log(GPR_DEBUG, "%s", (const char*)GPR_SLICE_START_PTR(m->md->value->slice));
+ census_add_method_tag(
+ calld->op_id, (const char*)GPR_SLICE_START_PTR(m->md->value->slice));
+ }
}
}
@@ -178,11 +180,11 @@ static void destroy_channel_elem(grpc_channel_element* elem) {
}
const grpc_channel_filter grpc_client_census_filter = {
- client_call_op, channel_op, sizeof(call_data),
- client_init_call_elem, client_destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "census-client"};
+ client_call_op, channel_op, sizeof(call_data), client_init_call_elem,
+ client_destroy_call_elem, sizeof(channel_data), init_channel_elem,
+ destroy_channel_elem, "census-client"};
const grpc_channel_filter grpc_server_census_filter = {
- server_call_op, channel_op, sizeof(call_data),
- server_init_call_elem, server_destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "census-server"};
+ server_call_op, channel_op, sizeof(call_data), server_init_call_elem,
+ server_destroy_call_elem, sizeof(channel_data), init_channel_elem,
+ destroy_channel_elem, "census-server"};
diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c
index 21df9771ce..3a3a3a75b7 100644
--- a/src/core/channel/channel_stack.c
+++ b/src/core/channel/channel_stack.c
@@ -77,9 +77,9 @@ size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
return size;
}
-#define CHANNEL_ELEMS_FROM_STACK(stk) \
- ((grpc_channel_element *)( \
- (char *)(stk) + ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack))))
+#define CHANNEL_ELEMS_FROM_STACK(stk) \
+ ((grpc_channel_element *)((char *)(stk) + ROUND_UP_TO_ALIGNMENT_SIZE( \
+ sizeof(grpc_channel_stack))))
#define CALL_ELEMS_FROM_STACK(stk) \
((grpc_call_element *)((char *)(stk) + \
@@ -183,6 +183,9 @@ void grpc_call_stack_destroy(grpc_call_stack *stack) {
void grpc_call_next_op(grpc_call_element *elem, grpc_call_op *op) {
grpc_call_element *next_elem = elem + op->dir;
+ if (op->type == GRPC_SEND_METADATA || op->type == GRPC_RECV_METADATA) {
+ grpc_metadata_batch_assert_ok(&op->data.metadata);
+ }
next_elem->filter->call_op(next_elem, elem, op);
}
@@ -193,42 +196,17 @@ void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op) {
grpc_channel_stack *grpc_channel_stack_from_top_element(
grpc_channel_element *elem) {
- return (grpc_channel_stack *)((char *)(elem) -
- ROUND_UP_TO_ALIGNMENT_SIZE(
- sizeof(grpc_channel_stack)));
+ return (grpc_channel_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE(
+ sizeof(grpc_channel_stack)));
}
grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) {
- return (grpc_call_stack *)((char *)(elem) - ROUND_UP_TO_ALIGNMENT_SIZE(
- sizeof(grpc_call_stack)));
+ return (grpc_call_stack *)((char *)(elem)-ROUND_UP_TO_ALIGNMENT_SIZE(
+ sizeof(grpc_call_stack)));
}
static void do_nothing(void *user_data, grpc_op_error error) {}
-void grpc_call_element_recv_metadata(grpc_call_element *cur_elem,
- grpc_mdelem *mdelem) {
- grpc_call_op metadata_op;
- metadata_op.type = GRPC_RECV_METADATA;
- metadata_op.dir = GRPC_CALL_UP;
- metadata_op.done_cb = do_nothing;
- metadata_op.user_data = NULL;
- metadata_op.flags = 0;
- metadata_op.data.metadata = mdelem;
- grpc_call_next_op(cur_elem, &metadata_op);
-}
-
-void grpc_call_element_send_metadata(grpc_call_element *cur_elem,
- grpc_mdelem *mdelem) {
- grpc_call_op metadata_op;
- metadata_op.type = GRPC_SEND_METADATA;
- metadata_op.dir = GRPC_CALL_DOWN;
- metadata_op.done_cb = do_nothing;
- metadata_op.user_data = NULL;
- metadata_op.flags = 0;
- metadata_op.data.metadata = mdelem;
- grpc_call_next_op(cur_elem, &metadata_op);
-}
-
void grpc_call_element_send_cancel(grpc_call_element *cur_elem) {
grpc_call_op cancel_op;
cancel_op.type = GRPC_CANCEL_OP;
@@ -236,6 +214,7 @@ void grpc_call_element_send_cancel(grpc_call_element *cur_elem) {
cancel_op.done_cb = do_nothing;
cancel_op.user_data = NULL;
cancel_op.flags = 0;
+ cancel_op.bind_pollset = NULL;
grpc_call_next_op(cur_elem, &cancel_op);
}
@@ -246,5 +225,19 @@ void grpc_call_element_send_finish(grpc_call_element *cur_elem) {
finish_op.done_cb = do_nothing;
finish_op.user_data = NULL;
finish_op.flags = 0;
+ finish_op.bind_pollset = NULL;
grpc_call_next_op(cur_elem, &finish_op);
}
+
+void grpc_call_element_recv_status(grpc_call_element *cur_elem,
+ grpc_status_code status,
+ const char *message) {
+ grpc_call_op op;
+ op.type = GRPC_RECV_SYNTHETIC_STATUS;
+ op.dir = GRPC_CALL_UP;
+ op.done_cb = do_nothing;
+ op.user_data = NULL;
+ op.data.synthetic_status.status = status;
+ op.data.synthetic_status.message = message;
+ grpc_call_next_op(cur_elem, &op);
+}
diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h
index ef1da7b33b..addc92b272 100644
--- a/src/core/channel/channel_stack.h
+++ b/src/core/channel/channel_stack.h
@@ -62,10 +62,6 @@ typedef struct grpc_call_element grpc_call_element;
typedef enum {
/* send metadata to the channels peer */
GRPC_SEND_METADATA,
- /* send a deadline */
- GRPC_SEND_DEADLINE,
- /* start a connection (corresponds to start_invoke/accept) */
- GRPC_SEND_START,
/* send a message to the channels peer */
GRPC_SEND_MESSAGE,
/* send a pre-formatted message to the channels peer */
@@ -76,16 +72,14 @@ typedef enum {
GRPC_REQUEST_DATA,
/* metadata was received from the channels peer */
GRPC_RECV_METADATA,
- /* receive a deadline */
- GRPC_RECV_DEADLINE,
- /* the end of the first batch of metadata was received */
- GRPC_RECV_END_OF_INITIAL_METADATA,
/* a message was received from the channels peer */
GRPC_RECV_MESSAGE,
/* half-close was received from the channels peer */
GRPC_RECV_HALF_CLOSE,
/* full close was received from the channels peer */
GRPC_RECV_FINISH,
+ /* a status has been sythesized locally */
+ GRPC_RECV_SYNTHETIC_STATUS,
/* the call has been abnormally terminated */
GRPC_CANCEL_OP
} grpc_call_op_type;
@@ -109,14 +103,16 @@ typedef struct {
/* Argument data, matching up with grpc_call_op_type names */
union {
- struct {
- grpc_pollset *pollset;
- } start;
grpc_byte_buffer *message;
- grpc_mdelem *metadata;
- gpr_timespec deadline;
+ grpc_metadata_batch metadata;
+ struct {
+ grpc_status_code status;
+ const char *message;
+ } synthetic_status;
} data;
+ grpc_pollset *bind_pollset;
+
/* Must be called when processing of this call-op is complete.
Signature chosen to match transport flow control callbacks */
void (*done_cb)(void *user_data, grpc_op_error error);
@@ -291,16 +287,15 @@ grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem);
void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
grpc_call_element *elem, grpc_call_op *op);
-void grpc_call_element_send_metadata(grpc_call_element *cur_elem,
- grpc_mdelem *elem);
-void grpc_call_element_recv_metadata(grpc_call_element *cur_elem,
- grpc_mdelem *elem);
void grpc_call_element_send_cancel(grpc_call_element *cur_elem);
void grpc_call_element_send_finish(grpc_call_element *cur_elem);
+void grpc_call_element_recv_status(grpc_call_element *cur_elem,
+ grpc_status_code status,
+ const char *message);
extern int grpc_trace_channel;
#define GRPC_CALL_LOG_OP(sev, elem, op) \
if (grpc_trace_channel) grpc_call_log_op(sev, elem, op)
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H */
+#endif /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H */
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 9791f98be8..bc481e59ca 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -38,7 +38,6 @@
#include "src/core/channel/channel_args.h"
#include "src/core/channel/child_channel.h"
#include "src/core/channel/connected_channel.h"
-#include "src/core/channel/metadata_buffer.h"
#include "src/core/iomgr/iomgr.h"
#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
@@ -70,9 +69,6 @@ typedef struct {
int transport_setup_initiated;
grpc_channel_args *args;
-
- /* metadata cache */
- grpc_mdelem *cancel_status;
} channel_data;
typedef enum {
@@ -86,20 +82,16 @@ struct call_data {
/* owning element */
grpc_call_element *elem;
+ gpr_uint8 got_first_send;
+
call_state state;
- grpc_metadata_buffer pending_metadata;
gpr_timespec deadline;
union {
struct {
/* our child call stack */
grpc_child_call *child_call;
} active;
- struct {
- void (*on_complete)(void *user_data, grpc_op_error error);
- void *on_complete_user_data;
- gpr_uint32 start_flags;
- grpc_pollset *pollset;
- } waiting;
+ grpc_call_op waiting_op;
} s;
};
@@ -127,20 +119,6 @@ static void complete_activate(grpc_call_element *elem, grpc_call_op *op) {
GPR_ASSERT(calld->state == CALL_ACTIVE);
- /* sending buffered metadata down the stack before the start call */
- grpc_metadata_buffer_flush(&calld->pending_metadata, child_elem);
-
- if (gpr_time_cmp(calld->deadline, gpr_inf_future) != 0) {
- grpc_call_op dop;
- dop.type = GRPC_SEND_DEADLINE;
- dop.dir = GRPC_CALL_DOWN;
- dop.flags = 0;
- dop.data.deadline = calld->deadline;
- dop.done_cb = do_nothing;
- dop.user_data = NULL;
- child_elem->filter->call_op(child_elem, elem, &dop);
- }
-
/* continue the start call down the stack, this nees to happen after metadata
are flushed*/
child_elem->filter->call_op(child_elem, elem, op);
@@ -152,6 +130,7 @@ static void start_rpc(grpc_call_element *elem, grpc_call_op *op) {
gpr_mu_lock(&chand->mu);
if (calld->state == CALL_CANCELLED) {
gpr_mu_unlock(&chand->mu);
+ grpc_metadata_batch_destroy(&op->data.metadata);
op->done_cb(op->user_data, GRPC_OP_ERROR);
return;
}
@@ -184,10 +163,7 @@ static void start_rpc(grpc_call_element *elem, grpc_call_op *op) {
gpr_realloc(chand->waiting_children,
chand->waiting_child_capacity * sizeof(call_data *));
}
- calld->s.waiting.on_complete = op->done_cb;
- calld->s.waiting.on_complete_user_data = op->user_data;
- calld->s.waiting.start_flags = op->flags;
- calld->s.waiting.pollset = op->data.start.pollset;
+ calld->s.waiting_op = *op;
chand->waiting_children[chand->waiting_child_count++] = calld;
gpr_mu_unlock(&chand->mu);
@@ -212,15 +188,8 @@ static void remove_waiting_child(channel_data *chand, call_data *calld) {
static void send_up_cancelled_ops(grpc_call_element *elem) {
grpc_call_op finish_op;
- channel_data *chand = elem->channel_data;
/* send up a synthesized status */
- finish_op.type = GRPC_RECV_METADATA;
- finish_op.dir = GRPC_CALL_UP;
- finish_op.flags = 0;
- finish_op.data.metadata = grpc_mdelem_ref(chand->cancel_status);
- finish_op.done_cb = do_nothing;
- finish_op.user_data = NULL;
- grpc_call_next_op(elem, &finish_op);
+ grpc_call_element_recv_status(elem, GRPC_STATUS_CANCELLED, "Cancelled");
/* send up a finish */
finish_op.type = GRPC_RECV_FINISH;
finish_op.dir = GRPC_CALL_UP;
@@ -243,12 +212,12 @@ static void cancel_rpc(grpc_call_element *elem, grpc_call_op *op) {
child_elem->filter->call_op(child_elem, elem, op);
return; /* early out */
case CALL_WAITING:
+ grpc_metadata_batch_destroy(&calld->s.waiting_op.data.metadata);
remove_waiting_child(chand, calld);
calld->state = CALL_CANCELLED;
gpr_mu_unlock(&chand->mu);
send_up_cancelled_ops(elem);
- calld->s.waiting.on_complete(calld->s.waiting.on_complete_user_data,
- GRPC_OP_ERROR);
+ calld->s.waiting_op.done_cb(calld->s.waiting_op.user_data, GRPC_OP_ERROR);
return; /* early out */
case CALL_CREATED:
calld->state = CALL_CANCELLED;
@@ -271,15 +240,13 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
switch (op->type) {
case GRPC_SEND_METADATA:
- grpc_metadata_buffer_queue(&calld->pending_metadata, op);
- break;
- case GRPC_SEND_DEADLINE:
- calld->deadline = op->data.deadline;
- op->done_cb(op->user_data, GRPC_OP_OK);
- break;
- case GRPC_SEND_START:
- /* filter out the start event to find which child to send on */
- start_rpc(elem, op);
+ if (!calld->got_first_send) {
+ /* filter out the start event to find which child to send on */
+ calld->got_first_send = 1;
+ start_rpc(elem, op);
+ } else {
+ grpc_call_next_op(elem, op);
+ }
break;
case GRPC_CANCEL_OP:
cancel_rpc(elem, op);
@@ -382,12 +349,6 @@ static void channel_op(grpc_channel_element *elem,
}
}
-static void error_bad_on_complete(void *arg, grpc_op_error error) {
- gpr_log(GPR_ERROR,
- "Waiting finished but not started? Bad on_complete callback");
- abort();
-}
-
/* Constructor for call_data */
static void init_call_elem(grpc_call_element *elem,
const void *server_transport_data) {
@@ -398,23 +359,22 @@ static void init_call_elem(grpc_call_element *elem,
calld->elem = elem;
calld->state = CALL_CREATED;
calld->deadline = gpr_inf_future;
- calld->s.waiting.on_complete = error_bad_on_complete;
- calld->s.waiting.on_complete_user_data = NULL;
- grpc_metadata_buffer_init(&calld->pending_metadata);
+ calld->got_first_send = 0;
}
/* Destructor for call_data */
static void destroy_call_elem(grpc_call_element *elem) {
call_data *calld = elem->call_data;
- /* if the metadata buffer is not flushed, destroy it here. */
- grpc_metadata_buffer_destroy(&calld->pending_metadata, GRPC_OP_OK);
/* if the call got activated, we need to destroy the child stack also, and
remove it from the in-flight requests tracked by the child_entry we
picked */
if (calld->state == CALL_ACTIVE) {
grpc_child_call_destroy(calld->s.active.child_call);
}
+ if (calld->state == CALL_WAITING) {
+ grpc_metadata_batch_destroy(&calld->s.waiting_op.data.metadata);
+ }
}
/* Constructor for channel_data */
@@ -423,7 +383,6 @@ static void init_channel_elem(grpc_channel_element *elem,
grpc_mdctx *metadata_context, int is_first,
int is_last) {
channel_data *chand = elem->channel_data;
- char temp[GPR_LTOA_MIN_BUFSIZE];
GPR_ASSERT(!is_first);
GPR_ASSERT(is_last);
@@ -437,10 +396,6 @@ static void init_channel_elem(grpc_channel_element *elem,
chand->transport_setup = NULL;
chand->transport_setup_initiated = 0;
chand->args = grpc_channel_args_copy(args);
-
- gpr_ltoa(GRPC_STATUS_CANCELLED, temp);
- chand->cancel_status =
- grpc_mdelem_from_strings(metadata_context, "grpc-status", temp);
}
/* Destructor for channel_data */
@@ -455,7 +410,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
grpc_channel_args_destroy(chand->args);
- grpc_mdelem_unref(chand->cancel_status);
gpr_mu_destroy(&chand->mu);
GPR_ASSERT(chand->waiting_child_count == 0);
@@ -463,9 +417,10 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_client_channel_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "client-channel", };
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+ "client-channel",
+};
grpc_transport_setup_result grpc_client_channel_transport_setup_complete(
grpc_channel_stack *channel_stack, grpc_transport *transport,
@@ -520,13 +475,7 @@ grpc_transport_setup_result grpc_client_channel_transport_setup_complete(
call_ops = gpr_malloc(sizeof(grpc_call_op) * waiting_child_count);
for (i = 0; i < waiting_child_count; i++) {
- call_ops[i].type = GRPC_SEND_START;
- call_ops[i].dir = GRPC_CALL_DOWN;
- call_ops[i].flags = waiting_children[i]->s.waiting.start_flags;
- call_ops[i].done_cb = waiting_children[i]->s.waiting.on_complete;
- call_ops[i].user_data =
- waiting_children[i]->s.waiting.on_complete_user_data;
- call_ops[i].data.start.pollset = waiting_children[i]->s.waiting.pollset;
+ call_ops[i] = waiting_children[i]->s.waiting_op;
if (!prepare_activate(waiting_children[i]->elem, chand->active_child)) {
waiting_children[i] = NULL;
call_ops[i].done_cb(call_ops[i].user_data, GRPC_OP_ERROR);
diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c
index 62611e08f3..711274bfe1 100644
--- a/src/core/channel/connected_channel.c
+++ b/src/core/channel/connected_channel.c
@@ -60,7 +60,6 @@ typedef struct connected_channel_call_data {
gpr_uint32 max_message_length;
gpr_uint32 incoming_message_length;
gpr_uint8 reading_message;
- gpr_uint8 got_metadata_boundary;
gpr_uint8 got_read_close;
gpr_slice_buffer incoming_message;
gpr_uint32 outgoing_buffer_length_estimate;
@@ -120,27 +119,20 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
+ if (op->bind_pollset) {
+ grpc_transport_add_to_pollset(chand->transport, op->bind_pollset);
+ }
+
switch (op->type) {
case GRPC_SEND_METADATA:
grpc_sopb_add_metadata(&calld->outgoing_sopb, op->data.metadata);
- grpc_sopb_add_flow_ctl_cb(&calld->outgoing_sopb, op->done_cb,
- op->user_data);
- break;
- case GRPC_SEND_DEADLINE:
- grpc_sopb_add_deadline(&calld->outgoing_sopb, op->data.deadline);
- grpc_sopb_add_flow_ctl_cb(&calld->outgoing_sopb, op->done_cb,
- op->user_data);
- break;
- case GRPC_SEND_START:
- grpc_transport_add_to_pollset(chand->transport, op->data.start.pollset);
- grpc_sopb_add_metadata_boundary(&calld->outgoing_sopb);
end_bufferable_op(op, chand, calld, 0);
break;
case GRPC_SEND_MESSAGE:
grpc_sopb_add_begin_message(&calld->outgoing_sopb,
grpc_byte_buffer_length(op->data.message),
op->flags);
- /* fall-through */
+ /* fall-through */
case GRPC_SEND_PREFORMATTED_MESSAGE:
copy_byte_buffer_to_stream_ops(op->data.message, &calld->outgoing_sopb);
calld->outgoing_buffer_length_estimate +=
@@ -200,7 +192,6 @@ static void init_call_elem(grpc_call_element *elem,
grpc_sopb_init(&calld->outgoing_sopb);
calld->reading_message = 0;
- calld->got_metadata_boundary = 0;
calld->got_read_close = 0;
calld->outgoing_buffer_length_estimate = 0;
calld->max_message_length = chand->max_message_length;
@@ -259,9 +250,9 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_connected_channel_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "connected", };
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem, "connected",
+};
static gpr_slice alloc_recv_buffer(void *user_data, grpc_transport *transport,
grpc_stream *stream, size_t size_hint) {
@@ -307,8 +298,8 @@ static void finish_message(channel_data *chand, call_data *calld) {
call_op.type = GRPC_RECV_MESSAGE;
call_op.done_cb = do_nothing;
/* TODO(ctiller): this could be a lot faster if coded directly */
- call_op.data.message = grpc_byte_buffer_create(
- calld->incoming_message.slices, calld->incoming_message.count);
+ call_op.data.message = grpc_byte_buffer_create(calld->incoming_message.slices,
+ calld->incoming_message.count);
gpr_slice_buffer_reset_and_unref(&calld->incoming_message);
/* disable window updates until we get a request more from above */
@@ -320,6 +311,19 @@ static void finish_message(channel_data *chand, call_data *calld) {
grpc_call_next_op(elem, &call_op);
}
+static void got_metadata(grpc_call_element *elem,
+ grpc_metadata_batch metadata) {
+ grpc_call_op op;
+ op.type = GRPC_RECV_METADATA;
+ op.dir = GRPC_CALL_UP;
+ op.flags = 0;
+ op.data.metadata = metadata;
+ op.done_cb = do_nothing;
+ op.user_data = NULL;
+
+ grpc_call_next_op(elem, &op);
+}
+
/* Handle incoming stream ops from the transport, translating them into
call_ops to pass up the call stack */
static void recv_batch(void *user_data, grpc_transport *transport,
@@ -339,40 +343,12 @@ static void recv_batch(void *user_data, grpc_transport *transport,
stream_op = ops + i;
switch (stream_op->type) {
case GRPC_OP_FLOW_CTL_CB:
- gpr_log(GPR_ERROR,
- "should not receive flow control ops from transport");
- abort();
+ stream_op->data.flow_ctl_cb.cb(stream_op->data.flow_ctl_cb.arg, 1);
break;
case GRPC_NO_OP:
break;
case GRPC_OP_METADATA:
- call_op.type = GRPC_RECV_METADATA;
- call_op.dir = GRPC_CALL_UP;
- call_op.flags = 0;
- call_op.data.metadata = stream_op->data.metadata;
- call_op.done_cb = do_nothing;
- call_op.user_data = NULL;
- grpc_call_next_op(elem, &call_op);
- break;
- case GRPC_OP_DEADLINE:
- call_op.type = GRPC_RECV_DEADLINE;
- call_op.dir = GRPC_CALL_UP;
- call_op.flags = 0;
- call_op.data.deadline = stream_op->data.deadline;
- call_op.done_cb = do_nothing;
- call_op.user_data = NULL;
- grpc_call_next_op(elem, &call_op);
- break;
- case GRPC_OP_METADATA_BOUNDARY:
- if (!calld->got_metadata_boundary) {
- calld->got_metadata_boundary = 1;
- call_op.type = GRPC_RECV_END_OF_INITIAL_METADATA;
- call_op.dir = GRPC_CALL_UP;
- call_op.flags = 0;
- call_op.done_cb = do_nothing;
- call_op.user_data = NULL;
- grpc_call_next_op(elem, &call_op);
- }
+ got_metadata(elem, stream_op->data.metadata);
break;
case GRPC_OP_BEGIN_MESSAGE:
/* can't begin a message when we're still reading a message */
@@ -495,7 +471,8 @@ static void transport_closed(void *user_data, grpc_transport *transport) {
const grpc_transport_callbacks connected_channel_transport_callbacks = {
alloc_recv_buffer, accept_stream, recv_batch,
- transport_goaway, transport_closed, };
+ transport_goaway, transport_closed,
+};
grpc_transport_setup_result grpc_connected_channel_bind_transport(
grpc_channel_stack *channel_stack, grpc_transport *transport) {
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
index 3ccc39b717..56e12342d7 100644
--- a/src/core/channel/http_client_filter.c
+++ b/src/core/channel/http_client_filter.c
@@ -35,7 +35,10 @@
#include <grpc/support/log.h>
typedef struct call_data {
- int sent_headers;
+ grpc_linked_mdelem method;
+ grpc_linked_mdelem scheme;
+ grpc_linked_mdelem te_trailers;
+ grpc_linked_mdelem content_type;
} call_data;
typedef struct channel_data {
@@ -49,6 +52,18 @@ typedef struct channel_data {
/* used to silence 'variable not used' warnings */
static void ignore_unused(void *ignored) {}
+static grpc_mdelem *client_filter(void *user_data, grpc_mdelem *md) {
+ grpc_call_element *elem = user_data;
+ channel_data *channeld = elem->channel_data;
+ if (md == channeld->status) {
+ return NULL;
+ } else if (md->key == channeld->status->key) {
+ grpc_call_element_send_cancel(elem);
+ return NULL;
+ }
+ return md;
+}
+
/* Called either:
- in response to an API call (or similar) from above, to send something
- a network event (or similar) from below, to receive something
@@ -61,42 +76,23 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
channel_data *channeld = elem->channel_data;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
- ignore_unused(calld);
-
switch (op->type) {
case GRPC_SEND_METADATA:
- if (!calld->sent_headers) {
- /* Send : prefixed headers, which have to be before any application
- * layer headers. */
- calld->sent_headers = 1;
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->method));
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->scheme));
- }
- grpc_call_next_op(elem, op);
- break;
- case GRPC_SEND_START:
- if (!calld->sent_headers) {
- /* Send : prefixed headers, if we haven't already */
- calld->sent_headers = 1;
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->method));
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->scheme));
- }
- /* Send non : prefixed headers */
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->te_trailers));
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(channeld->content_type));
+ /* Send : prefixed headers, which have to be before any application
+ * layer headers. */
+ grpc_metadata_batch_add_head(&op->data.metadata, &calld->method,
+ grpc_mdelem_ref(channeld->method));
+ grpc_metadata_batch_add_head(&op->data.metadata, &calld->scheme,
+ grpc_mdelem_ref(channeld->scheme));
+ grpc_metadata_batch_add_tail(&op->data.metadata, &calld->te_trailers,
+ grpc_mdelem_ref(channeld->te_trailers));
+ grpc_metadata_batch_add_tail(&op->data.metadata, &calld->content_type,
+ grpc_mdelem_ref(channeld->content_type));
grpc_call_next_op(elem, op);
break;
case GRPC_RECV_METADATA:
- if (op->data.metadata == channeld->status) {
- grpc_mdelem_unref(op->data.metadata);
- op->done_cb(op->user_data, GRPC_OP_OK);
- } else if (op->data.metadata->key == channeld->status->key) {
- grpc_mdelem_unref(op->data.metadata);
- op->done_cb(op->user_data, GRPC_OP_OK);
- grpc_call_element_send_cancel(elem);
- } else {
- grpc_call_next_op(elem, op);
- }
+ grpc_metadata_batch_filter(&op->data.metadata, client_filter, elem);
+ grpc_call_next_op(elem, op);
break;
default:
/* pass control up or down the stack depending on op->dir */
@@ -124,16 +120,7 @@ static void channel_op(grpc_channel_element *elem,
/* Constructor for call_data */
static void init_call_elem(grpc_call_element *elem,
- const void *server_transport_data) {
- /* grab pointers to our data from the call element */
- call_data *calld = elem->call_data;
- channel_data *channeld = elem->channel_data;
-
- ignore_unused(channeld);
-
- /* initialize members */
- calld->sent_headers = 0;
-}
+ const void *server_transport_data) {}
/* Destructor for call_data */
static void destroy_call_elem(grpc_call_element *elem) {
@@ -194,6 +181,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
const grpc_channel_filter grpc_http_client_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "http-client"};
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+ "http-client"};
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index 9da8b333ca..0bfe2f2e30 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -38,8 +38,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-typedef enum { NOT_RECEIVED, POST, GET } known_method_type;
-
typedef struct {
grpc_mdelem *path;
grpc_mdelem *content_type;
@@ -47,16 +45,17 @@ typedef struct {
} gettable;
typedef struct call_data {
- known_method_type seen_method;
+ gpr_uint8 got_initial_metadata;
+ gpr_uint8 seen_path;
+ gpr_uint8 seen_post;
gpr_uint8 sent_status;
gpr_uint8 seen_scheme;
gpr_uint8 seen_te_trailers;
- grpc_mdelem *path;
+ grpc_linked_mdelem status;
} call_data;
typedef struct channel_data {
grpc_mdelem *te_trailers;
- grpc_mdelem *method_get;
grpc_mdelem *method_post;
grpc_mdelem *http_scheme;
grpc_mdelem *https_scheme;
@@ -78,38 +77,70 @@ typedef struct channel_data {
/* used to silence 'variable not used' warnings */
static void ignore_unused(void *ignored) {}
-/* Handle 'GET': not technically grpc, so probably a web browser hitting
- us */
-static void payload_done(void *elem, grpc_op_error error) {
- if (error == GRPC_OP_OK) {
- grpc_call_element_send_finish(elem);
- }
-}
-
-static void handle_get(grpc_call_element *elem) {
+static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
+ grpc_call_element *elem = user_data;
channel_data *channeld = elem->channel_data;
call_data *calld = elem->call_data;
- grpc_call_op op;
- size_t i;
- for (i = 0; i < channeld->gettable_count; i++) {
- if (channeld->gettables[i].path == calld->path) {
- grpc_call_element_send_metadata(elem,
- grpc_mdelem_ref(channeld->status_ok));
- grpc_call_element_send_metadata(
- elem, grpc_mdelem_ref(channeld->gettables[i].content_type));
- op.type = GRPC_SEND_PREFORMATTED_MESSAGE;
- op.dir = GRPC_CALL_DOWN;
- op.flags = 0;
- op.data.message = channeld->gettables[i].content;
- op.done_cb = payload_done;
- op.user_data = elem;
- grpc_call_next_op(elem, &op);
+ /* Check if it is one of the headers we care about. */
+ if (md == channeld->te_trailers || md == channeld->method_post ||
+ md == channeld->http_scheme || md == channeld->https_scheme ||
+ md == channeld->grpc_scheme || md == channeld->content_type) {
+ /* swallow it */
+ if (md == channeld->method_post) {
+ calld->seen_post = 1;
+ } else if (md->key == channeld->http_scheme->key) {
+ calld->seen_scheme = 1;
+ } else if (md == channeld->te_trailers) {
+ calld->seen_te_trailers = 1;
}
+ /* TODO(klempner): Track that we've seen all the headers we should
+ require */
+ return NULL;
+ } else if (md->key == channeld->content_type->key) {
+ if (strncmp(grpc_mdstr_as_c_string(md->value), "application/grpc+", 17) ==
+ 0) {
+ /* Although the C implementation doesn't (currently) generate them,
+ any custom +-suffix is explicitly valid. */
+ /* TODO(klempner): We should consider preallocating common values such
+ as +proto or +json, or at least stashing them if we see them. */
+ /* TODO(klempner): Should we be surfacing this to application code? */
+ } else {
+ /* TODO(klempner): We're currently allowing this, but we shouldn't
+ see it without a proxy so log for now. */
+ gpr_log(GPR_INFO, "Unexpected content-type %s",
+ channeld->content_type->key);
+ }
+ return NULL;
+ } else if (md->key == channeld->te_trailers->key ||
+ md->key == channeld->method_post->key ||
+ md->key == channeld->http_scheme->key ||
+ md->key == channeld->content_type->key) {
+ gpr_log(GPR_ERROR, "Invalid %s: header: '%s'",
+ grpc_mdstr_as_c_string(md->key), grpc_mdstr_as_c_string(md->value));
+ /* swallow it and error everything out. */
+ /* TODO(klempner): We ought to generate more descriptive error messages
+ on the wire here. */
+ grpc_call_element_send_cancel(elem);
+ return NULL;
+ } else if (md->key == channeld->path_key) {
+ if (calld->seen_path) {
+ gpr_log(GPR_ERROR, "Received :path twice");
+ return NULL;
+ }
+ calld->seen_path = 1;
+ return md;
+ } else if (md->key == channeld->host_key) {
+ /* translate host to :authority since :authority may be
+ omitted */
+ grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
+ channeld->mdctx, grpc_mdstr_ref(channeld->authority_key),
+ grpc_mdstr_ref(md->value));
+ grpc_mdelem_unref(md);
+ return authority;
+ } else {
+ return md;
}
- grpc_call_element_send_metadata(elem,
- grpc_mdelem_ref(channeld->status_not_found));
- grpc_call_element_send_finish(elem);
}
/* Called either:
@@ -126,115 +157,44 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
switch (op->type) {
case GRPC_RECV_METADATA:
- /* Check if it is one of the headers we care about. */
- if (op->data.metadata == channeld->te_trailers ||
- op->data.metadata == channeld->method_get ||
- op->data.metadata == channeld->method_post ||
- op->data.metadata == channeld->http_scheme ||
- op->data.metadata == channeld->https_scheme ||
- op->data.metadata == channeld->grpc_scheme ||
- op->data.metadata == channeld->content_type) {
- /* swallow it */
- if (op->data.metadata == channeld->method_get) {
- calld->seen_method = GET;
- } else if (op->data.metadata == channeld->method_post) {
- calld->seen_method = POST;
- } else if (op->data.metadata->key == channeld->http_scheme->key) {
- calld->seen_scheme = 1;
- } else if (op->data.metadata == channeld->te_trailers) {
- calld->seen_te_trailers = 1;
- }
- /* TODO(klempner): Track that we've seen all the headers we should
- require */
- grpc_mdelem_unref(op->data.metadata);
- op->done_cb(op->user_data, GRPC_OP_OK);
- } else if (op->data.metadata->key == channeld->content_type->key) {
- if (strncmp(grpc_mdstr_as_c_string(op->data.metadata->value),
- "application/grpc+", 17) == 0) {
- /* Although the C implementation doesn't (currently) generate them,
- any
- custom +-suffix is explicitly valid. */
- /* TODO(klempner): We should consider preallocating common values such
- as +proto or +json, or at least stashing them if we see them. */
- /* TODO(klempner): Should we be surfacing this to application code? */
+ grpc_metadata_batch_filter(&op->data.metadata, server_filter, elem);
+ if (!calld->got_initial_metadata) {
+ calld->got_initial_metadata = 1;
+ /* Have we seen the required http2 transport headers?
+ (:method, :scheme, content-type, with :path and :authority covered
+ at the channel level right now) */
+ if (calld->seen_post && calld->seen_scheme && calld->seen_te_trailers &&
+ calld->seen_path) {
+ grpc_call_next_op(elem, op);
} else {
- /* TODO(klempner): We're currently allowing this, but we shouldn't
- see it without a proxy so log for now. */
- gpr_log(GPR_INFO, "Unexpected content-type %s",
- channeld->content_type->key);
- }
- grpc_mdelem_unref(op->data.metadata);
- op->done_cb(op->user_data, GRPC_OP_OK);
- } else if (op->data.metadata->key == channeld->te_trailers->key ||
- op->data.metadata->key == channeld->method_post->key ||
- op->data.metadata->key == channeld->http_scheme->key ||
- op->data.metadata->key == channeld->content_type->key) {
- gpr_log(GPR_ERROR, "Invalid %s: header: '%s'",
- grpc_mdstr_as_c_string(op->data.metadata->key),
- grpc_mdstr_as_c_string(op->data.metadata->value));
- /* swallow it and error everything out. */
- /* TODO(klempner): We ought to generate more descriptive error messages
- on the wire here. */
- grpc_mdelem_unref(op->data.metadata);
- op->done_cb(op->user_data, GRPC_OP_OK);
- grpc_call_element_send_cancel(elem);
- } else if (op->data.metadata->key == channeld->path_key) {
- if (calld->path != NULL) {
- gpr_log(GPR_ERROR, "Received :path twice");
- grpc_mdelem_unref(calld->path);
+ if (!calld->seen_path) {
+ gpr_log(GPR_ERROR, "Missing :path header");
+ }
+ if (!calld->seen_post) {
+ gpr_log(GPR_ERROR, "Missing :method header");
+ }
+ if (!calld->seen_scheme) {
+ gpr_log(GPR_ERROR, "Missing :scheme header");
+ }
+ if (!calld->seen_te_trailers) {
+ gpr_log(GPR_ERROR, "Missing te trailers header");
+ }
+ /* Error this call out */
+ grpc_metadata_batch_destroy(&op->data.metadata);
+ op->done_cb(op->user_data, GRPC_OP_OK);
+ grpc_call_element_send_cancel(elem);
}
- calld->path = op->data.metadata;
- op->done_cb(op->user_data, GRPC_OP_OK);
- } else if (op->data.metadata->key == channeld->host_key) {
- /* translate host to :authority since :authority may be
- omitted */
- grpc_mdelem *authority = grpc_mdelem_from_metadata_strings(
- channeld->mdctx, grpc_mdstr_ref(channeld->authority_key),
- grpc_mdstr_ref(op->data.metadata->value));
- grpc_mdelem_unref(op->data.metadata);
- op->data.metadata = authority;
- /* pass the event up */
- grpc_call_next_op(elem, op);
} else {
- /* pass the event up */
grpc_call_next_op(elem, op);
}
break;
- case GRPC_RECV_END_OF_INITIAL_METADATA:
- /* Have we seen the required http2 transport headers?
- (:method, :scheme, content-type, with :path and :authority covered
- at the channel level right now) */
- if (calld->seen_method == POST && calld->seen_scheme &&
- calld->seen_te_trailers && calld->path) {
- grpc_call_element_recv_metadata(elem, calld->path);
- calld->path = NULL;
- grpc_call_next_op(elem, op);
- } else if (calld->seen_method == GET) {
- handle_get(elem);
- } else {
- if (calld->seen_method == NOT_RECEIVED) {
- gpr_log(GPR_ERROR, "Missing :method header");
- }
- if (!calld->seen_scheme) {
- gpr_log(GPR_ERROR, "Missing :scheme header");
- }
- if (!calld->seen_te_trailers) {
- gpr_log(GPR_ERROR, "Missing te trailers header");
- }
- /* Error this call out */
- op->done_cb(op->user_data, GRPC_OP_OK);
- grpc_call_element_send_cancel(elem);
- }
- break;
- case GRPC_SEND_START:
case GRPC_SEND_METADATA:
/* If we haven't sent status 200 yet, we need to so so because it needs to
come before any non : prefixed metadata. */
if (!calld->sent_status) {
calld->sent_status = 1;
- /* status is reffed by grpc_call_element_send_metadata */
- grpc_call_element_send_metadata(elem,
- grpc_mdelem_ref(channeld->status_ok));
+ grpc_metadata_batch_add_head(&op->data.metadata, &calld->status,
+ grpc_mdelem_ref(channeld->status_ok));
}
grpc_call_next_op(elem, op);
break;
@@ -272,25 +232,11 @@ static void init_call_elem(grpc_call_element *elem,
ignore_unused(channeld);
/* initialize members */
- calld->path = NULL;
- calld->sent_status = 0;
- calld->seen_scheme = 0;
- calld->seen_method = NOT_RECEIVED;
- calld->seen_te_trailers = 0;
+ memset(calld, 0, sizeof(*calld));
}
/* Destructor for call_data */
-static void destroy_call_elem(grpc_call_element *elem) {
- /* grab pointers to our data from the call element */
- call_data *calld = elem->call_data;
- channel_data *channeld = elem->channel_data;
-
- ignore_unused(channeld);
-
- if (calld->path) {
- grpc_mdelem_unref(calld->path);
- }
-}
+static void destroy_call_elem(grpc_call_element *elem) {}
/* Constructor for channel_data */
static void init_channel_elem(grpc_channel_element *elem,
@@ -314,7 +260,6 @@ static void init_channel_elem(grpc_channel_element *elem,
channeld->status_not_found =
grpc_mdelem_from_strings(mdctx, ":status", "404");
channeld->method_post = grpc_mdelem_from_strings(mdctx, ":method", "POST");
- channeld->method_get = grpc_mdelem_from_strings(mdctx, ":method", "GET");
channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http");
channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https");
channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc");
@@ -369,7 +314,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
grpc_mdelem_unref(channeld->status_ok);
grpc_mdelem_unref(channeld->status_not_found);
grpc_mdelem_unref(channeld->method_post);
- grpc_mdelem_unref(channeld->method_get);
grpc_mdelem_unref(channeld->http_scheme);
grpc_mdelem_unref(channeld->https_scheme);
grpc_mdelem_unref(channeld->grpc_scheme);
diff --git a/src/core/channel/metadata_buffer.c b/src/core/channel/metadata_buffer.c
deleted file mode 100644
index eac852e4a4..0000000000
--- a/src/core/channel/metadata_buffer.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/channel/metadata_buffer.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/useful.h>
-
-#include <string.h>
-
-#define INITIAL_ELEM_CAP 8
-
-/* One queued call; we track offsets to string data in a shared buffer to
- reduce allocations. See grpc_metadata_buffer_impl for the memory use
- strategy */
-typedef struct {
- grpc_mdelem *md;
- void (*cb)(void *user_data, grpc_op_error error);
- void *user_data;
- gpr_uint32 flags;
-} qelem;
-
-/* Memory layout:
-
- grpc_metadata_buffer_impl
- followed by an array of qelem */
-struct grpc_metadata_buffer_impl {
- /* number of elements in q */
- size_t elems;
- /* capacity of q */
- size_t elem_cap;
-};
-
-#define ELEMS(buffer) ((qelem *)((buffer) + 1))
-
-void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer) {
- /* start buffer as NULL, indicating no elements */
- *buffer = NULL;
-}
-
-void grpc_metadata_buffer_destroy(grpc_metadata_buffer *buffer,
- grpc_op_error error) {
- size_t i;
- qelem *qe;
- if (*buffer) {
- for (i = 0; i < (*buffer)->elems; i++) {
- qe = &ELEMS(*buffer)[i];
- grpc_mdelem_unref(qe->md);
- qe->cb(qe->user_data, error);
- }
- gpr_free(*buffer);
- }
-}
-
-void grpc_metadata_buffer_queue(grpc_metadata_buffer *buffer,
- grpc_call_op *op) {
- grpc_metadata_buffer_impl *impl = *buffer;
- qelem *qe;
- size_t bytes;
-
- GPR_ASSERT(op->type == GRPC_SEND_METADATA || op->type == GRPC_RECV_METADATA);
-
- if (!impl) {
- /* this is the first element: allocate enough space to hold the
- header object and the initial element capacity of qelems */
- bytes =
- sizeof(grpc_metadata_buffer_impl) + INITIAL_ELEM_CAP * sizeof(qelem);
- impl = gpr_malloc(bytes);
- /* initialize the header object */
- impl->elems = 0;
- impl->elem_cap = INITIAL_ELEM_CAP;
- } else if (impl->elems == impl->elem_cap) {
- /* more qelems than what we can deal with: grow by doubling size */
- impl->elem_cap *= 2;
- bytes = sizeof(grpc_metadata_buffer_impl) + impl->elem_cap * sizeof(qelem);
- impl = gpr_realloc(impl, bytes);
- }
-
- /* append an element to the queue */
- qe = &ELEMS(impl)[impl->elems];
- impl->elems++;
-
- qe->md = op->data.metadata;
- qe->cb = op->done_cb;
- qe->user_data = op->user_data;
- qe->flags = op->flags;
-
- /* header object may have changed location: store it back */
- *buffer = impl;
-}
-
-void grpc_metadata_buffer_flush(grpc_metadata_buffer *buffer,
- grpc_call_element *elem) {
- grpc_metadata_buffer_impl *impl = *buffer;
- grpc_call_op op;
- qelem *qe;
- size_t i;
-
- if (!impl) {
- /* nothing to send */
- return;
- }
-
- /* construct call_op's, and push them down the stack */
- op.type = GRPC_SEND_METADATA;
- op.dir = GRPC_CALL_DOWN;
- for (i = 0; i < impl->elems; i++) {
- qe = &ELEMS(impl)[i];
- op.done_cb = qe->cb;
- op.user_data = qe->user_data;
- op.flags = qe->flags;
- op.data.metadata = qe->md;
- grpc_call_next_op(elem, &op);
- }
-
- /* free data structures and reset to NULL: we can only flush once */
- gpr_free(impl);
- *buffer = NULL;
-}
diff --git a/src/core/channel/metadata_buffer.h b/src/core/channel/metadata_buffer.h
deleted file mode 100644
index b7cc5170d1..0000000000
--- a/src/core/channel/metadata_buffer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_METADATA_BUFFER_H
-#define GRPC_INTERNAL_CORE_CHANNEL_METADATA_BUFFER_H
-
-#include "src/core/channel/channel_stack.h"
-
-/* Utility code to buffer GRPC_SEND_METADATA calls and pass them down the stack
- all at once at some otherwise-determined time. Useful for implementing
- filters that want to queue metadata until a START event chooses some
- underlying filter stack to send an rpc on. */
-
-/* Clients should declare a member of grpc_metadata_buffer. This may at some
- point become a typedef for a struct, but for now a pointer suffices */
-typedef struct grpc_metadata_buffer_impl grpc_metadata_buffer_impl;
-typedef grpc_metadata_buffer_impl *grpc_metadata_buffer;
-
-/* Initializes the metadata buffer. Allocates no memory. */
-void grpc_metadata_buffer_init(grpc_metadata_buffer *buffer);
-/* Destroy the metadata buffer. */
-void grpc_metadata_buffer_destroy(grpc_metadata_buffer *buffer,
- grpc_op_error error);
-/* Append a call to the end of a metadata buffer: may allocate memory */
-void grpc_metadata_buffer_queue(grpc_metadata_buffer *buffer, grpc_call_op *op);
-/* Flush all queued operations from the metadata buffer to the element below
- self */
-void grpc_metadata_buffer_flush(grpc_metadata_buffer *buffer,
- grpc_call_element *self);
-/* Count the number of queued elements in the buffer. */
-size_t grpc_metadata_buffer_count(const grpc_metadata_buffer *buffer);
-/* Extract elements as a grpc_metadata*, for presentation to applications.
- The returned buffer must be freed with
- grpc_metadata_buffer_cleanup_elements.
- Clears the metadata buffer (this is a one-shot operation) */
-grpc_metadata *grpc_metadata_buffer_extract_elements(
- grpc_metadata_buffer *buffer);
-void grpc_metadata_buffer_cleanup_elements(void *elements, grpc_op_error error);
-
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_METADATA_BUFFER_H */
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index 130698c11b..4af2c67d83 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -44,12 +44,15 @@
#include "src/core/security/credentials.h"
#include "src/core/surface/call.h"
+#define MAX_CREDENTIALS_METADATA_COUNT 4
+
/* We can have a per-call credentials. */
typedef struct {
grpc_credentials *creds;
grpc_mdstr *host;
grpc_mdstr *method;
grpc_call_op op;
+ grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
} call_data;
/* We can have a per-channel credentials. */
@@ -62,30 +65,8 @@ typedef struct {
grpc_mdstr *status_key;
} channel_data;
-static void do_nothing(void *ignored, grpc_op_error error) {}
-
static void bubbleup_error(grpc_call_element *elem, const char *error_msg) {
- grpc_call_op finish_op;
- channel_data *channeld = elem->channel_data;
- char status[GPR_LTOA_MIN_BUFSIZE];
-
- gpr_log(GPR_ERROR, "%s", error_msg);
- finish_op.type = GRPC_RECV_METADATA;
- finish_op.dir = GRPC_CALL_UP;
- finish_op.flags = 0;
- finish_op.data.metadata = grpc_mdelem_from_metadata_strings(
- channeld->md_ctx, grpc_mdstr_ref(channeld->error_msg_key),
- grpc_mdstr_from_string(channeld->md_ctx, error_msg));
- finish_op.done_cb = do_nothing;
- finish_op.user_data = NULL;
- grpc_call_next_op(elem, &finish_op);
-
- gpr_ltoa(GRPC_STATUS_UNAUTHENTICATED, status);
- finish_op.data.metadata = grpc_mdelem_from_metadata_strings(
- channeld->md_ctx, grpc_mdstr_ref(channeld->status_key),
- grpc_mdstr_from_string(channeld->md_ctx, status));
- grpc_call_next_op(elem, &finish_op);
-
+ grpc_call_element_recv_status(elem, GRPC_STATUS_UNAUTHENTICATED, error_msg);
grpc_call_element_send_cancel(elem);
}
@@ -93,11 +74,15 @@ static void on_credentials_metadata(void *user_data, grpc_mdelem **md_elems,
size_t num_md,
grpc_credentials_status status) {
grpc_call_element *elem = (grpc_call_element *)user_data;
+ call_data *calld = elem->call_data;
+ grpc_call_op op = calld->op;
size_t i;
+ GPR_ASSERT(num_md <= MAX_CREDENTIALS_METADATA_COUNT);
for (i = 0; i < num_md; i++) {
- grpc_call_element_send_metadata(elem, grpc_mdelem_ref(md_elems[i]));
+ grpc_metadata_batch_add_tail(&op.data.metadata, &calld->md_links[i],
+ grpc_mdelem_ref(md_elems[i]));
}
- grpc_call_next_op(elem, &((call_data *)elem->call_data)->op);
+ grpc_call_next_op(elem, &op);
}
static char *build_service_url(const char *url_scheme, call_data *calld) {
@@ -159,6 +144,7 @@ static void on_host_checked(void *user_data, grpc_security_status status) {
gpr_asprintf(&error_msg, "Invalid host %s set in :authority metadata.",
grpc_mdstr_as_c_string(calld->host));
bubbleup_error(elem, error_msg);
+ grpc_metadata_batch_destroy(&calld->op.data.metadata);
gpr_free(error_msg);
calld->op.done_cb(calld->op.user_data, GRPC_OP_ERROR);
}
@@ -174,21 +160,22 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
+ grpc_linked_mdelem *l;
switch (op->type) {
case GRPC_SEND_METADATA:
- /* Pointer comparison is OK for md_elems created from the same context. */
- if (op->data.metadata->key == channeld->authority_string) {
- if (calld->host != NULL) grpc_mdstr_unref(calld->host);
- calld->host = grpc_mdstr_ref(op->data.metadata->value);
- } else if (op->data.metadata->key == channeld->path_string) {
- if (calld->method != NULL) grpc_mdstr_unref(calld->method);
- calld->method = grpc_mdstr_ref(op->data.metadata->value);
+ for (l = op->data.metadata.list.head; l != NULL; l = l->next) {
+ grpc_mdelem *md = l->md;
+ /* Pointer comparison is OK for md_elems created from the same context.
+ */
+ if (md->key == channeld->authority_string) {
+ if (calld->host != NULL) grpc_mdstr_unref(calld->host);
+ calld->host = grpc_mdstr_ref(md->value);
+ } else if (md->key == channeld->path_string) {
+ if (calld->method != NULL) grpc_mdstr_unref(calld->method);
+ calld->method = grpc_mdstr_ref(md->value);
+ }
}
- grpc_call_next_op(elem, op);
- break;
-
- case GRPC_SEND_START:
if (calld->host != NULL) {
grpc_security_status status;
const char *call_host = grpc_mdstr_as_c_string(calld->host);
@@ -202,6 +189,7 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
"Invalid host %s set in :authority metadata.",
call_host);
bubbleup_error(elem, error_msg);
+ grpc_metadata_batch_destroy(&calld->op.data.metadata);
gpr_free(error_msg);
op->done_cb(op->user_data, GRPC_OP_ERROR);
}
@@ -210,7 +198,6 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
}
send_security_metadata(elem, op);
break;
-
default:
/* pass control up or down the stack depending on op->dir */
grpc_call_next_op(elem, op);
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index dba63058b8..2949805622 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -33,7 +33,6 @@
#include "src/core/surface/call.h"
#include "src/core/channel/channel_stack.h"
-#include "src/core/channel/metadata_buffer.h"
#include "src/core/iomgr/alarm.h"
#include "src/core/support/string.h"
#include "src/core/surface/byte_buffer_queue.h"
@@ -41,6 +40,7 @@
#include "src/core/surface/completion_queue.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -68,8 +68,10 @@ typedef struct {
} completed_request;
/* See request_set in grpc_call below for a description */
-#define REQSET_EMPTY 255
-#define REQSET_DONE 254
+#define REQSET_EMPTY 'X'
+#define REQSET_DONE 'Y'
+
+#define MAX_SEND_INITIAL_METADATA_COUNT 3
typedef struct {
/* Overall status of the operation: starts OK, may degrade to
@@ -92,6 +94,8 @@ typedef enum {
/* Status came from the application layer overriding whatever
the wire says */
STATUS_FROM_API_OVERRIDE = 0,
+ /* Status was created by some internal channel stack operation */
+ STATUS_FROM_CORE,
/* Status came from 'the wire' - or somewhere below the surface
layer */
STATUS_FROM_WIRE,
@@ -204,12 +208,18 @@ struct grpc_call {
/* Call refcount - to keep the call alive during asynchronous operations */
gpr_refcount internal_refcount;
+ grpc_linked_mdelem send_initial_metadata[MAX_SEND_INITIAL_METADATA_COUNT];
+ grpc_linked_mdelem status_link;
+ grpc_linked_mdelem details_link;
+ size_t send_initial_metadata_count;
+ gpr_timespec send_deadline;
+
/* Data that the legacy api needs to track. To be deleted at some point
soon */
legacy_state *legacy_state;
};
-#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call)+1))
+#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
#define CALL_ELEM_FROM_CALL(call, idx) \
grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
@@ -226,9 +236,13 @@ struct grpc_call {
static void do_nothing(void *ignored, grpc_op_error also_ignored) {}
static send_action choose_send_action(grpc_call *call);
static void enact_send_action(grpc_call *call, send_action sa);
+static void set_deadline_alarm(grpc_call *call, gpr_timespec deadline);
grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
- const void *server_transport_data) {
+ const void *server_transport_data,
+ grpc_mdelem **add_initial_metadata,
+ size_t add_initial_metadata_count,
+ gpr_timespec send_deadline) {
size_t i;
grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
grpc_call *call =
@@ -245,6 +259,12 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
call->request_set[GRPC_IOREQ_SEND_TRAILING_METADATA] = REQSET_DONE;
call->request_set[GRPC_IOREQ_SEND_STATUS] = REQSET_DONE;
}
+ GPR_ASSERT(add_initial_metadata_count < MAX_SEND_INITIAL_METADATA_COUNT);
+ for (i = 0; i < add_initial_metadata_count; i++) {
+ call->send_initial_metadata[i].md = add_initial_metadata[i];
+ }
+ call->send_initial_metadata_count = add_initial_metadata_count;
+ call->send_deadline = send_deadline;
grpc_channel_internal_ref(channel);
call->metadata_context = grpc_channel_get_metadata_context(channel);
/* one ref is dropped in response to destroy, the other in
@@ -252,6 +272,9 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
gpr_ref_init(&call->internal_refcount, 2);
grpc_call_stack_init(channel_stack, server_transport_data,
CALL_STACK_FROM_CALL(call));
+ if (gpr_time_cmp(send_deadline, gpr_inf_future) != 0) {
+ set_deadline_alarm(call, send_deadline);
+ }
return call;
}
@@ -284,6 +307,9 @@ static void destroy_call(void *call, int ignored_success) {
for (i = 0; i < GPR_ARRAY_SIZE(c->buffered_metadata); i++) {
gpr_free(c->buffered_metadata[i].metadata);
}
+ for (i = 0; i < c->send_initial_metadata_count; i++) {
+ grpc_mdelem_unref(c->send_initial_metadata[i].md);
+ }
if (c->legacy_state) {
destroy_legacy_state(c->legacy_state);
}
@@ -342,6 +368,7 @@ static void request_more_data(grpc_call *call) {
op.flags = 0;
op.done_cb = do_nothing;
op.user_data = NULL;
+ op.bind_pollset = NULL;
grpc_call_execute_op(call, &op);
}
@@ -587,15 +614,29 @@ static send_action choose_send_action(grpc_call *call) {
return SEND_NOTHING;
}
-static void send_metadata(grpc_call *call, grpc_mdelem *elem) {
- grpc_call_op op;
- op.type = GRPC_SEND_METADATA;
- op.dir = GRPC_CALL_DOWN;
- op.flags = GRPC_WRITE_BUFFER_HINT;
- op.data.metadata = elem;
- op.done_cb = do_nothing;
- op.user_data = NULL;
- grpc_call_execute_op(call, &op);
+static grpc_mdelem_list chain_metadata_from_app(grpc_call *call, size_t count,
+ grpc_metadata *metadata) {
+ size_t i;
+ grpc_mdelem_list out;
+ if (count == 0) {
+ out.head = out.tail = NULL;
+ return out;
+ }
+ for (i = 0; i < count; i++) {
+ grpc_metadata *md = &metadata[i];
+ grpc_metadata *next_md = (i == count - 1) ? NULL : &metadata[i + 1];
+ grpc_metadata *prev_md = (i == 0) ? NULL : &metadata[i - 1];
+ grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
+ GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
+ l->md = grpc_mdelem_from_string_and_buffer(call->metadata_context, md->key,
+ (const gpr_uint8 *)md->value,
+ md->value_length);
+ l->next = next_md ? (grpc_linked_mdelem *)&next_md->internal_data : NULL;
+ l->prev = prev_md ? (grpc_linked_mdelem *)&prev_md->internal_data : NULL;
+ }
+ out.head = (grpc_linked_mdelem *)&(metadata[0].internal_data);
+ out.tail = (grpc_linked_mdelem *)&(metadata[count - 1].internal_data);
+ return out;
}
static void enact_send_action(grpc_call *call, send_action sa) {
@@ -614,19 +655,21 @@ static void enact_send_action(grpc_call *call, send_action sa) {
/* fallthrough */
case SEND_INITIAL_METADATA:
data = call->request_data[GRPC_IOREQ_SEND_INITIAL_METADATA];
- for (i = 0; i < data.send_metadata.count; i++) {
- const grpc_metadata *md = &data.send_metadata.metadata[i];
- send_metadata(call,
- grpc_mdelem_from_string_and_buffer(
- call->metadata_context, md->key,
- (const gpr_uint8 *)md->value, md->value_length));
- }
- op.type = GRPC_SEND_START;
+ op.type = GRPC_SEND_METADATA;
op.dir = GRPC_CALL_DOWN;
op.flags = flags;
- op.data.start.pollset = grpc_cq_pollset(call->cq);
+ op.data.metadata.list = chain_metadata_from_app(
+ call, data.send_metadata.count, data.send_metadata.metadata);
+ op.data.metadata.garbage.head = op.data.metadata.garbage.tail = NULL;
+ op.data.metadata.deadline = call->send_deadline;
+ for (i = 0; i < call->send_initial_metadata_count; i++) {
+ grpc_metadata_batch_link_head(&op.data.metadata,
+ &call->send_initial_metadata[i]);
+ }
+ call->send_initial_metadata_count = 0;
op.done_cb = finish_start_step;
op.user_data = call;
+ op.bind_pollset = grpc_cq_pollset(call->cq);
grpc_call_execute_op(call, &op);
break;
case SEND_BUFFERED_MESSAGE:
@@ -640,37 +683,42 @@ static void enact_send_action(grpc_call *call, send_action sa) {
op.data.message = data.send_message;
op.done_cb = finish_write_step;
op.user_data = call;
+ op.bind_pollset = NULL;
grpc_call_execute_op(call, &op);
break;
case SEND_TRAILING_METADATA_AND_FINISH:
/* send trailing metadata */
data = call->request_data[GRPC_IOREQ_SEND_TRAILING_METADATA];
- for (i = 0; i < data.send_metadata.count; i++) {
- const grpc_metadata *md = &data.send_metadata.metadata[i];
- send_metadata(call,
- grpc_mdelem_from_string_and_buffer(
- call->metadata_context, md->key,
- (const gpr_uint8 *)md->value, md->value_length));
- }
+ op.type = GRPC_SEND_METADATA;
+ op.dir = GRPC_CALL_DOWN;
+ op.flags = flags;
+ op.data.metadata.list = chain_metadata_from_app(
+ call, data.send_metadata.count, data.send_metadata.metadata);
+ op.data.metadata.garbage.head = op.data.metadata.garbage.tail = NULL;
+ op.data.metadata.deadline = call->send_deadline;
+ op.bind_pollset = NULL;
/* send status */
/* TODO(ctiller): cache common status values */
data = call->request_data[GRPC_IOREQ_SEND_STATUS];
gpr_ltoa(data.send_status.code, status_str);
- send_metadata(
- call,
+ grpc_metadata_batch_add_tail(
+ &op.data.metadata, &call->status_link,
grpc_mdelem_from_metadata_strings(
call->metadata_context,
grpc_mdstr_ref(grpc_channel_get_status_string(call->channel)),
grpc_mdstr_from_string(call->metadata_context, status_str)));
if (data.send_status.details) {
- send_metadata(
- call,
+ grpc_metadata_batch_add_tail(
+ &op.data.metadata, &call->details_link,
grpc_mdelem_from_metadata_strings(
call->metadata_context,
grpc_mdstr_ref(grpc_channel_get_message_string(call->channel)),
grpc_mdstr_from_string(call->metadata_context,
data.send_status.details)));
}
+ op.done_cb = do_nothing;
+ op.user_data = NULL;
+ grpc_call_execute_op(call, &op);
/* fallthrough: see choose_send_action for details */
case SEND_FINISH:
op.type = GRPC_SEND_FINISH;
@@ -678,6 +726,7 @@ static void enact_send_action(grpc_call *call, send_action sa) {
op.flags = 0;
op.done_cb = finish_finish_step;
op.user_data = call;
+ op.bind_pollset = NULL;
grpc_call_execute_op(call, &op);
break;
}
@@ -831,6 +880,7 @@ grpc_call_error grpc_call_cancel(grpc_call *c) {
op.flags = 0;
op.done_cb = do_nothing;
op.user_data = NULL;
+ op.bind_pollset = NULL;
elem = CALL_ELEM_FROM_CALL(c, 0);
elem->filter->call_op(elem, NULL, &op);
@@ -875,9 +925,7 @@ static void call_alarm(void *arg, int success) {
grpc_call_internal_unref(call, 1);
}
-void grpc_call_set_deadline(grpc_call_element *elem, gpr_timespec deadline) {
- grpc_call *call = CALL_FROM_TOP_ELEM(elem);
-
+static void set_deadline_alarm(grpc_call *call, gpr_timespec deadline) {
if (call->have_alarm) {
gpr_log(GPR_ERROR, "Attempt to set deadline alarm twice");
}
@@ -886,11 +934,15 @@ void grpc_call_set_deadline(grpc_call_element *elem, gpr_timespec deadline) {
grpc_alarm_init(&call->alarm, deadline, call_alarm, call, gpr_now());
}
-static void set_read_state(grpc_call *call, read_state state) {
- lock(call);
+static void set_read_state_locked(grpc_call *call, read_state state) {
GPR_ASSERT(call->read_state < state);
call->read_state = state;
finish_read_ops(call);
+}
+
+static void set_read_state(grpc_call *call, read_state state) {
+ lock(call);
+ set_read_state_locked(call, state);
unlock(call);
}
@@ -914,7 +966,7 @@ static gpr_uint32 decode_status(grpc_mdelem *md) {
gpr_uint32 status;
void *user_data = grpc_mdelem_get_user_data(md, destroy_status);
if (user_data) {
- status = ((gpr_uint32)(gpr_intptr) user_data) - STATUS_OFFSET;
+ status = ((gpr_uint32)(gpr_intptr)user_data) - STATUS_OFFSET;
} else {
if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
GPR_SLICE_LENGTH(md->value->slice),
@@ -936,52 +988,81 @@ void grpc_call_recv_message(grpc_call_element *elem,
unlock(call);
}
-void grpc_call_recv_metadata(grpc_call_element *elem, grpc_mdelem *md) {
+void grpc_call_recv_synthetic_status(grpc_call_element *elem,
+ grpc_status_code status,
+ const char *message) {
grpc_call *call = CALL_FROM_TOP_ELEM(elem);
- grpc_mdstr *key = md->key;
+ lock(call);
+ set_status_code(call, STATUS_FROM_CORE, status);
+ set_status_details(call, STATUS_FROM_CORE,
+ grpc_mdstr_from_string(call->metadata_context, message));
+ unlock(call);
+}
+
+int grpc_call_recv_metadata(grpc_call_element *elem, grpc_metadata_batch *md) {
+ grpc_call *call = CALL_FROM_TOP_ELEM(elem);
+ grpc_linked_mdelem *l;
grpc_metadata_array *dest;
grpc_metadata *mdusr;
+ int is_trailing;
+ grpc_mdctx *mdctx = call->metadata_context;
lock(call);
- if (key == grpc_channel_get_status_string(call->channel)) {
- set_status_code(call, STATUS_FROM_WIRE, decode_status(md));
- grpc_mdelem_unref(md);
- } else if (key == grpc_channel_get_message_string(call->channel)) {
- set_status_details(call, STATUS_FROM_WIRE, grpc_mdstr_ref(md->value));
- grpc_mdelem_unref(md);
- } else {
- dest = &call->buffered_metadata[call->read_state >=
- READ_STATE_GOT_INITIAL_METADATA];
- if (dest->count == dest->capacity) {
- dest->capacity = GPR_MAX(dest->capacity + 8, dest->capacity * 2);
- dest->metadata =
- gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity);
- }
- mdusr = &dest->metadata[dest->count++];
- mdusr->key = grpc_mdstr_as_c_string(md->key);
- mdusr->value = grpc_mdstr_as_c_string(md->value);
- mdusr->value_length = GPR_SLICE_LENGTH(md->value->slice);
- if (call->owned_metadata_count == call->owned_metadata_capacity) {
- call->owned_metadata_capacity = GPR_MAX(
- call->owned_metadata_capacity + 8, call->owned_metadata_capacity * 2);
- call->owned_metadata =
- gpr_realloc(call->owned_metadata,
- sizeof(grpc_mdelem *) * call->owned_metadata_capacity);
+ is_trailing = call->read_state >= READ_STATE_GOT_INITIAL_METADATA;
+ for (l = md->list.head; l != NULL; l = l->next) {
+ grpc_mdelem *md = l->md;
+ grpc_mdstr *key = md->key;
+ if (key == grpc_channel_get_status_string(call->channel)) {
+ set_status_code(call, STATUS_FROM_WIRE, decode_status(md));
+ } else if (key == grpc_channel_get_message_string(call->channel)) {
+ set_status_details(call, STATUS_FROM_WIRE, grpc_mdstr_ref(md->value));
+ } else {
+ dest = &call->buffered_metadata[is_trailing];
+ if (dest->count == dest->capacity) {
+ dest->capacity = GPR_MAX(dest->capacity + 8, dest->capacity * 2);
+ dest->metadata =
+ gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity);
+ }
+ mdusr = &dest->metadata[dest->count++];
+ mdusr->key = grpc_mdstr_as_c_string(md->key);
+ mdusr->value = grpc_mdstr_as_c_string(md->value);
+ mdusr->value_length = GPR_SLICE_LENGTH(md->value->slice);
+ if (call->owned_metadata_count == call->owned_metadata_capacity) {
+ call->owned_metadata_capacity =
+ GPR_MAX(call->owned_metadata_capacity + 8,
+ call->owned_metadata_capacity * 2);
+ call->owned_metadata =
+ gpr_realloc(call->owned_metadata,
+ sizeof(grpc_mdelem *) * call->owned_metadata_capacity);
+ }
+ call->owned_metadata[call->owned_metadata_count++] = md;
+ l->md = 0;
}
- call->owned_metadata[call->owned_metadata_count++] = md;
+ }
+ if (gpr_time_cmp(md->deadline, gpr_inf_future) != 0) {
+ set_deadline_alarm(call, md->deadline);
+ }
+ if (!is_trailing) {
+ set_read_state_locked(call, READ_STATE_GOT_INITIAL_METADATA);
}
unlock(call);
+
+ grpc_mdctx_lock(mdctx);
+ for (l = md->list.head; l; l = l->next) {
+ if (l->md) grpc_mdctx_locked_mdelem_unref(mdctx, l->md);
+ }
+ for (l = md->garbage.head; l; l = l->next) {
+ grpc_mdctx_locked_mdelem_unref(mdctx, l->md);
+ }
+ grpc_mdctx_unlock(mdctx);
+
+ return !is_trailing;
}
grpc_call_stack *grpc_call_get_call_stack(grpc_call *call) {
return CALL_STACK_FROM_CALL(call);
}
-void grpc_call_initial_metadata_complete(grpc_call_element *surface_element) {
- grpc_call *call = grpc_call_from_top_element(surface_element);
- set_read_state(call, READ_STATE_GOT_INITIAL_METADATA);
-}
-
/*
* BATCH API IMPLEMENTATION
*/
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index 06434f87ac..f8d0915349 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -35,7 +35,6 @@
#define GRPC_INTERNAL_CORE_SURFACE_CALL_H
#include "src/core/channel/channel_stack.h"
-#include "src/core/channel/metadata_buffer.h"
#include <grpc/grpc.h>
/* Primitive operation types - grpc_op's get rewritten into these */
@@ -67,7 +66,7 @@ typedef union {
} recv_status_details;
struct {
size_t count;
- const grpc_metadata *metadata;
+ grpc_metadata *metadata;
} send_metadata;
grpc_byte_buffer *send_message;
struct {
@@ -86,7 +85,10 @@ typedef void (*grpc_ioreq_completion_func)(grpc_call *call,
void *user_data);
grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
- const void *server_transport_data);
+ const void *server_transport_data,
+ grpc_mdelem **add_initial_metadata,
+ size_t add_initial_metadata_count,
+ gpr_timespec send_deadline);
void grpc_call_set_completion_queue(grpc_call *call, grpc_completion_queue *cq);
grpc_completion_queue *grpc_call_get_completion_queue(grpc_call *call);
@@ -96,8 +98,9 @@ void grpc_call_internal_unref(grpc_call *call, int allow_immediate_deletion);
/* Helpers for grpc_client, grpc_server filters to publish received data to
the completion queue/surface layer */
-void grpc_call_recv_metadata(grpc_call_element *surface_element,
- grpc_mdelem *md);
+/* receive metadata - returns 1 if this was initial metadata */
+int grpc_call_recv_metadata(grpc_call_element *surface_element,
+ grpc_metadata_batch *md);
void grpc_call_recv_message(grpc_call_element *surface_element,
grpc_byte_buffer *message);
void grpc_call_read_closed(grpc_call_element *surface_element);
@@ -108,14 +111,12 @@ grpc_call_error grpc_call_start_ioreq_and_call_back(
grpc_call *call, const grpc_ioreq *reqs, size_t nreqs,
grpc_ioreq_completion_func on_complete, void *user_data);
-/* Called when it's known that the initial batch of metadata is complete */
-void grpc_call_initial_metadata_complete(grpc_call_element *surface_element);
-
-void grpc_call_set_deadline(grpc_call_element *surface_element,
- gpr_timespec deadline);
-
grpc_call_stack *grpc_call_get_call_stack(grpc_call *call);
+void grpc_call_recv_synthetic_status(grpc_call_element *elem,
+ grpc_status_code status,
+ const char *message);
+
/* Given the top call_element, get the call object. */
grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element);
@@ -128,4 +129,4 @@ void grpc_call_log_batch(char *file, int line, gpr_log_severity severity,
#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \
if (grpc_trace_batch) grpc_call_log_batch(sev, call, ops, nops, tag)
-#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */
+#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index d3962a00c4..29b042e7c1 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -62,7 +62,7 @@ struct grpc_channel {
registered_call *registered_calls;
};
-#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1))
+#define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c) + 1))
#define CHANNEL_FROM_CHANNEL_STACK(channel_stack) \
(((grpc_channel *)(channel_stack)) - 1)
#define CHANNEL_FROM_TOP_ELEM(top_elem) \
@@ -91,44 +91,25 @@ grpc_channel *grpc_channel_create_from_filters(
return channel;
}
-static void do_nothing(void *ignored, grpc_op_error error) {}
-
static grpc_call *grpc_channel_create_call_internal(
grpc_channel *channel, grpc_completion_queue *cq, grpc_mdelem *path_mdelem,
grpc_mdelem *authority_mdelem, gpr_timespec deadline) {
- grpc_call *call;
- grpc_call_op op;
+ grpc_mdelem *send_metadata[2];
- if (!channel->is_client) {
- gpr_log(GPR_ERROR, "Cannot create a call on the server.");
- return NULL;
- }
+ GPR_ASSERT(channel->is_client);
- call = grpc_call_create(channel, cq, NULL);
+ send_metadata[0] = path_mdelem;
+ send_metadata[1] = authority_mdelem;
- /* Add :path and :authority headers. */
- op.type = GRPC_SEND_METADATA;
- op.dir = GRPC_CALL_DOWN;
- op.flags = 0;
- op.data.metadata = path_mdelem;
- op.done_cb = do_nothing;
- op.user_data = NULL;
- grpc_call_execute_op(call, &op);
-
- op.data.metadata = authority_mdelem;
- grpc_call_execute_op(call, &op);
-
- if (0 != gpr_time_cmp(deadline, gpr_inf_future)) {
- op.type = GRPC_SEND_DEADLINE;
- op.dir = GRPC_CALL_DOWN;
- op.flags = 0;
- op.data.deadline = deadline;
- op.done_cb = do_nothing;
- op.user_data = NULL;
- grpc_call_execute_op(call, &op);
- }
+ return grpc_call_create(channel, cq, NULL, send_metadata,
+ GPR_ARRAY_SIZE(send_metadata), deadline);
+}
- return call;
+grpc_call *grpc_channel_create_call_old(grpc_channel *channel,
+ const char *method, const char *host,
+ gpr_timespec absolute_deadline) {
+ return grpc_channel_create_call(channel, NULL, method, host,
+ absolute_deadline);
}
grpc_call *grpc_channel_create_call(grpc_channel *channel,
@@ -146,13 +127,6 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
deadline);
}
-grpc_call *grpc_channel_create_call_old(grpc_channel *channel,
- const char *method, const char *host,
- gpr_timespec absolute_deadline) {
- return grpc_channel_create_call(channel, NULL, method, host,
- absolute_deadline);
-}
-
void *grpc_channel_register_call(grpc_channel *channel, const char *method,
const char *host) {
registered_call *rc = gpr_malloc(sizeof(registered_call));
diff --git a/src/core/surface/client.c b/src/core/surface/client.c
index 4d54865d16..2f898ff7d7 100644
--- a/src/core/surface/client.c
+++ b/src/core/surface/client.c
@@ -39,28 +39,17 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-typedef struct {
- void *unused;
-} call_data;
+typedef struct { void *unused; } call_data;
-typedef struct {
- void *unused;
-} channel_data;
+typedef struct { void *unused; } channel_data;
static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
grpc_call_op *op) {
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
switch (op->type) {
- case GRPC_SEND_DEADLINE:
- grpc_call_set_deadline(elem, op->data.deadline);
- grpc_call_next_op(elem, op);
- break;
case GRPC_RECV_METADATA:
- grpc_call_recv_metadata(elem, op->data.metadata);
- break;
- case GRPC_RECV_DEADLINE:
- gpr_log(GPR_ERROR, "Deadline received by client (ignored)");
+ grpc_call_recv_metadata(elem, &op->data.metadata);
break;
case GRPC_RECV_MESSAGE:
grpc_call_recv_message(elem, op->data.message);
@@ -72,8 +61,9 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
case GRPC_RECV_FINISH:
grpc_call_stream_closed(elem);
break;
- case GRPC_RECV_END_OF_INITIAL_METADATA:
- grpc_call_initial_metadata_complete(elem);
+ case GRPC_RECV_SYNTHETIC_STATUS:
+ grpc_call_recv_synthetic_status(elem, op->data.synthetic_status.status,
+ op->data.synthetic_status.message);
break;
default:
GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
@@ -114,6 +104,6 @@ static void init_channel_elem(grpc_channel_element *elem,
static void destroy_channel_elem(grpc_channel_element *elem) {}
const grpc_channel_filter grpc_client_surface_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "client", };
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem, "client",
+};
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index b40c48381f..78170806f1 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -42,28 +42,20 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-typedef struct {
- void *unused;
-} call_data;
+typedef struct { void *unused; } call_data;
-typedef struct {
- grpc_mdelem *status;
- grpc_mdelem *message;
-} channel_data;
+typedef struct { void *unused; } channel_data;
static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
grpc_call_op *op) {
- channel_data *channeld = elem->channel_data;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
switch (op->type) {
- case GRPC_SEND_START:
- grpc_call_recv_metadata(elem, grpc_mdelem_ref(channeld->status));
- grpc_call_recv_metadata(elem, grpc_mdelem_ref(channeld->message));
- grpc_call_stream_closed(elem);
- break;
case GRPC_SEND_METADATA:
- grpc_mdelem_unref(op->data.metadata);
+ grpc_metadata_batch_destroy(&op->data.metadata);
+ grpc_call_recv_synthetic_status(elem, GRPC_STATUS_UNKNOWN,
+ "Rpc sent on a lame channel.");
+ grpc_call_stream_closed(elem);
break;
default:
break;
@@ -94,29 +86,17 @@ static void destroy_call_elem(grpc_call_element *elem) {}
static void init_channel_elem(grpc_channel_element *elem,
const grpc_channel_args *args, grpc_mdctx *mdctx,
int is_first, int is_last) {
- channel_data *channeld = elem->channel_data;
- char status[12];
-
GPR_ASSERT(is_first);
GPR_ASSERT(is_last);
-
- channeld->message = grpc_mdelem_from_strings(mdctx, "grpc-message",
- "Rpc sent on a lame channel.");
- gpr_ltoa(GRPC_STATUS_UNKNOWN, status);
- channeld->status = grpc_mdelem_from_strings(mdctx, "grpc-status", status);
}
-static void destroy_channel_elem(grpc_channel_element *elem) {
- channel_data *channeld = elem->channel_data;
-
- grpc_mdelem_unref(channeld->message);
- grpc_mdelem_unref(channeld->status);
-}
+static void destroy_channel_elem(grpc_channel_element *elem) {}
static const grpc_channel_filter lame_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "lame-client", };
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem,
+ "lame-client",
+};
grpc_channel *grpc_lame_client_channel_create(void) {
static const grpc_channel_filter *filters[] = {&lame_filter};
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 17cba9a505..e771929870 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -411,29 +411,32 @@ static void read_closed(grpc_call_element *elem) {
gpr_mu_unlock(&chand->server->mu);
}
+static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
+ grpc_call_element *elem = user_data;
+ channel_data *chand = elem->channel_data;
+ call_data *calld = elem->call_data;
+ if (md->key == chand->path_key) {
+ calld->path = grpc_mdstr_ref(md->value);
+ return NULL;
+ } else if (md->key == chand->authority_key) {
+ calld->host = grpc_mdstr_ref(md->value);
+ return NULL;
+ }
+ return md;
+}
+
static void call_op(grpc_call_element *elem, grpc_call_element *from_elemn,
grpc_call_op *op) {
- channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
- grpc_mdelem *md;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
switch (op->type) {
case GRPC_RECV_METADATA:
- md = op->data.metadata;
- if (md->key == chand->path_key) {
- calld->path = grpc_mdstr_ref(md->value);
- grpc_mdelem_unref(md);
- } else if (md->key == chand->authority_key) {
- calld->host = grpc_mdstr_ref(md->value);
- grpc_mdelem_unref(md);
- } else {
- grpc_call_recv_metadata(elem, md);
+ grpc_metadata_batch_filter(&op->data.metadata, server_filter, elem);
+ if (grpc_call_recv_metadata(elem, &op->data.metadata)) {
+ calld->deadline = op->data.metadata.deadline;
+ start_new_rpc(elem);
}
break;
- case GRPC_RECV_END_OF_INITIAL_METADATA:
- start_new_rpc(elem);
- grpc_call_initial_metadata_complete(elem);
- break;
case GRPC_RECV_MESSAGE:
grpc_call_recv_message(elem, op->data.message);
op->done_cb(op->user_data, GRPC_OP_OK);
@@ -444,10 +447,6 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elemn,
case GRPC_RECV_FINISH:
stream_closed(elem);
break;
- case GRPC_RECV_DEADLINE:
- grpc_call_set_deadline(elem, op->data.deadline);
- ((call_data *)elem->call_data)->deadline = op->data.deadline;
- break;
default:
GPR_ASSERT(op->dir == GRPC_CALL_DOWN);
grpc_call_next_op(elem, op);
@@ -464,7 +463,8 @@ static void channel_op(grpc_channel_element *elem,
case GRPC_ACCEPT_CALL:
/* create a call */
grpc_call_create(chand->channel, NULL,
- op->data.accept_call.transport_server_data);
+ op->data.accept_call.transport_server_data, NULL, 0,
+ gpr_inf_future);
break;
case GRPC_TRANSPORT_CLOSED:
/* if the transport is closed for a server channel, we destroy the
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 708bb06c7f..5ca31d6bc7 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -43,7 +43,7 @@
#include "src/core/transport/chttp2/timeout_encoding.h"
#include "src/core/transport/chttp2/varint.h"
-#define HASH_FRAGMENT_1(x) ((x) & 255)
+#define HASH_FRAGMENT_1(x) ((x)&255)
#define HASH_FRAGMENT_2(x) ((x >> 8) & 255)
#define HASH_FRAGMENT_3(x) ((x >> 16) & 255)
#define HASH_FRAGMENT_4(x) ((x >> 24) & 255)
@@ -479,10 +479,9 @@ gpr_uint32 grpc_chttp2_preencode(grpc_stream_op *inops, size_t *inops_count,
/* skip */
curop++;
break;
- case GRPC_OP_FLOW_CTL_CB:
- case GRPC_OP_DEADLINE:
case GRPC_OP_METADATA:
- case GRPC_OP_METADATA_BOUNDARY:
+ grpc_metadata_batch_assert_ok(&op->data.metadata);
+ case GRPC_OP_FLOW_CTL_CB:
/* these just get copied as they don't impact the number of flow
controlled bytes */
grpc_sopb_append(outops, op, 1);
@@ -529,6 +528,12 @@ exit_loop:
*inops_count -= curop;
memmove(inops, inops + curop, *inops_count * sizeof(grpc_stream_op));
+ for (curop = 0; curop < *inops_count; curop++) {
+ if (inops[curop].type == GRPC_OP_METADATA) {
+ grpc_metadata_batch_assert_ok(&inops[curop].data.metadata);
+ }
+ }
+
return flow_controlled_bytes_taken;
}
@@ -543,6 +548,7 @@ void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
gpr_uint32 curop = 0;
gpr_uint32 unref_op;
grpc_mdctx *mdctx = compressor->mdctx;
+ grpc_linked_mdelem *l;
int need_unref = 0;
GPR_ASSERT(stream_id != 0);
@@ -566,19 +572,19 @@ void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
curop++;
break;
case GRPC_OP_METADATA:
- /* Encode a metadata element; store the returned value, representing
+ /* Encode a metadata batch; store the returned values, representing
a metadata element that needs to be unreffed back into the metadata
slot. THIS MAY NOT BE THE SAME ELEMENT (if a decoder table slot got
updated). After this loop, we'll do a batch unref of elements. */
- op->data.metadata = hpack_enc(compressor, op->data.metadata, &st);
- need_unref |= op->data.metadata != NULL;
- curop++;
- break;
- case GRPC_OP_DEADLINE:
- deadline_enc(compressor, op->data.deadline, &st);
- curop++;
- break;
- case GRPC_OP_METADATA_BOUNDARY:
+ need_unref |= op->data.metadata.garbage.head != NULL;
+ grpc_metadata_batch_assert_ok(&op->data.metadata);
+ for (l = op->data.metadata.list.head; l; l = l->next) {
+ l->md = hpack_enc(compressor, l->md, &st);
+ need_unref |= l->md != NULL;
+ }
+ if (gpr_time_cmp(op->data.metadata.deadline, gpr_inf_future) != 0) {
+ deadline_enc(compressor, op->data.metadata.deadline, &st);
+ }
ensure_frame_type(&st, HEADER, 0);
finish_frame(&st, 1, 0);
st.last_was_header = 0; /* force a new header frame */
@@ -614,8 +620,12 @@ void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
for (unref_op = 0; unref_op < curop; unref_op++) {
op = &ops[unref_op];
if (op->type != GRPC_OP_METADATA) continue;
- if (!op->data.metadata) continue;
- grpc_mdctx_locked_mdelem_unref(mdctx, op->data.metadata);
+ for (l = op->data.metadata.list.head; l; l = l->next) {
+ if (l->md) grpc_mdctx_locked_mdelem_unref(mdctx, l->md);
+ }
+ for (l = op->data.metadata.garbage.head; l; l = l->next) {
+ grpc_mdctx_locked_mdelem_unref(mdctx, l->md);
+ }
}
grpc_mdctx_unlock(mdctx);
}
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 995d64015a..e32ee284e0 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -68,10 +68,10 @@ int grpc_http_trace = 0;
typedef struct transport transport;
typedef struct stream stream;
-#define IF_TRACING(stmt) \
- if (!(grpc_http_trace)) \
- ; \
- else \
+#define IF_TRACING(stmt) \
+ if (!(grpc_http_trace)) \
+ ; \
+ else \
stmt
/* streams are kept in various linked lists depending on what things need to
@@ -292,6 +292,12 @@ struct stream {
stream_link links[STREAM_LIST_COUNT];
gpr_uint8 included[STREAM_LIST_COUNT];
+ /* incoming metadata */
+ grpc_linked_mdelem *incoming_metadata;
+ size_t incoming_metadata_count;
+ size_t incoming_metadata_capacity;
+ gpr_timespec incoming_deadline;
+
/* sops from application */
grpc_stream_op_buffer outgoing_sopb;
/* sops that have passed flow control to be written */
@@ -577,7 +583,7 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
lock(t);
s->id = 0;
} else {
- s->id = (gpr_uint32)(gpr_uintptr) server_data;
+ s->id = (gpr_uint32)(gpr_uintptr)server_data;
t->incoming_stream = s;
grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
}
@@ -593,6 +599,10 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
s->cancelled = 0;
s->allow_window_updates = 0;
s->published_close = 0;
+ s->incoming_metadata_count = 0;
+ s->incoming_metadata_capacity = 0;
+ s->incoming_metadata = NULL;
+ s->incoming_deadline = gpr_inf_future;
memset(&s->links, 0, sizeof(s->links));
memset(&s->included, 0, sizeof(s->included));
grpc_sopb_init(&s->outgoing_sopb);
@@ -698,7 +708,8 @@ static void stream_list_add_tail(transport *t, stream *s, stream_list_id id) {
}
static void stream_list_join(transport *t, stream *s, stream_list_id id) {
- if (id == PENDING_CALLBACKS) GPR_ASSERT(t->cb != NULL || t->error_state == ERROR_STATE_NONE);
+ if (id == PENDING_CALLBACKS)
+ GPR_ASSERT(t->cb != NULL || t->error_state == ERROR_STATE_NONE);
if (s->included[id]) {
return;
}
@@ -760,7 +771,7 @@ static void unlock(transport *t) {
if (t->error_state == ERROR_STATE_SEEN && !t->writing) {
call_closed = 1;
t->calling_back = 1;
- t->cb = NULL; /* no more callbacks */
+ t->cb = NULL; /* no more callbacks */
t->error_state = ERROR_STATE_NOTIFIED;
}
if (t->num_pending_goaways) {
@@ -782,8 +793,7 @@ static void unlock(transport *t) {
/* perform some callbacks if necessary */
for (i = 0; i < num_goaways; i++) {
- cb->goaway(t->cb_user_data, &t->base, goaways[i].status,
- goaways[i].debug);
+ cb->goaway(t->cb_user_data, &t->base, goaways[i].status, goaways[i].debug);
}
if (perform_callbacks) {
@@ -1058,6 +1068,17 @@ static void finalize_cancellations(transport *t) {
}
}
+static void add_incoming_metadata(transport *t, stream *s, grpc_mdelem *elem) {
+ if (s->incoming_metadata_capacity == s->incoming_metadata_count) {
+ s->incoming_metadata_capacity =
+ GPR_MAX(8, 2 * s->incoming_metadata_capacity);
+ s->incoming_metadata =
+ gpr_realloc(s->incoming_metadata, sizeof(*s->incoming_metadata) *
+ s->incoming_metadata_capacity);
+ }
+ s->incoming_metadata[s->incoming_metadata_count++].md = elem;
+}
+
static void cancel_stream_inner(transport *t, stream *s, gpr_uint32 id,
grpc_status_code local_status,
grpc_chttp2_error_code error_code,
@@ -1077,9 +1098,18 @@ static void cancel_stream_inner(transport *t, stream *s, gpr_uint32 id,
stream_list_join(t, s, CANCELLED);
gpr_ltoa(local_status, buffer);
- grpc_sopb_add_metadata(
- &s->parser.incoming_sopb,
+ add_incoming_metadata(
+ t, s,
grpc_mdelem_from_strings(t->metadata_context, "grpc-status", buffer));
+ switch (local_status) {
+ case GRPC_STATUS_CANCELLED:
+ add_incoming_metadata(
+ t, s, grpc_mdelem_from_strings(t->metadata_context,
+ "grpc-message", "Cancelled"));
+ break;
+ default:
+ break;
+ }
stream_list_join(t, s, PENDING_CALLBACKS);
}
@@ -1255,11 +1285,10 @@ static void on_header(void *tp, grpc_mdelem *md) {
}
grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
}
- grpc_sopb_add_deadline(&s->parser.incoming_sopb,
- gpr_time_add(gpr_now(), *cached_timeout));
+ s->incoming_deadline = gpr_time_add(gpr_now(), *cached_timeout);
grpc_mdelem_unref(md);
} else {
- grpc_sopb_add_metadata(&s->parser.incoming_sopb, md);
+ add_incoming_metadata(t, s, md);
}
}
@@ -1304,7 +1333,7 @@ static int init_header_frame_parser(transport *t, int is_continuation) {
t->incoming_stream = NULL;
/* if stream is accepted, we set incoming_stream in init_stream */
t->cb->accept_stream(t->cb_user_data, &t->base,
- (void *)(gpr_uintptr) t->incoming_stream_id);
+ (void *)(gpr_uintptr)t->incoming_stream_id);
s = t->incoming_stream;
if (!s) {
gpr_log(GPR_ERROR, "stream not accepted");
@@ -1435,6 +1464,35 @@ static int is_window_update_legal(gpr_int64 window_update, gpr_int64 window) {
return window + window_update < MAX_WINDOW;
}
+static void free_md(void *p, grpc_op_error result) { gpr_free(p); }
+
+static void add_metadata_batch(transport *t, stream *s) {
+ grpc_metadata_batch b;
+ size_t i;
+
+ b.list.head = &s->incoming_metadata[0];
+ b.list.tail = &s->incoming_metadata[s->incoming_metadata_count - 1];
+ b.garbage.head = b.garbage.tail = NULL;
+ b.deadline = s->incoming_deadline;
+
+ for (i = 1; i < s->incoming_metadata_count; i++) {
+ s->incoming_metadata[i].prev = &s->incoming_metadata[i - 1];
+ s->incoming_metadata[i - 1].next = &s->incoming_metadata[i];
+ }
+ s->incoming_metadata[0].prev = NULL;
+ s->incoming_metadata[s->incoming_metadata_count - 1].next = NULL;
+
+ grpc_sopb_add_metadata(&s->parser.incoming_sopb, b);
+ grpc_sopb_add_flow_ctl_cb(&s->parser.incoming_sopb, free_md,
+ s->incoming_metadata);
+
+ /* reset */
+ s->incoming_deadline = gpr_inf_future;
+ s->incoming_metadata = NULL;
+ s->incoming_metadata_count = 0;
+ s->incoming_metadata_capacity = 0;
+}
+
static int parse_frame_slice(transport *t, gpr_slice slice, int is_last) {
grpc_chttp2_parse_state st;
size_t i;
@@ -1449,8 +1507,7 @@ static int parse_frame_slice(transport *t, gpr_slice slice, int is_last) {
stream_list_join(t, t->incoming_stream, PENDING_CALLBACKS);
}
if (st.metadata_boundary) {
- grpc_sopb_add_metadata_boundary(
- &t->incoming_stream->parser.incoming_sopb);
+ add_metadata_batch(t, t->incoming_stream);
stream_list_join(t, t->incoming_stream, PENDING_CALLBACKS);
}
if (st.ack_settings) {
@@ -1580,8 +1637,8 @@ static int process_read(transport *t, gpr_slice slice) {
"Connect string mismatch: expected '%c' (%d) got '%c' (%d) "
"at byte %d",
CLIENT_CONNECT_STRING[t->deframe_state],
- (int)(gpr_uint8) CLIENT_CONNECT_STRING[t->deframe_state],
- *cur, (int)*cur, t->deframe_state);
+ (int)(gpr_uint8)CLIENT_CONNECT_STRING[t->deframe_state], *cur,
+ (int)*cur, t->deframe_state);
drop_connection(t);
return 0;
}
@@ -1778,17 +1835,20 @@ static int prepare_callbacks(transport *t) {
int n = 0;
while ((s = stream_list_remove_head(t, PENDING_CALLBACKS))) {
int execute = 1;
- grpc_sopb_swap(&s->parser.incoming_sopb, &s->callback_sopb);
s->callback_state = compute_state(s->sent_write_closed, s->read_closed);
if (s->callback_state == GRPC_STREAM_CLOSED) {
remove_from_stream_map(t, s);
if (s->published_close) {
execute = 0;
+ } else if (s->incoming_metadata_count) {
+ add_metadata_batch(t, s);
}
s->published_close = 1;
}
+ grpc_sopb_swap(&s->parser.incoming_sopb, &s->callback_sopb);
+
if (execute) {
stream_list_add_tail(t, s, EXECUTING_CALLBACKS);
n = 1;
@@ -1825,9 +1885,9 @@ static void add_to_pollset(grpc_transport *gt, grpc_pollset *pollset) {
*/
static const grpc_transport_vtable vtable = {
- sizeof(stream), init_stream, send_batch, set_allow_window_updates,
- add_to_pollset, destroy_stream, abort_stream, goaway,
- close_transport, send_ping, destroy_transport};
+ sizeof(stream), init_stream, send_batch, set_allow_window_updates,
+ add_to_pollset, destroy_stream, abort_stream, goaway, close_transport,
+ send_ping, destroy_transport};
void grpc_create_chttp2_transport(grpc_transport_setup_callback setup,
void *arg,
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index 44f6591c95..74e94b2c24 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -120,7 +120,7 @@ static void unlock(grpc_mdctx *ctx) {
if (ctx->refs == 0) {
/* uncomment if you're having trouble diagnosing an mdelem leak to make
things clearer (slows down destruction a lot, however) */
- /* gc_mdtab(ctx); */
+ gc_mdtab(ctx);
if (ctx->mdtab_count && ctx->mdtab_count == ctx->mdtab_free) {
discard_metadata(ctx);
}
diff --git a/src/core/transport/stream_op.c b/src/core/transport/stream_op.c
index c30e3a27f1..882c078d51 100644
--- a/src/core/transport/stream_op.c
+++ b/src/core/transport/stream_op.c
@@ -33,11 +33,11 @@
#include "src/core/transport/stream_op.h"
+#include <string.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <string.h>
-
/* Exponential growth function: Given x, return a larger x.
Currently we grow by 1.5 times upon reallocation. */
#define GROW(x) (3 * (x) / 2)
@@ -79,33 +79,46 @@ void grpc_stream_ops_unref_owned_objects(grpc_stream_op *ops, size_t nops) {
gpr_slice_unref(ops[i].data.slice);
break;
case GRPC_OP_METADATA:
- grpc_mdelem_unref(ops[i].data.metadata);
+ grpc_metadata_batch_destroy(&ops[i].data.metadata);
break;
case GRPC_OP_FLOW_CTL_CB:
ops[i].data.flow_ctl_cb.cb(ops[i].data.flow_ctl_cb.arg, GRPC_OP_ERROR);
break;
case GRPC_NO_OP:
- case GRPC_OP_DEADLINE:
- case GRPC_OP_METADATA_BOUNDARY:
case GRPC_OP_BEGIN_MESSAGE:
break;
}
}
}
+static void assert_contained_metadata_ok(grpc_stream_op *ops, size_t nops) {
+#ifndef NDEBUG
+ size_t i;
+ for (i = 0; i < nops; i++) {
+ if (ops[i].type == GRPC_OP_METADATA) {
+ grpc_metadata_batch_assert_ok(&ops[i].data.metadata);
+ }
+ }
+#endif /* NDEBUG */
+}
+
static void expandto(grpc_stream_op_buffer *sopb, size_t new_capacity) {
sopb->capacity = new_capacity;
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
if (sopb->ops == sopb->inlined_ops) {
sopb->ops = gpr_malloc(sizeof(grpc_stream_op) * new_capacity);
memcpy(sopb->ops, sopb->inlined_ops, sopb->nops * sizeof(grpc_stream_op));
} else {
sopb->ops = gpr_realloc(sopb->ops, sizeof(grpc_stream_op) * new_capacity);
}
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
}
static grpc_stream_op *add(grpc_stream_op_buffer *sopb) {
grpc_stream_op *out;
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
+
if (sopb->nops == sopb->capacity) {
expandto(sopb, GROW(sopb->capacity));
}
@@ -116,6 +129,7 @@ static grpc_stream_op *add(grpc_stream_op_buffer *sopb) {
void grpc_sopb_add_no_op(grpc_stream_op_buffer *sopb) {
add(sopb)->type = GRPC_NO_OP;
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
}
void grpc_sopb_add_begin_message(grpc_stream_op_buffer *sopb, gpr_uint32 length,
@@ -124,30 +138,24 @@ void grpc_sopb_add_begin_message(grpc_stream_op_buffer *sopb, gpr_uint32 length,
op->type = GRPC_OP_BEGIN_MESSAGE;
op->data.begin_message.length = length;
op->data.begin_message.flags = flags;
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
}
-void grpc_sopb_add_metadata_boundary(grpc_stream_op_buffer *sopb) {
- grpc_stream_op *op = add(sopb);
- op->type = GRPC_OP_METADATA_BOUNDARY;
-}
-
-void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb, grpc_mdelem *md) {
+void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb,
+ grpc_metadata_batch b) {
grpc_stream_op *op = add(sopb);
+ grpc_metadata_batch_assert_ok(&b);
op->type = GRPC_OP_METADATA;
- op->data.metadata = md;
-}
-
-void grpc_sopb_add_deadline(grpc_stream_op_buffer *sopb,
- gpr_timespec deadline) {
- grpc_stream_op *op = add(sopb);
- op->type = GRPC_OP_DEADLINE;
- op->data.deadline = deadline;
+ op->data.metadata = b;
+ grpc_metadata_batch_assert_ok(&op->data.metadata);
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
}
void grpc_sopb_add_slice(grpc_stream_op_buffer *sopb, gpr_slice slice) {
grpc_stream_op *op = add(sopb);
op->type = GRPC_OP_SLICE;
op->data.slice = slice;
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
}
void grpc_sopb_add_flow_ctl_cb(grpc_stream_op_buffer *sopb,
@@ -157,6 +165,7 @@ void grpc_sopb_add_flow_ctl_cb(grpc_stream_op_buffer *sopb,
op->type = GRPC_OP_FLOW_CTL_CB;
op->data.flow_ctl_cb.cb = cb;
op->data.flow_ctl_cb.arg = arg;
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
}
void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
@@ -164,10 +173,161 @@ void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
size_t orig_nops = sopb->nops;
size_t new_nops = orig_nops + nops;
+ assert_contained_metadata_ok(ops, nops);
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
if (new_nops > sopb->capacity) {
expandto(sopb, GPR_MAX(GROW(sopb->capacity), new_nops));
}
memcpy(sopb->ops + orig_nops, ops, sizeof(grpc_stream_op) * nops);
sopb->nops = new_nops;
+ assert_contained_metadata_ok(sopb->ops, sopb->nops);
+}
+
+static void assert_valid_list(grpc_mdelem_list *list) {
+#ifndef NDEBUG
+ grpc_linked_mdelem *l;
+
+ GPR_ASSERT((list->head == NULL) == (list->tail == NULL));
+ if (!list->head) return;
+ GPR_ASSERT(list->head->prev == NULL);
+ GPR_ASSERT(list->tail->next == NULL);
+ GPR_ASSERT((list->head == list->tail) == (list->head->next == NULL));
+
+ for (l = list->head; l; l = l->next) {
+ GPR_ASSERT(l->md);
+ GPR_ASSERT((l->prev == NULL) == (l == list->head));
+ GPR_ASSERT((l->next == NULL) == (l == list->tail));
+ if (l->next) GPR_ASSERT(l->next->prev == l);
+ if (l->prev) GPR_ASSERT(l->prev->next == l);
+ }
+#endif /* NDEBUG */
+}
+
+#ifndef NDEBUG
+void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd) {
+ assert_valid_list(&comd->list);
+ assert_valid_list(&comd->garbage);
+}
+#endif /* NDEBUG */
+
+void grpc_metadata_batch_init(grpc_metadata_batch *comd) {
+ comd->list.head = comd->list.tail = comd->garbage.head = comd->garbage.tail =
+ NULL;
+ comd->deadline = gpr_inf_future;
+}
+
+void grpc_metadata_batch_destroy(grpc_metadata_batch *comd) {
+ grpc_linked_mdelem *l;
+ for (l = comd->list.head; l; l = l->next) {
+ grpc_mdelem_unref(l->md);
+ }
+ for (l = comd->garbage.head; l; l = l->next) {
+ grpc_mdelem_unref(l->md);
+ }
+}
+
+void grpc_metadata_batch_add_head(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage,
+ grpc_mdelem *elem_to_add) {
+ GPR_ASSERT(elem_to_add);
+ storage->md = elem_to_add;
+ grpc_metadata_batch_link_head(comd, storage);
+}
+
+static void link_head(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
+ assert_valid_list(list);
+ GPR_ASSERT(storage->md);
+ storage->prev = NULL;
+ storage->next = list->head;
+ if (list->head != NULL) {
+ list->head->prev = storage;
+ } else {
+ list->tail = storage;
+ }
+ list->head = storage;
+ assert_valid_list(list);
+}
+
+void grpc_metadata_batch_link_head(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage) {
+ link_head(&comd->list, storage);
+}
+
+void grpc_metadata_batch_add_tail(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage,
+ grpc_mdelem *elem_to_add) {
+ GPR_ASSERT(elem_to_add);
+ storage->md = elem_to_add;
+ grpc_metadata_batch_link_tail(comd, storage);
+}
+
+static void link_tail(grpc_mdelem_list *list, grpc_linked_mdelem *storage) {
+ assert_valid_list(list);
+ GPR_ASSERT(storage->md);
+ storage->prev = list->tail;
+ storage->next = NULL;
+ if (list->tail != NULL) {
+ list->tail->next = storage;
+ } else {
+ list->head = storage;
+ }
+ list->tail = storage;
+ assert_valid_list(list);
+}
+
+void grpc_metadata_batch_link_tail(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage) {
+ link_tail(&comd->list, storage);
+}
+
+void grpc_metadata_batch_merge(grpc_metadata_batch *target,
+ grpc_metadata_batch *add) {
+ grpc_linked_mdelem *l;
+ grpc_linked_mdelem *next;
+ for (l = add->list.head; l; l = next) {
+ next = l->next;
+ link_tail(&target->list, l);
+ }
+ for (l = add->garbage.head; l; l = next) {
+ next = l->next;
+ link_tail(&target->garbage, l);
+ }
+}
+
+void grpc_metadata_batch_filter(grpc_metadata_batch *comd,
+ grpc_mdelem *(*filter)(void *user_data,
+ grpc_mdelem *elem),
+ void *user_data) {
+ grpc_linked_mdelem *l;
+ grpc_linked_mdelem *next;
+
+ assert_valid_list(&comd->list);
+ assert_valid_list(&comd->garbage);
+ for (l = comd->list.head; l; l = next) {
+ grpc_mdelem *orig = l->md;
+ grpc_mdelem *filt = filter(user_data, orig);
+ next = l->next;
+ if (filt == NULL) {
+ if (l->prev) {
+ l->prev->next = l->next;
+ }
+ if (l->next) {
+ l->next->prev = l->prev;
+ }
+ if (comd->list.head == l) {
+ comd->list.head = l->next;
+ }
+ if (comd->list.tail == l) {
+ comd->list.tail = l->prev;
+ }
+ assert_valid_list(&comd->list);
+ link_head(&comd->garbage, l);
+ } else if (filt != orig) {
+ grpc_mdelem_unref(orig);
+ l->md = filt;
+ }
+ }
+ assert_valid_list(&comd->list);
+ assert_valid_list(&comd->garbage);
}
diff --git a/src/core/transport/stream_op.h b/src/core/transport/stream_op.h
index 2ffbcce87b..20146b9af2 100644
--- a/src/core/transport/stream_op.h
+++ b/src/core/transport/stream_op.h
@@ -50,8 +50,6 @@ typedef enum grpc_stream_op_code {
Must be ignored by receivers */
GRPC_NO_OP,
GRPC_OP_METADATA,
- GRPC_OP_DEADLINE,
- GRPC_OP_METADATA_BOUNDARY,
/* Begin a message/metadata element/status - as defined by
grpc_message_type. */
GRPC_OP_BEGIN_MESSAGE,
@@ -76,6 +74,51 @@ typedef struct grpc_flow_ctl_cb {
void *arg;
} grpc_flow_ctl_cb;
+typedef struct grpc_linked_mdelem {
+ grpc_mdelem *md;
+ struct grpc_linked_mdelem *next;
+ struct grpc_linked_mdelem *prev;
+} grpc_linked_mdelem;
+
+typedef struct grpc_mdelem_list {
+ grpc_linked_mdelem *head;
+ grpc_linked_mdelem *tail;
+} grpc_mdelem_list;
+
+typedef struct grpc_metadata_batch {
+ grpc_mdelem_list list;
+ grpc_mdelem_list garbage;
+ gpr_timespec deadline;
+} grpc_metadata_batch;
+
+void grpc_metadata_batch_init(grpc_metadata_batch *comd);
+void grpc_metadata_batch_destroy(grpc_metadata_batch *comd);
+void grpc_metadata_batch_merge(grpc_metadata_batch *target,
+ grpc_metadata_batch *add);
+
+void grpc_metadata_batch_link_head(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage);
+void grpc_metadata_batch_link_tail(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage);
+
+void grpc_metadata_batch_add_head(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage,
+ grpc_mdelem *elem_to_add);
+void grpc_metadata_batch_add_tail(grpc_metadata_batch *comd,
+ grpc_linked_mdelem *storage,
+ grpc_mdelem *elem_to_add);
+
+void grpc_metadata_batch_filter(grpc_metadata_batch *comd,
+ grpc_mdelem *(*filter)(void *user_data,
+ grpc_mdelem *elem),
+ void *user_data);
+
+#ifndef NDEBUG
+void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd);
+#else
+#define grpc_metadata_batch_assert_ok(comd) do {} while (0)
+#endif
+
/* Represents a single operation performed on a stream/transport */
typedef struct grpc_stream_op {
/* the operation to be applied */
@@ -84,8 +127,7 @@ typedef struct grpc_stream_op {
associated op-code */
union {
grpc_begin_message begin_message;
- grpc_mdelem *metadata;
- gpr_timespec deadline;
+ grpc_metadata_batch metadata;
gpr_slice slice;
grpc_flow_ctl_cb flow_ctl_cb;
} data;
@@ -118,9 +160,7 @@ void grpc_sopb_add_no_op(grpc_stream_op_buffer *sopb);
/* Append a GRPC_OP_BEGIN to a buffer */
void grpc_sopb_add_begin_message(grpc_stream_op_buffer *sopb, gpr_uint32 length,
gpr_uint32 flags);
-void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb, grpc_mdelem *metadata);
-void grpc_sopb_add_deadline(grpc_stream_op_buffer *sopb, gpr_timespec deadline);
-void grpc_sopb_add_metadata_boundary(grpc_stream_op_buffer *sopb);
+void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb, grpc_metadata_batch metadata);
/* Append a GRPC_SLICE to a buffer - does not ref/unref the slice */
void grpc_sopb_add_slice(grpc_stream_op_buffer *sopb, gpr_slice slice);
/* Append a GRPC_OP_FLOW_CTL_CB to a buffer */
diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc
index f8d8eec065..ac2657472c 100644
--- a/src/cpp/util/byte_buffer.cc
+++ b/src/cpp/util/byte_buffer.cc
@@ -60,7 +60,6 @@ void ByteBuffer::Dump(std::vector<Slice>* slices) {
gpr_slice s;
while (grpc_byte_buffer_reader_next(reader, &s)) {
slices->push_back(Slice(s, Slice::STEAL_REF));
- gpr_slice_unref(s);
}
grpc_byte_buffer_reader_destroy(reader);
}
diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
index 884a84d0a6..f7429fb43f 100644
--- a/src/csharp/Grpc.Examples.MathServer/MathServer.cs
+++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
@@ -46,7 +46,7 @@ namespace math
Server server = new Server();
server.AddServiceDefinition(MathGrpc.BindService(new MathServiceImpl()));
- int port = server.AddListeningPort(host + ":0");
+ int port = server.AddListeningPort(host + ":23456");
server.Start();
Console.WriteLine("MathServer listening on port " + port);
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h
index 2e07dcc3c7..bc6a47d469 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.h
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.h
@@ -45,6 +45,7 @@ struct grpc_channel;
// Convenience constructor to allow for reuse of connections.
+ (instancetype)channelToHost:(NSString *)host;
-// Designated initializer
-- (instancetype)initWithHost:(NSString *)host;
+- (instancetype)initWithHost:(NSString *)host NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithChannel:(struct grpc_channel *)unmanagedChannel NS_DESIGNATED_INITIALIZER;
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m
index 7ddc01dc24..8b7055815d 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.m
@@ -33,7 +33,10 @@
#import "GRPCChannel.h"
-#import <grpc/grpc.h>
+#include <grpc/grpc.h>
+
+#import "GRPCSecureChannel.h"
+#import "GRPCUnsecuredChannel.h"
@implementation GRPCChannel
@@ -46,20 +49,42 @@
return [self initWithHost:nil];
}
-// Designated initializer
- (instancetype)initWithHost:(NSString *)host {
- if (!host) {
- [NSException raise:NSInvalidArgumentException format:@"Host can't be nil."];
+ if (![host containsString:@"://"]) {
+ // No scheme provided; assume https.
+ host = [@"https://" stringByAppendingString:host];
+ }
+ NSURL *hostURL = [NSURL URLWithString:host];
+ if (!hostURL) {
+ [NSException raise:NSInvalidArgumentException format:@"Invalid URL: %@", host];
+ }
+ if ([hostURL.scheme isEqualToString:@"https"]) {
+ host = [@[hostURL.host, hostURL.port ?: @443] componentsJoinedByString:@":"];
+ return [[GRPCSecureChannel alloc] initWithHost:host];
+ }
+ if ([hostURL.scheme isEqualToString:@"http"]) {
+ host = [@[hostURL.host, hostURL.port ?: @80] componentsJoinedByString:@":"];
+ return [[GRPCUnsecuredChannel alloc] initWithHost:host];
}
+ [NSException raise:NSInvalidArgumentException
+ format:@"URL scheme %@ isn't supported.", hostURL.scheme];
+ return nil; // silence warning.
+}
+
+- (instancetype)initWithChannel:(struct grpc_channel *)unmanagedChannel {
if ((self = [super init])) {
- _unmanagedChannel = grpc_channel_create(host.UTF8String, NULL);
+ _unmanagedChannel = unmanagedChannel;
}
return self;
}
- (void)dealloc {
- // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely,
- // as in the past that made this call to crash.
- grpc_channel_destroy(_unmanagedChannel);
+ // _unmanagedChannel is NULL when deallocating an object of the base class (because the
+ // initializer returns a different object).
+ if (_unmanagedChannel) {
+ // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely,
+ // as in the past that made this call to crash.
+ grpc_channel_destroy(_unmanagedChannel);
+ }
}
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.h b/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
new file mode 100644
index 0000000000..d34ceaea0c
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCChannel.h"
+
+@interface GRPCSecureChannel : GRPCChannel
+
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
new file mode 100644
index 0000000000..47bdfe3f28
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCSecureChannel.h"
+
+#import <grpc/grpc_security.h>
+
+@implementation GRPCSecureChannel
+
+- (instancetype)initWithHost:(NSString *)host {
+ // TODO(jcanizales): Load certs only once.
+ NSURL *certsURL = [[NSBundle mainBundle] URLForResource:@"gRPC.bundle/roots" withExtension:@"pem"];
+ NSData *certsData = [NSData dataWithContentsOfURL:certsURL];
+ NSString *certsString = [[NSString alloc] initWithData:certsData encoding:NSUTF8StringEncoding];
+
+ grpc_credentials *credentials = grpc_ssl_credentials_create(certsString.UTF8String, NULL);
+ return (self = [super initWithChannel:grpc_secure_channel_create(credentials,
+ host.UTF8String,
+ NULL)]);
+}
+
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.h b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.h
new file mode 100644
index 0000000000..9d89cfb541
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCChannel.h"
+
+@interface GRPCUnsecuredChannel : GRPCChannel
+
+@end
diff --git a/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m
new file mode 100644
index 0000000000..d27f7ca565
--- /dev/null
+++ b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import "GRPCUnsecuredChannel.h"
+
+#include <grpc/grpc.h>
+
+@implementation GRPCUnsecuredChannel
+
+- (instancetype)initWithHost:(NSString *)host {
+ return (self = [super initWithChannel:grpc_channel_create(host.UTF8String, NULL)]);
+}
+
+@end
diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile
index 31bd4eb821..8b1a90e39b 100644
--- a/src/objective-c/examples/Sample/Podfile
+++ b/src/objective-c/examples/Sample/Podfile
@@ -2,7 +2,8 @@ source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'gRPC', :path => "../../../.."
-pod 'Route_guide', :path => "protos"
+pod 'Route_guide', :path => "RouteGuideClient"
+pod 'RemoteTest', :path => "RemoteTestClient"
link_with 'Sample', 'SampleTests'
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.h b/src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.h
new file mode 100644
index 0000000000..bf9fa3e36f
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.h
@@ -0,0 +1,103 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#import <ProtocolBuffers/ProtocolBuffers.h>
+
+// @@protoc_insertion_point(imports)
+
+@class ObjectiveCFileOptions;
+@class ObjectiveCFileOptionsBuilder;
+@class PBDescriptorProto;
+@class PBDescriptorProtoBuilder;
+@class PBDescriptorProtoExtensionRange;
+@class PBDescriptorProtoExtensionRangeBuilder;
+@class PBEnumDescriptorProto;
+@class PBEnumDescriptorProtoBuilder;
+@class PBEnumOptions;
+@class PBEnumOptionsBuilder;
+@class PBEnumValueDescriptorProto;
+@class PBEnumValueDescriptorProtoBuilder;
+@class PBEnumValueOptions;
+@class PBEnumValueOptionsBuilder;
+@class PBFieldDescriptorProto;
+@class PBFieldDescriptorProtoBuilder;
+@class PBFieldOptions;
+@class PBFieldOptionsBuilder;
+@class PBFileDescriptorProto;
+@class PBFileDescriptorProtoBuilder;
+@class PBFileDescriptorSet;
+@class PBFileDescriptorSetBuilder;
+@class PBFileOptions;
+@class PBFileOptionsBuilder;
+@class PBMessageOptions;
+@class PBMessageOptionsBuilder;
+@class PBMethodDescriptorProto;
+@class PBMethodDescriptorProtoBuilder;
+@class PBMethodOptions;
+@class PBMethodOptionsBuilder;
+@class PBOneofDescriptorProto;
+@class PBOneofDescriptorProtoBuilder;
+@class PBServiceDescriptorProto;
+@class PBServiceDescriptorProtoBuilder;
+@class PBServiceOptions;
+@class PBServiceOptionsBuilder;
+@class PBSourceCodeInfo;
+@class PBSourceCodeInfoBuilder;
+@class PBSourceCodeInfoLocation;
+@class PBSourceCodeInfoLocationBuilder;
+@class PBUninterpretedOption;
+@class PBUninterpretedOptionBuilder;
+@class PBUninterpretedOptionNamePart;
+@class PBUninterpretedOptionNamePartBuilder;
+@class RMTEmpty;
+@class RMTEmptyBuilder;
+
+
+
+@interface RMTEmptyRoot : NSObject {
+}
++ (PBExtensionRegistry*) extensionRegistry;
++ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry;
+@end
+
+@interface RMTEmpty : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+}
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTEmptyBuilder*) builder;
++ (RMTEmptyBuilder*) builder;
++ (RMTEmptyBuilder*) builderWithPrototype:(RMTEmpty*) prototype;
+- (RMTEmptyBuilder*) toBuilder;
+
++ (RMTEmpty*) parseFromData:(NSData*) data;
++ (RMTEmpty*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTEmpty*) parseFromInputStream:(NSInputStream*) input;
++ (RMTEmpty*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTEmpty*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTEmpty*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTEmptyBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTEmpty* resultEmpty;
+}
+
+- (RMTEmpty*) defaultInstance;
+
+- (RMTEmptyBuilder*) clear;
+- (RMTEmptyBuilder*) clone;
+
+- (RMTEmpty*) build;
+- (RMTEmpty*) buildPartial;
+
+- (RMTEmptyBuilder*) mergeFrom:(RMTEmpty*) other;
+- (RMTEmptyBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTEmptyBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.m b/src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.m
new file mode 100644
index 0000000000..8e39cb70d1
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/Empty.pb.m
@@ -0,0 +1,179 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#import "Empty.pb.h"
+// @@protoc_insertion_point(imports)
+
+@implementation RMTEmptyRoot
+static PBExtensionRegistry* extensionRegistry = nil;
++ (PBExtensionRegistry*) extensionRegistry {
+ return extensionRegistry;
+}
+
++ (void) initialize {
+ if (self == [RMTEmptyRoot class]) {
+ PBMutableExtensionRegistry* registry = [PBMutableExtensionRegistry registry];
+ [self registerAllExtensions:registry];
+ [ObjectivecDescriptorRoot registerAllExtensions:registry];
+ extensionRegistry = registry;
+ }
+}
++ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry {
+}
+@end
+
+@interface RMTEmpty ()
+@end
+
+@implementation RMTEmpty
+
+- (instancetype) init {
+ if ((self = [super init])) {
+ }
+ return self;
+}
+static RMTEmpty* defaultRMTEmptyInstance = nil;
++ (void) initialize {
+ if (self == [RMTEmpty class]) {
+ defaultRMTEmptyInstance = [[RMTEmpty alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTEmptyInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTEmptyInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTEmpty*) parseFromData:(NSData*) data {
+ return (RMTEmpty*)[[[RMTEmpty builder] mergeFromData:data] build];
+}
++ (RMTEmpty*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTEmpty*)[[[RMTEmpty builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTEmpty*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTEmpty*)[[[RMTEmpty builder] mergeFromInputStream:input] build];
+}
++ (RMTEmpty*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTEmpty*)[[[RMTEmpty builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTEmpty*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTEmpty*)[[[RMTEmpty builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTEmpty*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTEmpty*)[[[RMTEmpty builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTEmptyBuilder*) builder {
+ return [[RMTEmptyBuilder alloc] init];
+}
++ (RMTEmptyBuilder*) builderWithPrototype:(RMTEmpty*) prototype {
+ return [[RMTEmpty builder] mergeFrom:prototype];
+}
+- (RMTEmptyBuilder*) builder {
+ return [RMTEmpty builder];
+}
+- (RMTEmptyBuilder*) toBuilder {
+ return [RMTEmpty builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTEmpty class]]) {
+ return NO;
+ }
+ RMTEmpty *otherMessage = other;
+ return
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTEmptyBuilder()
+@property (strong) RMTEmpty* resultEmpty;
+@end
+
+@implementation RMTEmptyBuilder
+@synthesize resultEmpty;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultEmpty = [[RMTEmpty alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultEmpty;
+}
+- (RMTEmptyBuilder*) clear {
+ self.resultEmpty = [[RMTEmpty alloc] init];
+ return self;
+}
+- (RMTEmptyBuilder*) clone {
+ return [RMTEmpty builderWithPrototype:resultEmpty];
+}
+- (RMTEmpty*) defaultInstance {
+ return [RMTEmpty defaultInstance];
+}
+- (RMTEmpty*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTEmpty*) buildPartial {
+ RMTEmpty* returnMe = resultEmpty;
+ self.resultEmpty = nil;
+ return returnMe;
+}
+- (RMTEmptyBuilder*) mergeFrom:(RMTEmpty*) other {
+ if (other == [RMTEmpty defaultInstance]) {
+ return self;
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTEmptyBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTEmptyBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ }
+ }
+}
+@end
+
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.h b/src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.h
new file mode 100644
index 0000000000..0a08e67702
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.h
@@ -0,0 +1,578 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#import <ProtocolBuffers/ProtocolBuffers.h>
+
+// @@protoc_insertion_point(imports)
+
+@class ObjectiveCFileOptions;
+@class ObjectiveCFileOptionsBuilder;
+@class PBDescriptorProto;
+@class PBDescriptorProtoBuilder;
+@class PBDescriptorProtoExtensionRange;
+@class PBDescriptorProtoExtensionRangeBuilder;
+@class PBEnumDescriptorProto;
+@class PBEnumDescriptorProtoBuilder;
+@class PBEnumOptions;
+@class PBEnumOptionsBuilder;
+@class PBEnumValueDescriptorProto;
+@class PBEnumValueDescriptorProtoBuilder;
+@class PBEnumValueOptions;
+@class PBEnumValueOptionsBuilder;
+@class PBFieldDescriptorProto;
+@class PBFieldDescriptorProtoBuilder;
+@class PBFieldOptions;
+@class PBFieldOptionsBuilder;
+@class PBFileDescriptorProto;
+@class PBFileDescriptorProtoBuilder;
+@class PBFileDescriptorSet;
+@class PBFileDescriptorSetBuilder;
+@class PBFileOptions;
+@class PBFileOptionsBuilder;
+@class PBMessageOptions;
+@class PBMessageOptionsBuilder;
+@class PBMethodDescriptorProto;
+@class PBMethodDescriptorProtoBuilder;
+@class PBMethodOptions;
+@class PBMethodOptionsBuilder;
+@class PBOneofDescriptorProto;
+@class PBOneofDescriptorProtoBuilder;
+@class PBServiceDescriptorProto;
+@class PBServiceDescriptorProtoBuilder;
+@class PBServiceOptions;
+@class PBServiceOptionsBuilder;
+@class PBSourceCodeInfo;
+@class PBSourceCodeInfoBuilder;
+@class PBSourceCodeInfoLocation;
+@class PBSourceCodeInfoLocationBuilder;
+@class PBUninterpretedOption;
+@class PBUninterpretedOptionBuilder;
+@class PBUninterpretedOptionNamePart;
+@class PBUninterpretedOptionNamePartBuilder;
+@class RMTPayload;
+@class RMTPayloadBuilder;
+@class RMTResponseParameters;
+@class RMTResponseParametersBuilder;
+@class RMTSimpleRequest;
+@class RMTSimpleRequestBuilder;
+@class RMTSimpleResponse;
+@class RMTSimpleResponseBuilder;
+@class RMTStreamingInputCallRequest;
+@class RMTStreamingInputCallRequestBuilder;
+@class RMTStreamingInputCallResponse;
+@class RMTStreamingInputCallResponseBuilder;
+@class RMTStreamingOutputCallRequest;
+@class RMTStreamingOutputCallRequestBuilder;
+@class RMTStreamingOutputCallResponse;
+@class RMTStreamingOutputCallResponseBuilder;
+
+
+typedef NS_ENUM(SInt32, RMTPayloadType) {
+ RMTPayloadTypeCompressable = 0,
+ RMTPayloadTypeUncompressable = 1,
+ RMTPayloadTypeRandom = 2,
+};
+
+BOOL RMTPayloadTypeIsValidValue(RMTPayloadType value);
+NSString *NSStringFromRMTPayloadType(RMTPayloadType value);
+
+
+@interface RMTMessagesRoot : NSObject {
+}
++ (PBExtensionRegistry*) extensionRegistry;
++ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry;
+@end
+
+@interface RMTPayload : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasBody_:1;
+ BOOL hasType_:1;
+ NSData* body;
+ RMTPayloadType type;
+}
+- (BOOL) hasType;
+- (BOOL) hasBody;
+@property (readonly) RMTPayloadType type;
+@property (readonly, strong) NSData* body;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTPayloadBuilder*) builder;
++ (RMTPayloadBuilder*) builder;
++ (RMTPayloadBuilder*) builderWithPrototype:(RMTPayload*) prototype;
+- (RMTPayloadBuilder*) toBuilder;
+
++ (RMTPayload*) parseFromData:(NSData*) data;
++ (RMTPayload*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTPayload*) parseFromInputStream:(NSInputStream*) input;
++ (RMTPayload*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTPayload*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTPayload*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTPayloadBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTPayload* resultPayload;
+}
+
+- (RMTPayload*) defaultInstance;
+
+- (RMTPayloadBuilder*) clear;
+- (RMTPayloadBuilder*) clone;
+
+- (RMTPayload*) build;
+- (RMTPayload*) buildPartial;
+
+- (RMTPayloadBuilder*) mergeFrom:(RMTPayload*) other;
+- (RMTPayloadBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTPayloadBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasType;
+- (RMTPayloadType) type;
+- (RMTPayloadBuilder*) setType:(RMTPayloadType) value;
+- (RMTPayloadBuilder*) clearType;
+
+- (BOOL) hasBody;
+- (NSData*) body;
+- (RMTPayloadBuilder*) setBody:(NSData*) value;
+- (RMTPayloadBuilder*) clearBody;
+@end
+
+@interface RMTSimpleRequest : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasFillUsername_:1;
+ BOOL hasFillOauthScope_:1;
+ BOOL hasResponseSize_:1;
+ BOOL hasPayload_:1;
+ BOOL hasResponseType_:1;
+ BOOL fillUsername_:1;
+ BOOL fillOauthScope_:1;
+ SInt32 responseSize;
+ RMTPayload* payload;
+ RMTPayloadType responseType;
+}
+- (BOOL) hasResponseType;
+- (BOOL) hasResponseSize;
+- (BOOL) hasPayload;
+- (BOOL) hasFillUsername;
+- (BOOL) hasFillOauthScope;
+@property (readonly) RMTPayloadType responseType;
+@property (readonly) SInt32 responseSize;
+@property (readonly, strong) RMTPayload* payload;
+- (BOOL) fillUsername;
+- (BOOL) fillOauthScope;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTSimpleRequestBuilder*) builder;
++ (RMTSimpleRequestBuilder*) builder;
++ (RMTSimpleRequestBuilder*) builderWithPrototype:(RMTSimpleRequest*) prototype;
+- (RMTSimpleRequestBuilder*) toBuilder;
+
++ (RMTSimpleRequest*) parseFromData:(NSData*) data;
++ (RMTSimpleRequest*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTSimpleRequest*) parseFromInputStream:(NSInputStream*) input;
++ (RMTSimpleRequest*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTSimpleRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTSimpleRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTSimpleRequestBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTSimpleRequest* resultSimpleRequest;
+}
+
+- (RMTSimpleRequest*) defaultInstance;
+
+- (RMTSimpleRequestBuilder*) clear;
+- (RMTSimpleRequestBuilder*) clone;
+
+- (RMTSimpleRequest*) build;
+- (RMTSimpleRequest*) buildPartial;
+
+- (RMTSimpleRequestBuilder*) mergeFrom:(RMTSimpleRequest*) other;
+- (RMTSimpleRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTSimpleRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasResponseType;
+- (RMTPayloadType) responseType;
+- (RMTSimpleRequestBuilder*) setResponseType:(RMTPayloadType) value;
+- (RMTSimpleRequestBuilder*) clearResponseType;
+
+- (BOOL) hasResponseSize;
+- (SInt32) responseSize;
+- (RMTSimpleRequestBuilder*) setResponseSize:(SInt32) value;
+- (RMTSimpleRequestBuilder*) clearResponseSize;
+
+- (BOOL) hasPayload;
+- (RMTPayload*) payload;
+- (RMTSimpleRequestBuilder*) setPayload:(RMTPayload*) value;
+- (RMTSimpleRequestBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue;
+- (RMTSimpleRequestBuilder*) mergePayload:(RMTPayload*) value;
+- (RMTSimpleRequestBuilder*) clearPayload;
+
+- (BOOL) hasFillUsername;
+- (BOOL) fillUsername;
+- (RMTSimpleRequestBuilder*) setFillUsername:(BOOL) value;
+- (RMTSimpleRequestBuilder*) clearFillUsername;
+
+- (BOOL) hasFillOauthScope;
+- (BOOL) fillOauthScope;
+- (RMTSimpleRequestBuilder*) setFillOauthScope:(BOOL) value;
+- (RMTSimpleRequestBuilder*) clearFillOauthScope;
+@end
+
+@interface RMTSimpleResponse : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasUsername_:1;
+ BOOL hasOauthScope_:1;
+ BOOL hasPayload_:1;
+ NSString* username;
+ NSString* oauthScope;
+ RMTPayload* payload;
+}
+- (BOOL) hasPayload;
+- (BOOL) hasUsername;
+- (BOOL) hasOauthScope;
+@property (readonly, strong) RMTPayload* payload;
+@property (readonly, strong) NSString* username;
+@property (readonly, strong) NSString* oauthScope;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTSimpleResponseBuilder*) builder;
++ (RMTSimpleResponseBuilder*) builder;
++ (RMTSimpleResponseBuilder*) builderWithPrototype:(RMTSimpleResponse*) prototype;
+- (RMTSimpleResponseBuilder*) toBuilder;
+
++ (RMTSimpleResponse*) parseFromData:(NSData*) data;
++ (RMTSimpleResponse*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTSimpleResponse*) parseFromInputStream:(NSInputStream*) input;
++ (RMTSimpleResponse*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTSimpleResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTSimpleResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTSimpleResponseBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTSimpleResponse* resultSimpleResponse;
+}
+
+- (RMTSimpleResponse*) defaultInstance;
+
+- (RMTSimpleResponseBuilder*) clear;
+- (RMTSimpleResponseBuilder*) clone;
+
+- (RMTSimpleResponse*) build;
+- (RMTSimpleResponse*) buildPartial;
+
+- (RMTSimpleResponseBuilder*) mergeFrom:(RMTSimpleResponse*) other;
+- (RMTSimpleResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTSimpleResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasPayload;
+- (RMTPayload*) payload;
+- (RMTSimpleResponseBuilder*) setPayload:(RMTPayload*) value;
+- (RMTSimpleResponseBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue;
+- (RMTSimpleResponseBuilder*) mergePayload:(RMTPayload*) value;
+- (RMTSimpleResponseBuilder*) clearPayload;
+
+- (BOOL) hasUsername;
+- (NSString*) username;
+- (RMTSimpleResponseBuilder*) setUsername:(NSString*) value;
+- (RMTSimpleResponseBuilder*) clearUsername;
+
+- (BOOL) hasOauthScope;
+- (NSString*) oauthScope;
+- (RMTSimpleResponseBuilder*) setOauthScope:(NSString*) value;
+- (RMTSimpleResponseBuilder*) clearOauthScope;
+@end
+
+@interface RMTStreamingInputCallRequest : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasPayload_:1;
+ RMTPayload* payload;
+}
+- (BOOL) hasPayload;
+@property (readonly, strong) RMTPayload* payload;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTStreamingInputCallRequestBuilder*) builder;
++ (RMTStreamingInputCallRequestBuilder*) builder;
++ (RMTStreamingInputCallRequestBuilder*) builderWithPrototype:(RMTStreamingInputCallRequest*) prototype;
+- (RMTStreamingInputCallRequestBuilder*) toBuilder;
+
++ (RMTStreamingInputCallRequest*) parseFromData:(NSData*) data;
++ (RMTStreamingInputCallRequest*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingInputCallRequest*) parseFromInputStream:(NSInputStream*) input;
++ (RMTStreamingInputCallRequest*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingInputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTStreamingInputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTStreamingInputCallRequestBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTStreamingInputCallRequest* resultStreamingInputCallRequest;
+}
+
+- (RMTStreamingInputCallRequest*) defaultInstance;
+
+- (RMTStreamingInputCallRequestBuilder*) clear;
+- (RMTStreamingInputCallRequestBuilder*) clone;
+
+- (RMTStreamingInputCallRequest*) build;
+- (RMTStreamingInputCallRequest*) buildPartial;
+
+- (RMTStreamingInputCallRequestBuilder*) mergeFrom:(RMTStreamingInputCallRequest*) other;
+- (RMTStreamingInputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTStreamingInputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasPayload;
+- (RMTPayload*) payload;
+- (RMTStreamingInputCallRequestBuilder*) setPayload:(RMTPayload*) value;
+- (RMTStreamingInputCallRequestBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue;
+- (RMTStreamingInputCallRequestBuilder*) mergePayload:(RMTPayload*) value;
+- (RMTStreamingInputCallRequestBuilder*) clearPayload;
+@end
+
+@interface RMTStreamingInputCallResponse : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasAggregatedPayloadSize_:1;
+ SInt32 aggregatedPayloadSize;
+}
+- (BOOL) hasAggregatedPayloadSize;
+@property (readonly) SInt32 aggregatedPayloadSize;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTStreamingInputCallResponseBuilder*) builder;
++ (RMTStreamingInputCallResponseBuilder*) builder;
++ (RMTStreamingInputCallResponseBuilder*) builderWithPrototype:(RMTStreamingInputCallResponse*) prototype;
+- (RMTStreamingInputCallResponseBuilder*) toBuilder;
+
++ (RMTStreamingInputCallResponse*) parseFromData:(NSData*) data;
++ (RMTStreamingInputCallResponse*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingInputCallResponse*) parseFromInputStream:(NSInputStream*) input;
++ (RMTStreamingInputCallResponse*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingInputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTStreamingInputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTStreamingInputCallResponseBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTStreamingInputCallResponse* resultStreamingInputCallResponse;
+}
+
+- (RMTStreamingInputCallResponse*) defaultInstance;
+
+- (RMTStreamingInputCallResponseBuilder*) clear;
+- (RMTStreamingInputCallResponseBuilder*) clone;
+
+- (RMTStreamingInputCallResponse*) build;
+- (RMTStreamingInputCallResponse*) buildPartial;
+
+- (RMTStreamingInputCallResponseBuilder*) mergeFrom:(RMTStreamingInputCallResponse*) other;
+- (RMTStreamingInputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTStreamingInputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasAggregatedPayloadSize;
+- (SInt32) aggregatedPayloadSize;
+- (RMTStreamingInputCallResponseBuilder*) setAggregatedPayloadSize:(SInt32) value;
+- (RMTStreamingInputCallResponseBuilder*) clearAggregatedPayloadSize;
+@end
+
+@interface RMTResponseParameters : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasSize_:1;
+ BOOL hasIntervalUs_:1;
+ SInt32 size;
+ SInt32 intervalUs;
+}
+- (BOOL) hasSize;
+- (BOOL) hasIntervalUs;
+@property (readonly) SInt32 size;
+@property (readonly) SInt32 intervalUs;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTResponseParametersBuilder*) builder;
++ (RMTResponseParametersBuilder*) builder;
++ (RMTResponseParametersBuilder*) builderWithPrototype:(RMTResponseParameters*) prototype;
+- (RMTResponseParametersBuilder*) toBuilder;
+
++ (RMTResponseParameters*) parseFromData:(NSData*) data;
++ (RMTResponseParameters*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTResponseParameters*) parseFromInputStream:(NSInputStream*) input;
++ (RMTResponseParameters*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTResponseParameters*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTResponseParameters*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTResponseParametersBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTResponseParameters* resultResponseParameters;
+}
+
+- (RMTResponseParameters*) defaultInstance;
+
+- (RMTResponseParametersBuilder*) clear;
+- (RMTResponseParametersBuilder*) clone;
+
+- (RMTResponseParameters*) build;
+- (RMTResponseParameters*) buildPartial;
+
+- (RMTResponseParametersBuilder*) mergeFrom:(RMTResponseParameters*) other;
+- (RMTResponseParametersBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTResponseParametersBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasSize;
+- (SInt32) size;
+- (RMTResponseParametersBuilder*) setSize:(SInt32) value;
+- (RMTResponseParametersBuilder*) clearSize;
+
+- (BOOL) hasIntervalUs;
+- (SInt32) intervalUs;
+- (RMTResponseParametersBuilder*) setIntervalUs:(SInt32) value;
+- (RMTResponseParametersBuilder*) clearIntervalUs;
+@end
+
+@interface RMTStreamingOutputCallRequest : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasPayload_:1;
+ BOOL hasResponseType_:1;
+ RMTPayload* payload;
+ RMTPayloadType responseType;
+ NSMutableArray * responseParametersArray;
+}
+- (BOOL) hasResponseType;
+- (BOOL) hasPayload;
+@property (readonly) RMTPayloadType responseType;
+@property (readonly, strong) NSArray * responseParameters;
+@property (readonly, strong) RMTPayload* payload;
+- (RMTResponseParameters*)responseParametersAtIndex:(NSUInteger)index;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTStreamingOutputCallRequestBuilder*) builder;
++ (RMTStreamingOutputCallRequestBuilder*) builder;
++ (RMTStreamingOutputCallRequestBuilder*) builderWithPrototype:(RMTStreamingOutputCallRequest*) prototype;
+- (RMTStreamingOutputCallRequestBuilder*) toBuilder;
+
++ (RMTStreamingOutputCallRequest*) parseFromData:(NSData*) data;
++ (RMTStreamingOutputCallRequest*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingOutputCallRequest*) parseFromInputStream:(NSInputStream*) input;
++ (RMTStreamingOutputCallRequest*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingOutputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTStreamingOutputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTStreamingOutputCallRequestBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTStreamingOutputCallRequest* resultStreamingOutputCallRequest;
+}
+
+- (RMTStreamingOutputCallRequest*) defaultInstance;
+
+- (RMTStreamingOutputCallRequestBuilder*) clear;
+- (RMTStreamingOutputCallRequestBuilder*) clone;
+
+- (RMTStreamingOutputCallRequest*) build;
+- (RMTStreamingOutputCallRequest*) buildPartial;
+
+- (RMTStreamingOutputCallRequestBuilder*) mergeFrom:(RMTStreamingOutputCallRequest*) other;
+- (RMTStreamingOutputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTStreamingOutputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasResponseType;
+- (RMTPayloadType) responseType;
+- (RMTStreamingOutputCallRequestBuilder*) setResponseType:(RMTPayloadType) value;
+- (RMTStreamingOutputCallRequestBuilder*) clearResponseType;
+
+- (NSMutableArray *)responseParameters;
+- (RMTResponseParameters*)responseParametersAtIndex:(NSUInteger)index;
+- (RMTStreamingOutputCallRequestBuilder *)addResponseParameters:(RMTResponseParameters*)value;
+- (RMTStreamingOutputCallRequestBuilder *)setResponseParametersArray:(NSArray *)array;
+- (RMTStreamingOutputCallRequestBuilder *)clearResponseParameters;
+
+- (BOOL) hasPayload;
+- (RMTPayload*) payload;
+- (RMTStreamingOutputCallRequestBuilder*) setPayload:(RMTPayload*) value;
+- (RMTStreamingOutputCallRequestBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue;
+- (RMTStreamingOutputCallRequestBuilder*) mergePayload:(RMTPayload*) value;
+- (RMTStreamingOutputCallRequestBuilder*) clearPayload;
+@end
+
+@interface RMTStreamingOutputCallResponse : PBGeneratedMessage<GeneratedMessageProtocol> {
+@private
+ BOOL hasPayload_:1;
+ RMTPayload* payload;
+}
+- (BOOL) hasPayload;
+@property (readonly, strong) RMTPayload* payload;
+
++ (instancetype) defaultInstance;
+- (instancetype) defaultInstance;
+
+- (BOOL) isInitialized;
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output;
+- (RMTStreamingOutputCallResponseBuilder*) builder;
++ (RMTStreamingOutputCallResponseBuilder*) builder;
++ (RMTStreamingOutputCallResponseBuilder*) builderWithPrototype:(RMTStreamingOutputCallResponse*) prototype;
+- (RMTStreamingOutputCallResponseBuilder*) toBuilder;
+
++ (RMTStreamingOutputCallResponse*) parseFromData:(NSData*) data;
++ (RMTStreamingOutputCallResponse*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingOutputCallResponse*) parseFromInputStream:(NSInputStream*) input;
++ (RMTStreamingOutputCallResponse*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
++ (RMTStreamingOutputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input;
++ (RMTStreamingOutputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+@end
+
+@interface RMTStreamingOutputCallResponseBuilder : PBGeneratedMessageBuilder {
+@private
+ RMTStreamingOutputCallResponse* resultStreamingOutputCallResponse;
+}
+
+- (RMTStreamingOutputCallResponse*) defaultInstance;
+
+- (RMTStreamingOutputCallResponseBuilder*) clear;
+- (RMTStreamingOutputCallResponseBuilder*) clone;
+
+- (RMTStreamingOutputCallResponse*) build;
+- (RMTStreamingOutputCallResponse*) buildPartial;
+
+- (RMTStreamingOutputCallResponseBuilder*) mergeFrom:(RMTStreamingOutputCallResponse*) other;
+- (RMTStreamingOutputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input;
+- (RMTStreamingOutputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
+
+- (BOOL) hasPayload;
+- (RMTPayload*) payload;
+- (RMTStreamingOutputCallResponseBuilder*) setPayload:(RMTPayload*) value;
+- (RMTStreamingOutputCallResponseBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue;
+- (RMTStreamingOutputCallResponseBuilder*) mergePayload:(RMTPayload*) value;
+- (RMTStreamingOutputCallResponseBuilder*) clearPayload;
+@end
+
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.m b/src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.m
new file mode 100644
index 0000000000..fbad1a9c09
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/Messages.pb.m
@@ -0,0 +1,2256 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#import "Messages.pb.h"
+// @@protoc_insertion_point(imports)
+
+@implementation RMTMessagesRoot
+static PBExtensionRegistry* extensionRegistry = nil;
++ (PBExtensionRegistry*) extensionRegistry {
+ return extensionRegistry;
+}
+
++ (void) initialize {
+ if (self == [RMTMessagesRoot class]) {
+ PBMutableExtensionRegistry* registry = [PBMutableExtensionRegistry registry];
+ [self registerAllExtensions:registry];
+ [ObjectivecDescriptorRoot registerAllExtensions:registry];
+ extensionRegistry = registry;
+ }
+}
++ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry {
+}
+@end
+
+BOOL RMTPayloadTypeIsValidValue(RMTPayloadType value) {
+ switch (value) {
+ case RMTPayloadTypeCompressable:
+ case RMTPayloadTypeUncompressable:
+ case RMTPayloadTypeRandom:
+ return YES;
+ default:
+ return NO;
+ }
+}
+NSString *NSStringFromRMTPayloadType(RMTPayloadType value) {
+ switch (value) {
+ case RMTPayloadTypeCompressable:
+ return @"RMTPayloadTypeCompressable";
+ case RMTPayloadTypeUncompressable:
+ return @"RMTPayloadTypeUncompressable";
+ case RMTPayloadTypeRandom:
+ return @"RMTPayloadTypeRandom";
+ default:
+ return nil;
+ }
+}
+
+@interface RMTPayload ()
+@property RMTPayloadType type;
+@property (strong) NSData* body;
+@end
+
+@implementation RMTPayload
+
+- (BOOL) hasType {
+ return !!hasType_;
+}
+- (void) setHasType:(BOOL) _value_ {
+ hasType_ = !!_value_;
+}
+@synthesize type;
+- (BOOL) hasBody {
+ return !!hasBody_;
+}
+- (void) setHasBody:(BOOL) _value_ {
+ hasBody_ = !!_value_;
+}
+@synthesize body;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.type = RMTPayloadTypeCompressable;
+ self.body = [NSData data];
+ }
+ return self;
+}
+static RMTPayload* defaultRMTPayloadInstance = nil;
++ (void) initialize {
+ if (self == [RMTPayload class]) {
+ defaultRMTPayloadInstance = [[RMTPayload alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTPayloadInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTPayloadInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasType) {
+ [output writeEnum:1 value:self.type];
+ }
+ if (self.hasBody) {
+ [output writeData:2 value:self.body];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasType) {
+ size_ += computeEnumSize(1, self.type);
+ }
+ if (self.hasBody) {
+ size_ += computeDataSize(2, self.body);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTPayload*) parseFromData:(NSData*) data {
+ return (RMTPayload*)[[[RMTPayload builder] mergeFromData:data] build];
+}
++ (RMTPayload*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTPayload*)[[[RMTPayload builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTPayload*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTPayload*)[[[RMTPayload builder] mergeFromInputStream:input] build];
+}
++ (RMTPayload*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTPayload*)[[[RMTPayload builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTPayload*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTPayload*)[[[RMTPayload builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTPayload*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTPayload*)[[[RMTPayload builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTPayloadBuilder*) builder {
+ return [[RMTPayloadBuilder alloc] init];
+}
++ (RMTPayloadBuilder*) builderWithPrototype:(RMTPayload*) prototype {
+ return [[RMTPayload builder] mergeFrom:prototype];
+}
+- (RMTPayloadBuilder*) builder {
+ return [RMTPayload builder];
+}
+- (RMTPayloadBuilder*) toBuilder {
+ return [RMTPayload builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasType) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"type", NSStringFromRMTPayloadType(self.type)];
+ }
+ if (self.hasBody) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"body", self.body];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTPayload class]]) {
+ return NO;
+ }
+ RMTPayload *otherMessage = other;
+ return
+ self.hasType == otherMessage.hasType &&
+ (!self.hasType || self.type == otherMessage.type) &&
+ self.hasBody == otherMessage.hasBody &&
+ (!self.hasBody || [self.body isEqual:otherMessage.body]) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasType) {
+ hashCode = hashCode * 31 + self.type;
+ }
+ if (self.hasBody) {
+ hashCode = hashCode * 31 + [self.body hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTPayloadBuilder()
+@property (strong) RMTPayload* resultPayload;
+@end
+
+@implementation RMTPayloadBuilder
+@synthesize resultPayload;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultPayload = [[RMTPayload alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultPayload;
+}
+- (RMTPayloadBuilder*) clear {
+ self.resultPayload = [[RMTPayload alloc] init];
+ return self;
+}
+- (RMTPayloadBuilder*) clone {
+ return [RMTPayload builderWithPrototype:resultPayload];
+}
+- (RMTPayload*) defaultInstance {
+ return [RMTPayload defaultInstance];
+}
+- (RMTPayload*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTPayload*) buildPartial {
+ RMTPayload* returnMe = resultPayload;
+ self.resultPayload = nil;
+ return returnMe;
+}
+- (RMTPayloadBuilder*) mergeFrom:(RMTPayload*) other {
+ if (other == [RMTPayload defaultInstance]) {
+ return self;
+ }
+ if (other.hasType) {
+ [self setType:other.type];
+ }
+ if (other.hasBody) {
+ [self setBody:other.body];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTPayloadBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTPayloadBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 8: {
+ RMTPayloadType value = (RMTPayloadType)[input readEnum];
+ if (RMTPayloadTypeIsValidValue(value)) {
+ [self setType:value];
+ } else {
+ [unknownFields mergeVarintField:1 value:value];
+ }
+ break;
+ }
+ case 18: {
+ [self setBody:[input readData]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasType {
+ return resultPayload.hasType;
+}
+- (RMTPayloadType) type {
+ return resultPayload.type;
+}
+- (RMTPayloadBuilder*) setType:(RMTPayloadType) value {
+ resultPayload.hasType = YES;
+ resultPayload.type = value;
+ return self;
+}
+- (RMTPayloadBuilder*) clearType {
+ resultPayload.hasType = NO;
+ resultPayload.type = RMTPayloadTypeCompressable;
+ return self;
+}
+- (BOOL) hasBody {
+ return resultPayload.hasBody;
+}
+- (NSData*) body {
+ return resultPayload.body;
+}
+- (RMTPayloadBuilder*) setBody:(NSData*) value {
+ resultPayload.hasBody = YES;
+ resultPayload.body = value;
+ return self;
+}
+- (RMTPayloadBuilder*) clearBody {
+ resultPayload.hasBody = NO;
+ resultPayload.body = [NSData data];
+ return self;
+}
+@end
+
+@interface RMTSimpleRequest ()
+@property RMTPayloadType responseType;
+@property SInt32 responseSize;
+@property (strong) RMTPayload* payload;
+@property BOOL fillUsername;
+@property BOOL fillOauthScope;
+@end
+
+@implementation RMTSimpleRequest
+
+- (BOOL) hasResponseType {
+ return !!hasResponseType_;
+}
+- (void) setHasResponseType:(BOOL) _value_ {
+ hasResponseType_ = !!_value_;
+}
+@synthesize responseType;
+- (BOOL) hasResponseSize {
+ return !!hasResponseSize_;
+}
+- (void) setHasResponseSize:(BOOL) _value_ {
+ hasResponseSize_ = !!_value_;
+}
+@synthesize responseSize;
+- (BOOL) hasPayload {
+ return !!hasPayload_;
+}
+- (void) setHasPayload:(BOOL) _value_ {
+ hasPayload_ = !!_value_;
+}
+@synthesize payload;
+- (BOOL) hasFillUsername {
+ return !!hasFillUsername_;
+}
+- (void) setHasFillUsername:(BOOL) _value_ {
+ hasFillUsername_ = !!_value_;
+}
+- (BOOL) fillUsername {
+ return !!fillUsername_;
+}
+- (void) setFillUsername:(BOOL) _value_ {
+ fillUsername_ = !!_value_;
+}
+- (BOOL) hasFillOauthScope {
+ return !!hasFillOauthScope_;
+}
+- (void) setHasFillOauthScope:(BOOL) _value_ {
+ hasFillOauthScope_ = !!_value_;
+}
+- (BOOL) fillOauthScope {
+ return !!fillOauthScope_;
+}
+- (void) setFillOauthScope:(BOOL) _value_ {
+ fillOauthScope_ = !!_value_;
+}
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.responseType = RMTPayloadTypeCompressable;
+ self.responseSize = 0;
+ self.payload = [RMTPayload defaultInstance];
+ self.fillUsername = NO;
+ self.fillOauthScope = NO;
+ }
+ return self;
+}
+static RMTSimpleRequest* defaultRMTSimpleRequestInstance = nil;
++ (void) initialize {
+ if (self == [RMTSimpleRequest class]) {
+ defaultRMTSimpleRequestInstance = [[RMTSimpleRequest alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTSimpleRequestInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTSimpleRequestInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasResponseType) {
+ [output writeEnum:1 value:self.responseType];
+ }
+ if (self.hasResponseSize) {
+ [output writeInt32:2 value:self.responseSize];
+ }
+ if (self.hasPayload) {
+ [output writeMessage:3 value:self.payload];
+ }
+ if (self.hasFillUsername) {
+ [output writeBool:4 value:self.fillUsername];
+ }
+ if (self.hasFillOauthScope) {
+ [output writeBool:5 value:self.fillOauthScope];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasResponseType) {
+ size_ += computeEnumSize(1, self.responseType);
+ }
+ if (self.hasResponseSize) {
+ size_ += computeInt32Size(2, self.responseSize);
+ }
+ if (self.hasPayload) {
+ size_ += computeMessageSize(3, self.payload);
+ }
+ if (self.hasFillUsername) {
+ size_ += computeBoolSize(4, self.fillUsername);
+ }
+ if (self.hasFillOauthScope) {
+ size_ += computeBoolSize(5, self.fillOauthScope);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTSimpleRequest*) parseFromData:(NSData*) data {
+ return (RMTSimpleRequest*)[[[RMTSimpleRequest builder] mergeFromData:data] build];
+}
++ (RMTSimpleRequest*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTSimpleRequest*)[[[RMTSimpleRequest builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTSimpleRequest*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTSimpleRequest*)[[[RMTSimpleRequest builder] mergeFromInputStream:input] build];
+}
++ (RMTSimpleRequest*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTSimpleRequest*)[[[RMTSimpleRequest builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTSimpleRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTSimpleRequest*)[[[RMTSimpleRequest builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTSimpleRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTSimpleRequest*)[[[RMTSimpleRequest builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTSimpleRequestBuilder*) builder {
+ return [[RMTSimpleRequestBuilder alloc] init];
+}
++ (RMTSimpleRequestBuilder*) builderWithPrototype:(RMTSimpleRequest*) prototype {
+ return [[RMTSimpleRequest builder] mergeFrom:prototype];
+}
+- (RMTSimpleRequestBuilder*) builder {
+ return [RMTSimpleRequest builder];
+}
+- (RMTSimpleRequestBuilder*) toBuilder {
+ return [RMTSimpleRequest builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasResponseType) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"responseType", NSStringFromRMTPayloadType(self.responseType)];
+ }
+ if (self.hasResponseSize) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"responseSize", [NSNumber numberWithInteger:self.responseSize]];
+ }
+ if (self.hasPayload) {
+ [output appendFormat:@"%@%@ {\n", indent, @"payload"];
+ [self.payload writeDescriptionTo:output
+ withIndent:[NSString stringWithFormat:@"%@ ", indent]];
+ [output appendFormat:@"%@}\n", indent];
+ }
+ if (self.hasFillUsername) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"fillUsername", [NSNumber numberWithBool:self.fillUsername]];
+ }
+ if (self.hasFillOauthScope) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"fillOauthScope", [NSNumber numberWithBool:self.fillOauthScope]];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTSimpleRequest class]]) {
+ return NO;
+ }
+ RMTSimpleRequest *otherMessage = other;
+ return
+ self.hasResponseType == otherMessage.hasResponseType &&
+ (!self.hasResponseType || self.responseType == otherMessage.responseType) &&
+ self.hasResponseSize == otherMessage.hasResponseSize &&
+ (!self.hasResponseSize || self.responseSize == otherMessage.responseSize) &&
+ self.hasPayload == otherMessage.hasPayload &&
+ (!self.hasPayload || [self.payload isEqual:otherMessage.payload]) &&
+ self.hasFillUsername == otherMessage.hasFillUsername &&
+ (!self.hasFillUsername || self.fillUsername == otherMessage.fillUsername) &&
+ self.hasFillOauthScope == otherMessage.hasFillOauthScope &&
+ (!self.hasFillOauthScope || self.fillOauthScope == otherMessage.fillOauthScope) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasResponseType) {
+ hashCode = hashCode * 31 + self.responseType;
+ }
+ if (self.hasResponseSize) {
+ hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.responseSize] hash];
+ }
+ if (self.hasPayload) {
+ hashCode = hashCode * 31 + [self.payload hash];
+ }
+ if (self.hasFillUsername) {
+ hashCode = hashCode * 31 + [[NSNumber numberWithBool:self.fillUsername] hash];
+ }
+ if (self.hasFillOauthScope) {
+ hashCode = hashCode * 31 + [[NSNumber numberWithBool:self.fillOauthScope] hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTSimpleRequestBuilder()
+@property (strong) RMTSimpleRequest* resultSimpleRequest;
+@end
+
+@implementation RMTSimpleRequestBuilder
+@synthesize resultSimpleRequest;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultSimpleRequest = [[RMTSimpleRequest alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultSimpleRequest;
+}
+- (RMTSimpleRequestBuilder*) clear {
+ self.resultSimpleRequest = [[RMTSimpleRequest alloc] init];
+ return self;
+}
+- (RMTSimpleRequestBuilder*) clone {
+ return [RMTSimpleRequest builderWithPrototype:resultSimpleRequest];
+}
+- (RMTSimpleRequest*) defaultInstance {
+ return [RMTSimpleRequest defaultInstance];
+}
+- (RMTSimpleRequest*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTSimpleRequest*) buildPartial {
+ RMTSimpleRequest* returnMe = resultSimpleRequest;
+ self.resultSimpleRequest = nil;
+ return returnMe;
+}
+- (RMTSimpleRequestBuilder*) mergeFrom:(RMTSimpleRequest*) other {
+ if (other == [RMTSimpleRequest defaultInstance]) {
+ return self;
+ }
+ if (other.hasResponseType) {
+ [self setResponseType:other.responseType];
+ }
+ if (other.hasResponseSize) {
+ [self setResponseSize:other.responseSize];
+ }
+ if (other.hasPayload) {
+ [self mergePayload:other.payload];
+ }
+ if (other.hasFillUsername) {
+ [self setFillUsername:other.fillUsername];
+ }
+ if (other.hasFillOauthScope) {
+ [self setFillOauthScope:other.fillOauthScope];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTSimpleRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTSimpleRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 8: {
+ RMTPayloadType value = (RMTPayloadType)[input readEnum];
+ if (RMTPayloadTypeIsValidValue(value)) {
+ [self setResponseType:value];
+ } else {
+ [unknownFields mergeVarintField:1 value:value];
+ }
+ break;
+ }
+ case 16: {
+ [self setResponseSize:[input readInt32]];
+ break;
+ }
+ case 26: {
+ RMTPayloadBuilder* subBuilder = [RMTPayload builder];
+ if (self.hasPayload) {
+ [subBuilder mergeFrom:self.payload];
+ }
+ [input readMessage:subBuilder extensionRegistry:extensionRegistry];
+ [self setPayload:[subBuilder buildPartial]];
+ break;
+ }
+ case 32: {
+ [self setFillUsername:[input readBool]];
+ break;
+ }
+ case 40: {
+ [self setFillOauthScope:[input readBool]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasResponseType {
+ return resultSimpleRequest.hasResponseType;
+}
+- (RMTPayloadType) responseType {
+ return resultSimpleRequest.responseType;
+}
+- (RMTSimpleRequestBuilder*) setResponseType:(RMTPayloadType) value {
+ resultSimpleRequest.hasResponseType = YES;
+ resultSimpleRequest.responseType = value;
+ return self;
+}
+- (RMTSimpleRequestBuilder*) clearResponseType {
+ resultSimpleRequest.hasResponseType = NO;
+ resultSimpleRequest.responseType = RMTPayloadTypeCompressable;
+ return self;
+}
+- (BOOL) hasResponseSize {
+ return resultSimpleRequest.hasResponseSize;
+}
+- (SInt32) responseSize {
+ return resultSimpleRequest.responseSize;
+}
+- (RMTSimpleRequestBuilder*) setResponseSize:(SInt32) value {
+ resultSimpleRequest.hasResponseSize = YES;
+ resultSimpleRequest.responseSize = value;
+ return self;
+}
+- (RMTSimpleRequestBuilder*) clearResponseSize {
+ resultSimpleRequest.hasResponseSize = NO;
+ resultSimpleRequest.responseSize = 0;
+ return self;
+}
+- (BOOL) hasPayload {
+ return resultSimpleRequest.hasPayload;
+}
+- (RMTPayload*) payload {
+ return resultSimpleRequest.payload;
+}
+- (RMTSimpleRequestBuilder*) setPayload:(RMTPayload*) value {
+ resultSimpleRequest.hasPayload = YES;
+ resultSimpleRequest.payload = value;
+ return self;
+}
+- (RMTSimpleRequestBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue {
+ return [self setPayload:[builderForValue build]];
+}
+- (RMTSimpleRequestBuilder*) mergePayload:(RMTPayload*) value {
+ if (resultSimpleRequest.hasPayload &&
+ resultSimpleRequest.payload != [RMTPayload defaultInstance]) {
+ resultSimpleRequest.payload =
+ [[[RMTPayload builderWithPrototype:resultSimpleRequest.payload] mergeFrom:value] buildPartial];
+ } else {
+ resultSimpleRequest.payload = value;
+ }
+ resultSimpleRequest.hasPayload = YES;
+ return self;
+}
+- (RMTSimpleRequestBuilder*) clearPayload {
+ resultSimpleRequest.hasPayload = NO;
+ resultSimpleRequest.payload = [RMTPayload defaultInstance];
+ return self;
+}
+- (BOOL) hasFillUsername {
+ return resultSimpleRequest.hasFillUsername;
+}
+- (BOOL) fillUsername {
+ return resultSimpleRequest.fillUsername;
+}
+- (RMTSimpleRequestBuilder*) setFillUsername:(BOOL) value {
+ resultSimpleRequest.hasFillUsername = YES;
+ resultSimpleRequest.fillUsername = value;
+ return self;
+}
+- (RMTSimpleRequestBuilder*) clearFillUsername {
+ resultSimpleRequest.hasFillUsername = NO;
+ resultSimpleRequest.fillUsername = NO;
+ return self;
+}
+- (BOOL) hasFillOauthScope {
+ return resultSimpleRequest.hasFillOauthScope;
+}
+- (BOOL) fillOauthScope {
+ return resultSimpleRequest.fillOauthScope;
+}
+- (RMTSimpleRequestBuilder*) setFillOauthScope:(BOOL) value {
+ resultSimpleRequest.hasFillOauthScope = YES;
+ resultSimpleRequest.fillOauthScope = value;
+ return self;
+}
+- (RMTSimpleRequestBuilder*) clearFillOauthScope {
+ resultSimpleRequest.hasFillOauthScope = NO;
+ resultSimpleRequest.fillOauthScope = NO;
+ return self;
+}
+@end
+
+@interface RMTSimpleResponse ()
+@property (strong) RMTPayload* payload;
+@property (strong) NSString* username;
+@property (strong) NSString* oauthScope;
+@end
+
+@implementation RMTSimpleResponse
+
+- (BOOL) hasPayload {
+ return !!hasPayload_;
+}
+- (void) setHasPayload:(BOOL) _value_ {
+ hasPayload_ = !!_value_;
+}
+@synthesize payload;
+- (BOOL) hasUsername {
+ return !!hasUsername_;
+}
+- (void) setHasUsername:(BOOL) _value_ {
+ hasUsername_ = !!_value_;
+}
+@synthesize username;
+- (BOOL) hasOauthScope {
+ return !!hasOauthScope_;
+}
+- (void) setHasOauthScope:(BOOL) _value_ {
+ hasOauthScope_ = !!_value_;
+}
+@synthesize oauthScope;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.payload = [RMTPayload defaultInstance];
+ self.username = @"";
+ self.oauthScope = @"";
+ }
+ return self;
+}
+static RMTSimpleResponse* defaultRMTSimpleResponseInstance = nil;
++ (void) initialize {
+ if (self == [RMTSimpleResponse class]) {
+ defaultRMTSimpleResponseInstance = [[RMTSimpleResponse alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTSimpleResponseInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTSimpleResponseInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasPayload) {
+ [output writeMessage:1 value:self.payload];
+ }
+ if (self.hasUsername) {
+ [output writeString:2 value:self.username];
+ }
+ if (self.hasOauthScope) {
+ [output writeString:3 value:self.oauthScope];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasPayload) {
+ size_ += computeMessageSize(1, self.payload);
+ }
+ if (self.hasUsername) {
+ size_ += computeStringSize(2, self.username);
+ }
+ if (self.hasOauthScope) {
+ size_ += computeStringSize(3, self.oauthScope);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTSimpleResponse*) parseFromData:(NSData*) data {
+ return (RMTSimpleResponse*)[[[RMTSimpleResponse builder] mergeFromData:data] build];
+}
++ (RMTSimpleResponse*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTSimpleResponse*)[[[RMTSimpleResponse builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTSimpleResponse*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTSimpleResponse*)[[[RMTSimpleResponse builder] mergeFromInputStream:input] build];
+}
++ (RMTSimpleResponse*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTSimpleResponse*)[[[RMTSimpleResponse builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTSimpleResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTSimpleResponse*)[[[RMTSimpleResponse builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTSimpleResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTSimpleResponse*)[[[RMTSimpleResponse builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTSimpleResponseBuilder*) builder {
+ return [[RMTSimpleResponseBuilder alloc] init];
+}
++ (RMTSimpleResponseBuilder*) builderWithPrototype:(RMTSimpleResponse*) prototype {
+ return [[RMTSimpleResponse builder] mergeFrom:prototype];
+}
+- (RMTSimpleResponseBuilder*) builder {
+ return [RMTSimpleResponse builder];
+}
+- (RMTSimpleResponseBuilder*) toBuilder {
+ return [RMTSimpleResponse builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasPayload) {
+ [output appendFormat:@"%@%@ {\n", indent, @"payload"];
+ [self.payload writeDescriptionTo:output
+ withIndent:[NSString stringWithFormat:@"%@ ", indent]];
+ [output appendFormat:@"%@}\n", indent];
+ }
+ if (self.hasUsername) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"username", self.username];
+ }
+ if (self.hasOauthScope) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"oauthScope", self.oauthScope];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTSimpleResponse class]]) {
+ return NO;
+ }
+ RMTSimpleResponse *otherMessage = other;
+ return
+ self.hasPayload == otherMessage.hasPayload &&
+ (!self.hasPayload || [self.payload isEqual:otherMessage.payload]) &&
+ self.hasUsername == otherMessage.hasUsername &&
+ (!self.hasUsername || [self.username isEqual:otherMessage.username]) &&
+ self.hasOauthScope == otherMessage.hasOauthScope &&
+ (!self.hasOauthScope || [self.oauthScope isEqual:otherMessage.oauthScope]) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasPayload) {
+ hashCode = hashCode * 31 + [self.payload hash];
+ }
+ if (self.hasUsername) {
+ hashCode = hashCode * 31 + [self.username hash];
+ }
+ if (self.hasOauthScope) {
+ hashCode = hashCode * 31 + [self.oauthScope hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTSimpleResponseBuilder()
+@property (strong) RMTSimpleResponse* resultSimpleResponse;
+@end
+
+@implementation RMTSimpleResponseBuilder
+@synthesize resultSimpleResponse;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultSimpleResponse = [[RMTSimpleResponse alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultSimpleResponse;
+}
+- (RMTSimpleResponseBuilder*) clear {
+ self.resultSimpleResponse = [[RMTSimpleResponse alloc] init];
+ return self;
+}
+- (RMTSimpleResponseBuilder*) clone {
+ return [RMTSimpleResponse builderWithPrototype:resultSimpleResponse];
+}
+- (RMTSimpleResponse*) defaultInstance {
+ return [RMTSimpleResponse defaultInstance];
+}
+- (RMTSimpleResponse*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTSimpleResponse*) buildPartial {
+ RMTSimpleResponse* returnMe = resultSimpleResponse;
+ self.resultSimpleResponse = nil;
+ return returnMe;
+}
+- (RMTSimpleResponseBuilder*) mergeFrom:(RMTSimpleResponse*) other {
+ if (other == [RMTSimpleResponse defaultInstance]) {
+ return self;
+ }
+ if (other.hasPayload) {
+ [self mergePayload:other.payload];
+ }
+ if (other.hasUsername) {
+ [self setUsername:other.username];
+ }
+ if (other.hasOauthScope) {
+ [self setOauthScope:other.oauthScope];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTSimpleResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTSimpleResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 10: {
+ RMTPayloadBuilder* subBuilder = [RMTPayload builder];
+ if (self.hasPayload) {
+ [subBuilder mergeFrom:self.payload];
+ }
+ [input readMessage:subBuilder extensionRegistry:extensionRegistry];
+ [self setPayload:[subBuilder buildPartial]];
+ break;
+ }
+ case 18: {
+ [self setUsername:[input readString]];
+ break;
+ }
+ case 26: {
+ [self setOauthScope:[input readString]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasPayload {
+ return resultSimpleResponse.hasPayload;
+}
+- (RMTPayload*) payload {
+ return resultSimpleResponse.payload;
+}
+- (RMTSimpleResponseBuilder*) setPayload:(RMTPayload*) value {
+ resultSimpleResponse.hasPayload = YES;
+ resultSimpleResponse.payload = value;
+ return self;
+}
+- (RMTSimpleResponseBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue {
+ return [self setPayload:[builderForValue build]];
+}
+- (RMTSimpleResponseBuilder*) mergePayload:(RMTPayload*) value {
+ if (resultSimpleResponse.hasPayload &&
+ resultSimpleResponse.payload != [RMTPayload defaultInstance]) {
+ resultSimpleResponse.payload =
+ [[[RMTPayload builderWithPrototype:resultSimpleResponse.payload] mergeFrom:value] buildPartial];
+ } else {
+ resultSimpleResponse.payload = value;
+ }
+ resultSimpleResponse.hasPayload = YES;
+ return self;
+}
+- (RMTSimpleResponseBuilder*) clearPayload {
+ resultSimpleResponse.hasPayload = NO;
+ resultSimpleResponse.payload = [RMTPayload defaultInstance];
+ return self;
+}
+- (BOOL) hasUsername {
+ return resultSimpleResponse.hasUsername;
+}
+- (NSString*) username {
+ return resultSimpleResponse.username;
+}
+- (RMTSimpleResponseBuilder*) setUsername:(NSString*) value {
+ resultSimpleResponse.hasUsername = YES;
+ resultSimpleResponse.username = value;
+ return self;
+}
+- (RMTSimpleResponseBuilder*) clearUsername {
+ resultSimpleResponse.hasUsername = NO;
+ resultSimpleResponse.username = @"";
+ return self;
+}
+- (BOOL) hasOauthScope {
+ return resultSimpleResponse.hasOauthScope;
+}
+- (NSString*) oauthScope {
+ return resultSimpleResponse.oauthScope;
+}
+- (RMTSimpleResponseBuilder*) setOauthScope:(NSString*) value {
+ resultSimpleResponse.hasOauthScope = YES;
+ resultSimpleResponse.oauthScope = value;
+ return self;
+}
+- (RMTSimpleResponseBuilder*) clearOauthScope {
+ resultSimpleResponse.hasOauthScope = NO;
+ resultSimpleResponse.oauthScope = @"";
+ return self;
+}
+@end
+
+@interface RMTStreamingInputCallRequest ()
+@property (strong) RMTPayload* payload;
+@end
+
+@implementation RMTStreamingInputCallRequest
+
+- (BOOL) hasPayload {
+ return !!hasPayload_;
+}
+- (void) setHasPayload:(BOOL) _value_ {
+ hasPayload_ = !!_value_;
+}
+@synthesize payload;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.payload = [RMTPayload defaultInstance];
+ }
+ return self;
+}
+static RMTStreamingInputCallRequest* defaultRMTStreamingInputCallRequestInstance = nil;
++ (void) initialize {
+ if (self == [RMTStreamingInputCallRequest class]) {
+ defaultRMTStreamingInputCallRequestInstance = [[RMTStreamingInputCallRequest alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTStreamingInputCallRequestInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTStreamingInputCallRequestInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasPayload) {
+ [output writeMessage:1 value:self.payload];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasPayload) {
+ size_ += computeMessageSize(1, self.payload);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTStreamingInputCallRequest*) parseFromData:(NSData*) data {
+ return (RMTStreamingInputCallRequest*)[[[RMTStreamingInputCallRequest builder] mergeFromData:data] build];
+}
++ (RMTStreamingInputCallRequest*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingInputCallRequest*)[[[RMTStreamingInputCallRequest builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingInputCallRequest*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTStreamingInputCallRequest*)[[[RMTStreamingInputCallRequest builder] mergeFromInputStream:input] build];
+}
++ (RMTStreamingInputCallRequest*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingInputCallRequest*)[[[RMTStreamingInputCallRequest builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingInputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTStreamingInputCallRequest*)[[[RMTStreamingInputCallRequest builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTStreamingInputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingInputCallRequest*)[[[RMTStreamingInputCallRequest builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingInputCallRequestBuilder*) builder {
+ return [[RMTStreamingInputCallRequestBuilder alloc] init];
+}
++ (RMTStreamingInputCallRequestBuilder*) builderWithPrototype:(RMTStreamingInputCallRequest*) prototype {
+ return [[RMTStreamingInputCallRequest builder] mergeFrom:prototype];
+}
+- (RMTStreamingInputCallRequestBuilder*) builder {
+ return [RMTStreamingInputCallRequest builder];
+}
+- (RMTStreamingInputCallRequestBuilder*) toBuilder {
+ return [RMTStreamingInputCallRequest builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasPayload) {
+ [output appendFormat:@"%@%@ {\n", indent, @"payload"];
+ [self.payload writeDescriptionTo:output
+ withIndent:[NSString stringWithFormat:@"%@ ", indent]];
+ [output appendFormat:@"%@}\n", indent];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTStreamingInputCallRequest class]]) {
+ return NO;
+ }
+ RMTStreamingInputCallRequest *otherMessage = other;
+ return
+ self.hasPayload == otherMessage.hasPayload &&
+ (!self.hasPayload || [self.payload isEqual:otherMessage.payload]) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasPayload) {
+ hashCode = hashCode * 31 + [self.payload hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTStreamingInputCallRequestBuilder()
+@property (strong) RMTStreamingInputCallRequest* resultStreamingInputCallRequest;
+@end
+
+@implementation RMTStreamingInputCallRequestBuilder
+@synthesize resultStreamingInputCallRequest;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultStreamingInputCallRequest = [[RMTStreamingInputCallRequest alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultStreamingInputCallRequest;
+}
+- (RMTStreamingInputCallRequestBuilder*) clear {
+ self.resultStreamingInputCallRequest = [[RMTStreamingInputCallRequest alloc] init];
+ return self;
+}
+- (RMTStreamingInputCallRequestBuilder*) clone {
+ return [RMTStreamingInputCallRequest builderWithPrototype:resultStreamingInputCallRequest];
+}
+- (RMTStreamingInputCallRequest*) defaultInstance {
+ return [RMTStreamingInputCallRequest defaultInstance];
+}
+- (RMTStreamingInputCallRequest*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTStreamingInputCallRequest*) buildPartial {
+ RMTStreamingInputCallRequest* returnMe = resultStreamingInputCallRequest;
+ self.resultStreamingInputCallRequest = nil;
+ return returnMe;
+}
+- (RMTStreamingInputCallRequestBuilder*) mergeFrom:(RMTStreamingInputCallRequest*) other {
+ if (other == [RMTStreamingInputCallRequest defaultInstance]) {
+ return self;
+ }
+ if (other.hasPayload) {
+ [self mergePayload:other.payload];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTStreamingInputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTStreamingInputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 10: {
+ RMTPayloadBuilder* subBuilder = [RMTPayload builder];
+ if (self.hasPayload) {
+ [subBuilder mergeFrom:self.payload];
+ }
+ [input readMessage:subBuilder extensionRegistry:extensionRegistry];
+ [self setPayload:[subBuilder buildPartial]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasPayload {
+ return resultStreamingInputCallRequest.hasPayload;
+}
+- (RMTPayload*) payload {
+ return resultStreamingInputCallRequest.payload;
+}
+- (RMTStreamingInputCallRequestBuilder*) setPayload:(RMTPayload*) value {
+ resultStreamingInputCallRequest.hasPayload = YES;
+ resultStreamingInputCallRequest.payload = value;
+ return self;
+}
+- (RMTStreamingInputCallRequestBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue {
+ return [self setPayload:[builderForValue build]];
+}
+- (RMTStreamingInputCallRequestBuilder*) mergePayload:(RMTPayload*) value {
+ if (resultStreamingInputCallRequest.hasPayload &&
+ resultStreamingInputCallRequest.payload != [RMTPayload defaultInstance]) {
+ resultStreamingInputCallRequest.payload =
+ [[[RMTPayload builderWithPrototype:resultStreamingInputCallRequest.payload] mergeFrom:value] buildPartial];
+ } else {
+ resultStreamingInputCallRequest.payload = value;
+ }
+ resultStreamingInputCallRequest.hasPayload = YES;
+ return self;
+}
+- (RMTStreamingInputCallRequestBuilder*) clearPayload {
+ resultStreamingInputCallRequest.hasPayload = NO;
+ resultStreamingInputCallRequest.payload = [RMTPayload defaultInstance];
+ return self;
+}
+@end
+
+@interface RMTStreamingInputCallResponse ()
+@property SInt32 aggregatedPayloadSize;
+@end
+
+@implementation RMTStreamingInputCallResponse
+
+- (BOOL) hasAggregatedPayloadSize {
+ return !!hasAggregatedPayloadSize_;
+}
+- (void) setHasAggregatedPayloadSize:(BOOL) _value_ {
+ hasAggregatedPayloadSize_ = !!_value_;
+}
+@synthesize aggregatedPayloadSize;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.aggregatedPayloadSize = 0;
+ }
+ return self;
+}
+static RMTStreamingInputCallResponse* defaultRMTStreamingInputCallResponseInstance = nil;
++ (void) initialize {
+ if (self == [RMTStreamingInputCallResponse class]) {
+ defaultRMTStreamingInputCallResponseInstance = [[RMTStreamingInputCallResponse alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTStreamingInputCallResponseInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTStreamingInputCallResponseInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasAggregatedPayloadSize) {
+ [output writeInt32:1 value:self.aggregatedPayloadSize];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasAggregatedPayloadSize) {
+ size_ += computeInt32Size(1, self.aggregatedPayloadSize);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTStreamingInputCallResponse*) parseFromData:(NSData*) data {
+ return (RMTStreamingInputCallResponse*)[[[RMTStreamingInputCallResponse builder] mergeFromData:data] build];
+}
++ (RMTStreamingInputCallResponse*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingInputCallResponse*)[[[RMTStreamingInputCallResponse builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingInputCallResponse*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTStreamingInputCallResponse*)[[[RMTStreamingInputCallResponse builder] mergeFromInputStream:input] build];
+}
++ (RMTStreamingInputCallResponse*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingInputCallResponse*)[[[RMTStreamingInputCallResponse builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingInputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTStreamingInputCallResponse*)[[[RMTStreamingInputCallResponse builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTStreamingInputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingInputCallResponse*)[[[RMTStreamingInputCallResponse builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingInputCallResponseBuilder*) builder {
+ return [[RMTStreamingInputCallResponseBuilder alloc] init];
+}
++ (RMTStreamingInputCallResponseBuilder*) builderWithPrototype:(RMTStreamingInputCallResponse*) prototype {
+ return [[RMTStreamingInputCallResponse builder] mergeFrom:prototype];
+}
+- (RMTStreamingInputCallResponseBuilder*) builder {
+ return [RMTStreamingInputCallResponse builder];
+}
+- (RMTStreamingInputCallResponseBuilder*) toBuilder {
+ return [RMTStreamingInputCallResponse builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasAggregatedPayloadSize) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"aggregatedPayloadSize", [NSNumber numberWithInteger:self.aggregatedPayloadSize]];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTStreamingInputCallResponse class]]) {
+ return NO;
+ }
+ RMTStreamingInputCallResponse *otherMessage = other;
+ return
+ self.hasAggregatedPayloadSize == otherMessage.hasAggregatedPayloadSize &&
+ (!self.hasAggregatedPayloadSize || self.aggregatedPayloadSize == otherMessage.aggregatedPayloadSize) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasAggregatedPayloadSize) {
+ hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.aggregatedPayloadSize] hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTStreamingInputCallResponseBuilder()
+@property (strong) RMTStreamingInputCallResponse* resultStreamingInputCallResponse;
+@end
+
+@implementation RMTStreamingInputCallResponseBuilder
+@synthesize resultStreamingInputCallResponse;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultStreamingInputCallResponse = [[RMTStreamingInputCallResponse alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultStreamingInputCallResponse;
+}
+- (RMTStreamingInputCallResponseBuilder*) clear {
+ self.resultStreamingInputCallResponse = [[RMTStreamingInputCallResponse alloc] init];
+ return self;
+}
+- (RMTStreamingInputCallResponseBuilder*) clone {
+ return [RMTStreamingInputCallResponse builderWithPrototype:resultStreamingInputCallResponse];
+}
+- (RMTStreamingInputCallResponse*) defaultInstance {
+ return [RMTStreamingInputCallResponse defaultInstance];
+}
+- (RMTStreamingInputCallResponse*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTStreamingInputCallResponse*) buildPartial {
+ RMTStreamingInputCallResponse* returnMe = resultStreamingInputCallResponse;
+ self.resultStreamingInputCallResponse = nil;
+ return returnMe;
+}
+- (RMTStreamingInputCallResponseBuilder*) mergeFrom:(RMTStreamingInputCallResponse*) other {
+ if (other == [RMTStreamingInputCallResponse defaultInstance]) {
+ return self;
+ }
+ if (other.hasAggregatedPayloadSize) {
+ [self setAggregatedPayloadSize:other.aggregatedPayloadSize];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTStreamingInputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTStreamingInputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 8: {
+ [self setAggregatedPayloadSize:[input readInt32]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasAggregatedPayloadSize {
+ return resultStreamingInputCallResponse.hasAggregatedPayloadSize;
+}
+- (SInt32) aggregatedPayloadSize {
+ return resultStreamingInputCallResponse.aggregatedPayloadSize;
+}
+- (RMTStreamingInputCallResponseBuilder*) setAggregatedPayloadSize:(SInt32) value {
+ resultStreamingInputCallResponse.hasAggregatedPayloadSize = YES;
+ resultStreamingInputCallResponse.aggregatedPayloadSize = value;
+ return self;
+}
+- (RMTStreamingInputCallResponseBuilder*) clearAggregatedPayloadSize {
+ resultStreamingInputCallResponse.hasAggregatedPayloadSize = NO;
+ resultStreamingInputCallResponse.aggregatedPayloadSize = 0;
+ return self;
+}
+@end
+
+@interface RMTResponseParameters ()
+@property SInt32 size;
+@property SInt32 intervalUs;
+@end
+
+@implementation RMTResponseParameters
+
+- (BOOL) hasSize {
+ return !!hasSize_;
+}
+- (void) setHasSize:(BOOL) _value_ {
+ hasSize_ = !!_value_;
+}
+@synthesize size;
+- (BOOL) hasIntervalUs {
+ return !!hasIntervalUs_;
+}
+- (void) setHasIntervalUs:(BOOL) _value_ {
+ hasIntervalUs_ = !!_value_;
+}
+@synthesize intervalUs;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.size = 0;
+ self.intervalUs = 0;
+ }
+ return self;
+}
+static RMTResponseParameters* defaultRMTResponseParametersInstance = nil;
++ (void) initialize {
+ if (self == [RMTResponseParameters class]) {
+ defaultRMTResponseParametersInstance = [[RMTResponseParameters alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTResponseParametersInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTResponseParametersInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasSize) {
+ [output writeInt32:1 value:self.size];
+ }
+ if (self.hasIntervalUs) {
+ [output writeInt32:2 value:self.intervalUs];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasSize) {
+ size_ += computeInt32Size(1, self.size);
+ }
+ if (self.hasIntervalUs) {
+ size_ += computeInt32Size(2, self.intervalUs);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTResponseParameters*) parseFromData:(NSData*) data {
+ return (RMTResponseParameters*)[[[RMTResponseParameters builder] mergeFromData:data] build];
+}
++ (RMTResponseParameters*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTResponseParameters*)[[[RMTResponseParameters builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTResponseParameters*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTResponseParameters*)[[[RMTResponseParameters builder] mergeFromInputStream:input] build];
+}
++ (RMTResponseParameters*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTResponseParameters*)[[[RMTResponseParameters builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTResponseParameters*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTResponseParameters*)[[[RMTResponseParameters builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTResponseParameters*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTResponseParameters*)[[[RMTResponseParameters builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTResponseParametersBuilder*) builder {
+ return [[RMTResponseParametersBuilder alloc] init];
+}
++ (RMTResponseParametersBuilder*) builderWithPrototype:(RMTResponseParameters*) prototype {
+ return [[RMTResponseParameters builder] mergeFrom:prototype];
+}
+- (RMTResponseParametersBuilder*) builder {
+ return [RMTResponseParameters builder];
+}
+- (RMTResponseParametersBuilder*) toBuilder {
+ return [RMTResponseParameters builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasSize) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"size", [NSNumber numberWithInteger:self.size]];
+ }
+ if (self.hasIntervalUs) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"intervalUs", [NSNumber numberWithInteger:self.intervalUs]];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTResponseParameters class]]) {
+ return NO;
+ }
+ RMTResponseParameters *otherMessage = other;
+ return
+ self.hasSize == otherMessage.hasSize &&
+ (!self.hasSize || self.size == otherMessage.size) &&
+ self.hasIntervalUs == otherMessage.hasIntervalUs &&
+ (!self.hasIntervalUs || self.intervalUs == otherMessage.intervalUs) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasSize) {
+ hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.size] hash];
+ }
+ if (self.hasIntervalUs) {
+ hashCode = hashCode * 31 + [[NSNumber numberWithInteger:self.intervalUs] hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTResponseParametersBuilder()
+@property (strong) RMTResponseParameters* resultResponseParameters;
+@end
+
+@implementation RMTResponseParametersBuilder
+@synthesize resultResponseParameters;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultResponseParameters = [[RMTResponseParameters alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultResponseParameters;
+}
+- (RMTResponseParametersBuilder*) clear {
+ self.resultResponseParameters = [[RMTResponseParameters alloc] init];
+ return self;
+}
+- (RMTResponseParametersBuilder*) clone {
+ return [RMTResponseParameters builderWithPrototype:resultResponseParameters];
+}
+- (RMTResponseParameters*) defaultInstance {
+ return [RMTResponseParameters defaultInstance];
+}
+- (RMTResponseParameters*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTResponseParameters*) buildPartial {
+ RMTResponseParameters* returnMe = resultResponseParameters;
+ self.resultResponseParameters = nil;
+ return returnMe;
+}
+- (RMTResponseParametersBuilder*) mergeFrom:(RMTResponseParameters*) other {
+ if (other == [RMTResponseParameters defaultInstance]) {
+ return self;
+ }
+ if (other.hasSize) {
+ [self setSize:other.size];
+ }
+ if (other.hasIntervalUs) {
+ [self setIntervalUs:other.intervalUs];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTResponseParametersBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTResponseParametersBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 8: {
+ [self setSize:[input readInt32]];
+ break;
+ }
+ case 16: {
+ [self setIntervalUs:[input readInt32]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasSize {
+ return resultResponseParameters.hasSize;
+}
+- (SInt32) size {
+ return resultResponseParameters.size;
+}
+- (RMTResponseParametersBuilder*) setSize:(SInt32) value {
+ resultResponseParameters.hasSize = YES;
+ resultResponseParameters.size = value;
+ return self;
+}
+- (RMTResponseParametersBuilder*) clearSize {
+ resultResponseParameters.hasSize = NO;
+ resultResponseParameters.size = 0;
+ return self;
+}
+- (BOOL) hasIntervalUs {
+ return resultResponseParameters.hasIntervalUs;
+}
+- (SInt32) intervalUs {
+ return resultResponseParameters.intervalUs;
+}
+- (RMTResponseParametersBuilder*) setIntervalUs:(SInt32) value {
+ resultResponseParameters.hasIntervalUs = YES;
+ resultResponseParameters.intervalUs = value;
+ return self;
+}
+- (RMTResponseParametersBuilder*) clearIntervalUs {
+ resultResponseParameters.hasIntervalUs = NO;
+ resultResponseParameters.intervalUs = 0;
+ return self;
+}
+@end
+
+@interface RMTStreamingOutputCallRequest ()
+@property RMTPayloadType responseType;
+@property (strong) NSMutableArray * responseParametersArray;
+@property (strong) RMTPayload* payload;
+@end
+
+@implementation RMTStreamingOutputCallRequest
+
+- (BOOL) hasResponseType {
+ return !!hasResponseType_;
+}
+- (void) setHasResponseType:(BOOL) _value_ {
+ hasResponseType_ = !!_value_;
+}
+@synthesize responseType;
+@synthesize responseParametersArray;
+@dynamic responseParameters;
+- (BOOL) hasPayload {
+ return !!hasPayload_;
+}
+- (void) setHasPayload:(BOOL) _value_ {
+ hasPayload_ = !!_value_;
+}
+@synthesize payload;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.responseType = RMTPayloadTypeCompressable;
+ self.payload = [RMTPayload defaultInstance];
+ }
+ return self;
+}
+static RMTStreamingOutputCallRequest* defaultRMTStreamingOutputCallRequestInstance = nil;
++ (void) initialize {
+ if (self == [RMTStreamingOutputCallRequest class]) {
+ defaultRMTStreamingOutputCallRequestInstance = [[RMTStreamingOutputCallRequest alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTStreamingOutputCallRequestInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTStreamingOutputCallRequestInstance;
+}
+- (NSArray *)responseParameters {
+ return responseParametersArray;
+}
+- (RMTResponseParameters*)responseParametersAtIndex:(NSUInteger)index {
+ return [responseParametersArray objectAtIndex:index];
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasResponseType) {
+ [output writeEnum:1 value:self.responseType];
+ }
+ [self.responseParametersArray enumerateObjectsUsingBlock:^(RMTResponseParameters *element, NSUInteger idx, BOOL *stop) {
+ [output writeMessage:2 value:element];
+ }];
+ if (self.hasPayload) {
+ [output writeMessage:3 value:self.payload];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasResponseType) {
+ size_ += computeEnumSize(1, self.responseType);
+ }
+ [self.responseParametersArray enumerateObjectsUsingBlock:^(RMTResponseParameters *element, NSUInteger idx, BOOL *stop) {
+ size_ += computeMessageSize(2, element);
+ }];
+ if (self.hasPayload) {
+ size_ += computeMessageSize(3, self.payload);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTStreamingOutputCallRequest*) parseFromData:(NSData*) data {
+ return (RMTStreamingOutputCallRequest*)[[[RMTStreamingOutputCallRequest builder] mergeFromData:data] build];
+}
++ (RMTStreamingOutputCallRequest*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingOutputCallRequest*)[[[RMTStreamingOutputCallRequest builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingOutputCallRequest*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTStreamingOutputCallRequest*)[[[RMTStreamingOutputCallRequest builder] mergeFromInputStream:input] build];
+}
++ (RMTStreamingOutputCallRequest*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingOutputCallRequest*)[[[RMTStreamingOutputCallRequest builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingOutputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTStreamingOutputCallRequest*)[[[RMTStreamingOutputCallRequest builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTStreamingOutputCallRequest*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingOutputCallRequest*)[[[RMTStreamingOutputCallRequest builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingOutputCallRequestBuilder*) builder {
+ return [[RMTStreamingOutputCallRequestBuilder alloc] init];
+}
++ (RMTStreamingOutputCallRequestBuilder*) builderWithPrototype:(RMTStreamingOutputCallRequest*) prototype {
+ return [[RMTStreamingOutputCallRequest builder] mergeFrom:prototype];
+}
+- (RMTStreamingOutputCallRequestBuilder*) builder {
+ return [RMTStreamingOutputCallRequest builder];
+}
+- (RMTStreamingOutputCallRequestBuilder*) toBuilder {
+ return [RMTStreamingOutputCallRequest builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasResponseType) {
+ [output appendFormat:@"%@%@: %@\n", indent, @"responseType", NSStringFromRMTPayloadType(self.responseType)];
+ }
+ [self.responseParametersArray enumerateObjectsUsingBlock:^(RMTResponseParameters *element, NSUInteger idx, BOOL *stop) {
+ [output appendFormat:@"%@%@ {\n", indent, @"responseParameters"];
+ [element writeDescriptionTo:output
+ withIndent:[NSString stringWithFormat:@"%@ ", indent]];
+ [output appendFormat:@"%@}\n", indent];
+ }];
+ if (self.hasPayload) {
+ [output appendFormat:@"%@%@ {\n", indent, @"payload"];
+ [self.payload writeDescriptionTo:output
+ withIndent:[NSString stringWithFormat:@"%@ ", indent]];
+ [output appendFormat:@"%@}\n", indent];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTStreamingOutputCallRequest class]]) {
+ return NO;
+ }
+ RMTStreamingOutputCallRequest *otherMessage = other;
+ return
+ self.hasResponseType == otherMessage.hasResponseType &&
+ (!self.hasResponseType || self.responseType == otherMessage.responseType) &&
+ [self.responseParametersArray isEqualToArray:otherMessage.responseParametersArray] &&
+ self.hasPayload == otherMessage.hasPayload &&
+ (!self.hasPayload || [self.payload isEqual:otherMessage.payload]) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasResponseType) {
+ hashCode = hashCode * 31 + self.responseType;
+ }
+ [self.responseParametersArray enumerateObjectsUsingBlock:^(RMTResponseParameters *element, NSUInteger idx, BOOL *stop) {
+ hashCode = hashCode * 31 + [element hash];
+ }];
+ if (self.hasPayload) {
+ hashCode = hashCode * 31 + [self.payload hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTStreamingOutputCallRequestBuilder()
+@property (strong) RMTStreamingOutputCallRequest* resultStreamingOutputCallRequest;
+@end
+
+@implementation RMTStreamingOutputCallRequestBuilder
+@synthesize resultStreamingOutputCallRequest;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultStreamingOutputCallRequest = [[RMTStreamingOutputCallRequest alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultStreamingOutputCallRequest;
+}
+- (RMTStreamingOutputCallRequestBuilder*) clear {
+ self.resultStreamingOutputCallRequest = [[RMTStreamingOutputCallRequest alloc] init];
+ return self;
+}
+- (RMTStreamingOutputCallRequestBuilder*) clone {
+ return [RMTStreamingOutputCallRequest builderWithPrototype:resultStreamingOutputCallRequest];
+}
+- (RMTStreamingOutputCallRequest*) defaultInstance {
+ return [RMTStreamingOutputCallRequest defaultInstance];
+}
+- (RMTStreamingOutputCallRequest*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTStreamingOutputCallRequest*) buildPartial {
+ RMTStreamingOutputCallRequest* returnMe = resultStreamingOutputCallRequest;
+ self.resultStreamingOutputCallRequest = nil;
+ return returnMe;
+}
+- (RMTStreamingOutputCallRequestBuilder*) mergeFrom:(RMTStreamingOutputCallRequest*) other {
+ if (other == [RMTStreamingOutputCallRequest defaultInstance]) {
+ return self;
+ }
+ if (other.hasResponseType) {
+ [self setResponseType:other.responseType];
+ }
+ if (other.responseParametersArray.count > 0) {
+ if (resultStreamingOutputCallRequest.responseParametersArray == nil) {
+ resultStreamingOutputCallRequest.responseParametersArray = [[NSMutableArray alloc] initWithArray:other.responseParametersArray];
+ } else {
+ [resultStreamingOutputCallRequest.responseParametersArray addObjectsFromArray:other.responseParametersArray];
+ }
+ }
+ if (other.hasPayload) {
+ [self mergePayload:other.payload];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTStreamingOutputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTStreamingOutputCallRequestBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 8: {
+ RMTPayloadType value = (RMTPayloadType)[input readEnum];
+ if (RMTPayloadTypeIsValidValue(value)) {
+ [self setResponseType:value];
+ } else {
+ [unknownFields mergeVarintField:1 value:value];
+ }
+ break;
+ }
+ case 18: {
+ RMTResponseParametersBuilder* subBuilder = [RMTResponseParameters builder];
+ [input readMessage:subBuilder extensionRegistry:extensionRegistry];
+ [self addResponseParameters:[subBuilder buildPartial]];
+ break;
+ }
+ case 26: {
+ RMTPayloadBuilder* subBuilder = [RMTPayload builder];
+ if (self.hasPayload) {
+ [subBuilder mergeFrom:self.payload];
+ }
+ [input readMessage:subBuilder extensionRegistry:extensionRegistry];
+ [self setPayload:[subBuilder buildPartial]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasResponseType {
+ return resultStreamingOutputCallRequest.hasResponseType;
+}
+- (RMTPayloadType) responseType {
+ return resultStreamingOutputCallRequest.responseType;
+}
+- (RMTStreamingOutputCallRequestBuilder*) setResponseType:(RMTPayloadType) value {
+ resultStreamingOutputCallRequest.hasResponseType = YES;
+ resultStreamingOutputCallRequest.responseType = value;
+ return self;
+}
+- (RMTStreamingOutputCallRequestBuilder*) clearResponseType {
+ resultStreamingOutputCallRequest.hasResponseType = NO;
+ resultStreamingOutputCallRequest.responseType = RMTPayloadTypeCompressable;
+ return self;
+}
+- (NSMutableArray *)responseParameters {
+ return resultStreamingOutputCallRequest.responseParametersArray;
+}
+- (RMTResponseParameters*)responseParametersAtIndex:(NSUInteger)index {
+ return [resultStreamingOutputCallRequest responseParametersAtIndex:index];
+}
+- (RMTStreamingOutputCallRequestBuilder *)addResponseParameters:(RMTResponseParameters*)value {
+ if (resultStreamingOutputCallRequest.responseParametersArray == nil) {
+ resultStreamingOutputCallRequest.responseParametersArray = [[NSMutableArray alloc]init];
+ }
+ [resultStreamingOutputCallRequest.responseParametersArray addObject:value];
+ return self;
+}
+- (RMTStreamingOutputCallRequestBuilder *)setResponseParametersArray:(NSArray *)array {
+ resultStreamingOutputCallRequest.responseParametersArray = [[NSMutableArray alloc]initWithArray:array];
+ return self;
+}
+- (RMTStreamingOutputCallRequestBuilder *)clearResponseParameters {
+ resultStreamingOutputCallRequest.responseParametersArray = nil;
+ return self;
+}
+- (BOOL) hasPayload {
+ return resultStreamingOutputCallRequest.hasPayload;
+}
+- (RMTPayload*) payload {
+ return resultStreamingOutputCallRequest.payload;
+}
+- (RMTStreamingOutputCallRequestBuilder*) setPayload:(RMTPayload*) value {
+ resultStreamingOutputCallRequest.hasPayload = YES;
+ resultStreamingOutputCallRequest.payload = value;
+ return self;
+}
+- (RMTStreamingOutputCallRequestBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue {
+ return [self setPayload:[builderForValue build]];
+}
+- (RMTStreamingOutputCallRequestBuilder*) mergePayload:(RMTPayload*) value {
+ if (resultStreamingOutputCallRequest.hasPayload &&
+ resultStreamingOutputCallRequest.payload != [RMTPayload defaultInstance]) {
+ resultStreamingOutputCallRequest.payload =
+ [[[RMTPayload builderWithPrototype:resultStreamingOutputCallRequest.payload] mergeFrom:value] buildPartial];
+ } else {
+ resultStreamingOutputCallRequest.payload = value;
+ }
+ resultStreamingOutputCallRequest.hasPayload = YES;
+ return self;
+}
+- (RMTStreamingOutputCallRequestBuilder*) clearPayload {
+ resultStreamingOutputCallRequest.hasPayload = NO;
+ resultStreamingOutputCallRequest.payload = [RMTPayload defaultInstance];
+ return self;
+}
+@end
+
+@interface RMTStreamingOutputCallResponse ()
+@property (strong) RMTPayload* payload;
+@end
+
+@implementation RMTStreamingOutputCallResponse
+
+- (BOOL) hasPayload {
+ return !!hasPayload_;
+}
+- (void) setHasPayload:(BOOL) _value_ {
+ hasPayload_ = !!_value_;
+}
+@synthesize payload;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.payload = [RMTPayload defaultInstance];
+ }
+ return self;
+}
+static RMTStreamingOutputCallResponse* defaultRMTStreamingOutputCallResponseInstance = nil;
++ (void) initialize {
+ if (self == [RMTStreamingOutputCallResponse class]) {
+ defaultRMTStreamingOutputCallResponseInstance = [[RMTStreamingOutputCallResponse alloc] init];
+ }
+}
++ (instancetype) defaultInstance {
+ return defaultRMTStreamingOutputCallResponseInstance;
+}
+- (instancetype) defaultInstance {
+ return defaultRMTStreamingOutputCallResponseInstance;
+}
+- (BOOL) isInitialized {
+ return YES;
+}
+- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
+ if (self.hasPayload) {
+ [output writeMessage:1 value:self.payload];
+ }
+ [self.unknownFields writeToCodedOutputStream:output];
+}
+- (SInt32) serializedSize {
+ __block SInt32 size_ = memoizedSerializedSize;
+ if (size_ != -1) {
+ return size_;
+ }
+
+ size_ = 0;
+ if (self.hasPayload) {
+ size_ += computeMessageSize(1, self.payload);
+ }
+ size_ += self.unknownFields.serializedSize;
+ memoizedSerializedSize = size_;
+ return size_;
+}
++ (RMTStreamingOutputCallResponse*) parseFromData:(NSData*) data {
+ return (RMTStreamingOutputCallResponse*)[[[RMTStreamingOutputCallResponse builder] mergeFromData:data] build];
+}
++ (RMTStreamingOutputCallResponse*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingOutputCallResponse*)[[[RMTStreamingOutputCallResponse builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingOutputCallResponse*) parseFromInputStream:(NSInputStream*) input {
+ return (RMTStreamingOutputCallResponse*)[[[RMTStreamingOutputCallResponse builder] mergeFromInputStream:input] build];
+}
++ (RMTStreamingOutputCallResponse*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingOutputCallResponse*)[[[RMTStreamingOutputCallResponse builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingOutputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input {
+ return (RMTStreamingOutputCallResponse*)[[[RMTStreamingOutputCallResponse builder] mergeFromCodedInputStream:input] build];
+}
++ (RMTStreamingOutputCallResponse*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ return (RMTStreamingOutputCallResponse*)[[[RMTStreamingOutputCallResponse builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
+}
++ (RMTStreamingOutputCallResponseBuilder*) builder {
+ return [[RMTStreamingOutputCallResponseBuilder alloc] init];
+}
++ (RMTStreamingOutputCallResponseBuilder*) builderWithPrototype:(RMTStreamingOutputCallResponse*) prototype {
+ return [[RMTStreamingOutputCallResponse builder] mergeFrom:prototype];
+}
+- (RMTStreamingOutputCallResponseBuilder*) builder {
+ return [RMTStreamingOutputCallResponse builder];
+}
+- (RMTStreamingOutputCallResponseBuilder*) toBuilder {
+ return [RMTStreamingOutputCallResponse builderWithPrototype:self];
+}
+- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
+ if (self.hasPayload) {
+ [output appendFormat:@"%@%@ {\n", indent, @"payload"];
+ [self.payload writeDescriptionTo:output
+ withIndent:[NSString stringWithFormat:@"%@ ", indent]];
+ [output appendFormat:@"%@}\n", indent];
+ }
+ [self.unknownFields writeDescriptionTo:output withIndent:indent];
+}
+- (BOOL) isEqual:(id)other {
+ if (other == self) {
+ return YES;
+ }
+ if (![other isKindOfClass:[RMTStreamingOutputCallResponse class]]) {
+ return NO;
+ }
+ RMTStreamingOutputCallResponse *otherMessage = other;
+ return
+ self.hasPayload == otherMessage.hasPayload &&
+ (!self.hasPayload || [self.payload isEqual:otherMessage.payload]) &&
+ (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
+}
+- (NSUInteger) hash {
+ __block NSUInteger hashCode = 7;
+ if (self.hasPayload) {
+ hashCode = hashCode * 31 + [self.payload hash];
+ }
+ hashCode = hashCode * 31 + [self.unknownFields hash];
+ return hashCode;
+}
+@end
+
+@interface RMTStreamingOutputCallResponseBuilder()
+@property (strong) RMTStreamingOutputCallResponse* resultStreamingOutputCallResponse;
+@end
+
+@implementation RMTStreamingOutputCallResponseBuilder
+@synthesize resultStreamingOutputCallResponse;
+- (instancetype) init {
+ if ((self = [super init])) {
+ self.resultStreamingOutputCallResponse = [[RMTStreamingOutputCallResponse alloc] init];
+ }
+ return self;
+}
+- (PBGeneratedMessage*) internalGetResult {
+ return resultStreamingOutputCallResponse;
+}
+- (RMTStreamingOutputCallResponseBuilder*) clear {
+ self.resultStreamingOutputCallResponse = [[RMTStreamingOutputCallResponse alloc] init];
+ return self;
+}
+- (RMTStreamingOutputCallResponseBuilder*) clone {
+ return [RMTStreamingOutputCallResponse builderWithPrototype:resultStreamingOutputCallResponse];
+}
+- (RMTStreamingOutputCallResponse*) defaultInstance {
+ return [RMTStreamingOutputCallResponse defaultInstance];
+}
+- (RMTStreamingOutputCallResponse*) build {
+ [self checkInitialized];
+ return [self buildPartial];
+}
+- (RMTStreamingOutputCallResponse*) buildPartial {
+ RMTStreamingOutputCallResponse* returnMe = resultStreamingOutputCallResponse;
+ self.resultStreamingOutputCallResponse = nil;
+ return returnMe;
+}
+- (RMTStreamingOutputCallResponseBuilder*) mergeFrom:(RMTStreamingOutputCallResponse*) other {
+ if (other == [RMTStreamingOutputCallResponse defaultInstance]) {
+ return self;
+ }
+ if (other.hasPayload) {
+ [self mergePayload:other.payload];
+ }
+ [self mergeUnknownFields:other.unknownFields];
+ return self;
+}
+- (RMTStreamingOutputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
+ return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
+}
+- (RMTStreamingOutputCallResponseBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
+ PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
+ while (YES) {
+ SInt32 tag = [input readTag];
+ switch (tag) {
+ case 0:
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ default: {
+ if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
+ [self setUnknownFields:[unknownFields build]];
+ return self;
+ }
+ break;
+ }
+ case 10: {
+ RMTPayloadBuilder* subBuilder = [RMTPayload builder];
+ if (self.hasPayload) {
+ [subBuilder mergeFrom:self.payload];
+ }
+ [input readMessage:subBuilder extensionRegistry:extensionRegistry];
+ [self setPayload:[subBuilder buildPartial]];
+ break;
+ }
+ }
+ }
+}
+- (BOOL) hasPayload {
+ return resultStreamingOutputCallResponse.hasPayload;
+}
+- (RMTPayload*) payload {
+ return resultStreamingOutputCallResponse.payload;
+}
+- (RMTStreamingOutputCallResponseBuilder*) setPayload:(RMTPayload*) value {
+ resultStreamingOutputCallResponse.hasPayload = YES;
+ resultStreamingOutputCallResponse.payload = value;
+ return self;
+}
+- (RMTStreamingOutputCallResponseBuilder*) setPayloadBuilder:(RMTPayloadBuilder*) builderForValue {
+ return [self setPayload:[builderForValue build]];
+}
+- (RMTStreamingOutputCallResponseBuilder*) mergePayload:(RMTPayload*) value {
+ if (resultStreamingOutputCallResponse.hasPayload &&
+ resultStreamingOutputCallResponse.payload != [RMTPayload defaultInstance]) {
+ resultStreamingOutputCallResponse.payload =
+ [[[RMTPayload builderWithPrototype:resultStreamingOutputCallResponse.payload] mergeFrom:value] buildPartial];
+ } else {
+ resultStreamingOutputCallResponse.payload = value;
+ }
+ resultStreamingOutputCallResponse.hasPayload = YES;
+ return self;
+}
+- (RMTStreamingOutputCallResponseBuilder*) clearPayload {
+ resultStreamingOutputCallResponse.hasPayload = NO;
+ resultStreamingOutputCallResponse.payload = [RMTPayload defaultInstance];
+ return self;
+}
+@end
+
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec
new file mode 100644
index 0000000000..4790594bc5
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec
@@ -0,0 +1,17 @@
+Pod::Spec.new do |s|
+ s.name = 'RemoteTest'
+ s.version = '0.0.1'
+ s.summary = 'Protobuf library generated from test.proto, messages.proto, and empty.proto'
+ s.homepage = 'https://github.com/grpc/grpc/tree/master/src/objective-c/examples/Sample/RemoteTestClient'
+ s.license = 'New BSD'
+ s.authors = { 'Jorge Canizales' => 'jcanizales@google.com' }
+
+ s.source_files = '*.pb.{h,m}'
+ s.public_header_files = '*.pb.h'
+
+ s.platform = :ios
+ s.ios.deployment_target = '6.0'
+ s.requires_arc = true
+
+ s.dependency 'ProtocolBuffers', '~> 1.9'
+end
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h
new file mode 100644
index 0000000000..6db981dc5b
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h
@@ -0,0 +1,81 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#import <ProtocolBuffers/ProtocolBuffers.h>
+
+#import "Empty.pb.h"
+#import "Messages.pb.h"
+// @@protoc_insertion_point(imports)
+
+@class ObjectiveCFileOptions;
+@class ObjectiveCFileOptionsBuilder;
+@class PBDescriptorProto;
+@class PBDescriptorProtoBuilder;
+@class PBDescriptorProtoExtensionRange;
+@class PBDescriptorProtoExtensionRangeBuilder;
+@class PBEnumDescriptorProto;
+@class PBEnumDescriptorProtoBuilder;
+@class PBEnumOptions;
+@class PBEnumOptionsBuilder;
+@class PBEnumValueDescriptorProto;
+@class PBEnumValueDescriptorProtoBuilder;
+@class PBEnumValueOptions;
+@class PBEnumValueOptionsBuilder;
+@class PBFieldDescriptorProto;
+@class PBFieldDescriptorProtoBuilder;
+@class PBFieldOptions;
+@class PBFieldOptionsBuilder;
+@class PBFileDescriptorProto;
+@class PBFileDescriptorProtoBuilder;
+@class PBFileDescriptorSet;
+@class PBFileDescriptorSetBuilder;
+@class PBFileOptions;
+@class PBFileOptionsBuilder;
+@class PBMessageOptions;
+@class PBMessageOptionsBuilder;
+@class PBMethodDescriptorProto;
+@class PBMethodDescriptorProtoBuilder;
+@class PBMethodOptions;
+@class PBMethodOptionsBuilder;
+@class PBOneofDescriptorProto;
+@class PBOneofDescriptorProtoBuilder;
+@class PBServiceDescriptorProto;
+@class PBServiceDescriptorProtoBuilder;
+@class PBServiceOptions;
+@class PBServiceOptionsBuilder;
+@class PBSourceCodeInfo;
+@class PBSourceCodeInfoBuilder;
+@class PBSourceCodeInfoLocation;
+@class PBSourceCodeInfoLocationBuilder;
+@class PBUninterpretedOption;
+@class PBUninterpretedOptionBuilder;
+@class PBUninterpretedOptionNamePart;
+@class PBUninterpretedOptionNamePartBuilder;
+@class RMTEmpty;
+@class RMTEmptyBuilder;
+@class RMTPayload;
+@class RMTPayloadBuilder;
+@class RMTResponseParameters;
+@class RMTResponseParametersBuilder;
+@class RMTSimpleRequest;
+@class RMTSimpleRequestBuilder;
+@class RMTSimpleResponse;
+@class RMTSimpleResponseBuilder;
+@class RMTStreamingInputCallRequest;
+@class RMTStreamingInputCallRequestBuilder;
+@class RMTStreamingInputCallResponse;
+@class RMTStreamingInputCallResponseBuilder;
+@class RMTStreamingOutputCallRequest;
+@class RMTStreamingOutputCallRequestBuilder;
+@class RMTStreamingOutputCallResponse;
+@class RMTStreamingOutputCallResponseBuilder;
+
+
+
+@interface RMTTestRoot : NSObject {
+}
++ (PBExtensionRegistry*) extensionRegistry;
++ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry;
+@end
+
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m
new file mode 100644
index 0000000000..bd6a29df41
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m
@@ -0,0 +1,27 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#import "Test.pb.h"
+// @@protoc_insertion_point(imports)
+
+@implementation RMTTestRoot
+static PBExtensionRegistry* extensionRegistry = nil;
++ (PBExtensionRegistry*) extensionRegistry {
+ return extensionRegistry;
+}
+
++ (void) initialize {
+ if (self == [RMTTestRoot class]) {
+ PBMutableExtensionRegistry* registry = [PBMutableExtensionRegistry registry];
+ [self registerAllExtensions:registry];
+ [RMTEmptyRoot registerAllExtensions:registry];
+ [RMTMessagesRoot registerAllExtensions:registry];
+ [ObjectivecDescriptorRoot registerAllExtensions:registry];
+ extensionRegistry = registry;
+ }
+}
++ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry {
+}
+@end
+
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/empty.proto b/src/objective-c/examples/Sample/RemoteTestClient/empty.proto
new file mode 100644
index 0000000000..3b626ab131
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/empty.proto
@@ -0,0 +1,46 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto2";
+
+import "google/protobuf/objectivec-descriptor.proto";
+
+package grpc.testing;
+
+option (google.protobuf.objectivec_file_options).class_prefix = "RMT";
+
+// An empty message that you can re-use to avoid defining duplicated empty
+// messages in your project. A typical example is to use it as argument or the
+// return value of a service API. For instance:
+//
+// service Foo {
+// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
+// };
+//
+message Empty {}
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/messages.proto b/src/objective-c/examples/Sample/RemoteTestClient/messages.proto
new file mode 100644
index 0000000000..ab8577401f
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/messages.proto
@@ -0,0 +1,135 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Message definitions to be used by integration test service definitions.
+
+syntax = "proto2";
+
+import "google/protobuf/objectivec-descriptor.proto";
+
+package grpc.testing;
+
+option (google.protobuf.objectivec_file_options).class_prefix = "RMT";
+
+// The type of payload that should be returned.
+enum PayloadType {
+ // Compressable text format.
+ COMPRESSABLE = 0;
+
+ // Uncompressable binary format.
+ UNCOMPRESSABLE = 1;
+
+ // Randomly chosen from all other formats defined in this enum.
+ RANDOM = 2;
+}
+
+// A block of data, to simply increase gRPC message size.
+message Payload {
+ // The type of data in body.
+ optional PayloadType type = 1;
+ // Primary contents of payload.
+ optional bytes body = 2;
+}
+
+// Unary request.
+message SimpleRequest {
+ // Desired payload type in the response from the server.
+ // If response_type is RANDOM, server randomly chooses one from other formats.
+ optional PayloadType response_type = 1;
+
+ // Desired payload size in the response from the server.
+ // If response_type is COMPRESSABLE, this denotes the size before compression.
+ optional int32 response_size = 2;
+
+ // Optional input payload sent along with the request.
+ optional Payload payload = 3;
+
+ // Whether SimpleResponse should include username.
+ optional bool fill_username = 4;
+
+ // Whether SimpleResponse should include OAuth scope.
+ optional bool fill_oauth_scope = 5;
+}
+
+// Unary response, as configured by the request.
+message SimpleResponse {
+ // Payload to increase message size.
+ optional Payload payload = 1;
+ // The user the request came from, for verifying authentication was
+ // successful when the client expected it.
+ optional string username = 2;
+ // OAuth scope.
+ optional string oauth_scope = 3;
+}
+
+// Client-streaming request.
+message StreamingInputCallRequest {
+ // Optional input payload sent along with the request.
+ optional Payload payload = 1;
+
+ // Not expecting any payload from the response.
+}
+
+// Client-streaming response.
+message StreamingInputCallResponse {
+ // Aggregated size of payloads received from the client.
+ optional int32 aggregated_payload_size = 1;
+}
+
+// Configuration for a particular response.
+message ResponseParameters {
+ // Desired payload sizes in responses from the server.
+ // If response_type is COMPRESSABLE, this denotes the size before compression.
+ optional int32 size = 1;
+
+ // Desired interval between consecutive responses in the response stream in
+ // microseconds.
+ optional int32 interval_us = 2;
+}
+
+// Server-streaming request.
+message StreamingOutputCallRequest {
+ // Desired payload type in the response from the server.
+ // If response_type is RANDOM, the payload from each response in the stream
+ // might be of different types. This is to simulate a mixed type of payload
+ // stream.
+ optional PayloadType response_type = 1;
+
+ // Configuration for each expected response message.
+ repeated ResponseParameters response_parameters = 2;
+
+ // Optional input payload sent along with the request.
+ optional Payload payload = 3;
+}
+
+// Server-streaming response, as configured by the request and parameters.
+message StreamingOutputCallResponse {
+ // Payload to increase response size.
+ optional Payload payload = 1;
+}
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/test.proto b/src/objective-c/examples/Sample/RemoteTestClient/test.proto
new file mode 100644
index 0000000000..4b08220599
--- /dev/null
+++ b/src/objective-c/examples/Sample/RemoteTestClient/test.proto
@@ -0,0 +1,74 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto2";
+
+import "empty.proto";
+import "messages.proto";
+import "google/protobuf/objectivec-descriptor.proto";
+
+package grpc.testing;
+
+option (google.protobuf.objectivec_file_options).class_prefix = "RMT";
+
+// A simple service to test the various types of RPCs and experiment with
+// performance with various types of payload.
+service TestService {
+ // One empty request followed by one empty response.
+ rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);
+
+ // One request followed by one response.
+ // TODO(Issue 527): Describe required server behavior.
+ rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
+
+ // One request followed by a sequence of responses (streamed download).
+ // The server returns the payload with client desired type and sizes.
+// rpc StreamingOutputCall(StreamingOutputCallRequest)
+// returns (stream StreamingOutputCallResponse);
+
+ // A sequence of requests followed by one response (streamed upload).
+ // The server returns the aggregated size of client payload as the result.
+// rpc StreamingInputCall(stream StreamingInputCallRequest)
+// returns (StreamingInputCallResponse);
+
+ // A sequence of requests with each request served by the server immediately.
+ // As one request could lead to multiple responses, this interface
+ // demonstrates the idea of full duplexing.
+// rpc FullDuplexCall(stream StreamingOutputCallRequest)
+// returns (stream StreamingOutputCallResponse);
+
+ // A sequence of requests followed by a sequence of responses.
+ // The server buffers all the client requests and then serves them in order. A
+ // stream of responses are returned to the client when the server starts with
+ // first request.
+// rpc HalfDuplexCall(stream StreamingOutputCallRequest)
+// returns (stream StreamingOutputCallResponse);
+}
diff --git a/src/objective-c/examples/Sample/protos/Route_guide.pb.h b/src/objective-c/examples/Sample/RouteGuideClient/Route_guide.pb.h
index 194bfc5f2a..194bfc5f2a 100644
--- a/src/objective-c/examples/Sample/protos/Route_guide.pb.h
+++ b/src/objective-c/examples/Sample/RouteGuideClient/Route_guide.pb.h
diff --git a/src/objective-c/examples/Sample/protos/Route_guide.pb.m b/src/objective-c/examples/Sample/RouteGuideClient/Route_guide.pb.m
index 63cdd00206..63cdd00206 100644
--- a/src/objective-c/examples/Sample/protos/Route_guide.pb.m
+++ b/src/objective-c/examples/Sample/RouteGuideClient/Route_guide.pb.m
diff --git a/src/objective-c/examples/Sample/protos/Route_guide.podspec b/src/objective-c/examples/Sample/RouteGuideClient/Route_guide.podspec
index 6fba1c5c1e..04d847bf8f 100644
--- a/src/objective-c/examples/Sample/protos/Route_guide.podspec
+++ b/src/objective-c/examples/Sample/RouteGuideClient/Route_guide.podspec
@@ -2,7 +2,7 @@ Pod::Spec.new do |s|
s.name = 'Route_guide'
s.version = '0.0.1'
s.summary = 'Protobuf library generated from route_guide.proto'
- s.homepage = 'https://github.com/grpc/grpc/tree/master/src/objective-c/examples/Sample/protos'
+ s.homepage = 'https://github.com/grpc/grpc/tree/master/src/objective-c/examples/Sample/RouteGuideClient'
s.license = 'New BSD'
s.authors = { 'Jorge Canizales' => 'jcanizales@google.com' }
diff --git a/src/objective-c/examples/Sample/protos/route_guide.proto b/src/objective-c/examples/Sample/RouteGuideClient/route_guide.proto
index 91b0372a07..91b0372a07 100644
--- a/src/objective-c/examples/Sample/protos/route_guide.proto
+++ b/src/objective-c/examples/Sample/RouteGuideClient/route_guide.proto
diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
index 162046fca6..3ddaceadce 100644
--- a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
+++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
@@ -1,1024 +1,532 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>archiveVersion</key>
- <string>1</string>
- <key>classes</key>
- <dict/>
- <key>objectVersion</key>
- <string>46</string>
- <key>objects</key>
- <dict>
- <key>04554623324BE4A838846086</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array/>
- <key>inputPaths</key>
- <array/>
- <key>isa</key>
- <string>PBXShellScriptBuildPhase</string>
- <key>name</key>
- <string>Copy Pods Resources</string>
- <key>outputPaths</key>
- <array/>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- <key>shellPath</key>
- <string>/bin/sh</string>
- <key>shellScript</key>
- <string>"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh"
-</string>
- <key>showEnvVarsInLog</key>
- <string>0</string>
- </dict>
- <key>2DC7B7C4C0410F43B9621631</key>
- <dict>
- <key>explicitFileType</key>
- <string>archive.ar</string>
- <key>includeInIndex</key>
- <string>0</string>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>path</key>
- <string>libPods.a</string>
- <key>sourceTree</key>
- <string>BUILT_PRODUCTS_DIR</string>
- </dict>
- <key>41F7486D8F66994B0BFB84AF</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array/>
- <key>inputPaths</key>
- <array/>
- <key>isa</key>
- <string>PBXShellScriptBuildPhase</string>
- <key>name</key>
- <string>Check Pods Manifest.lock</string>
- <key>outputPaths</key>
- <array/>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- <key>shellPath</key>
- <string>/bin/sh</string>
- <key>shellScript</key>
- <string>diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" &gt; /dev/null
-if [[ $? != 0 ]] ; then
- cat &lt;&lt; EOM
-error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
-EOM
- exit 1
-fi
-</string>
- <key>showEnvVarsInLog</key>
- <string>0</string>
- </dict>
- <key>60BBBBB15823BBF7639D7AA9</key>
- <dict>
- <key>fileRef</key>
- <string>2DC7B7C4C0410F43B9621631</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A2611A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A26C1A9322E20015FC5C</string>
- <string>6369A2861A9322E20015FC5C</string>
- <string>6369A26B1A9322E20015FC5C</string>
- <string>AB3331C9AE6488E61B2B094E</string>
- <string>C4C2C5219053E079C9EFB930</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2621A9322E20015FC5C</key>
- <dict>
- <key>attributes</key>
- <dict>
- <key>LastUpgradeCheck</key>
- <string>0610</string>
- <key>ORGANIZATIONNAME</key>
- <string>gRPC</string>
- <key>TargetAttributes</key>
- <dict>
- <key>6369A2691A9322E20015FC5C</key>
- <dict>
- <key>CreatedOnToolsVersion</key>
- <string>6.1.1</string>
- </dict>
- <key>6369A2821A9322E20015FC5C</key>
- <dict>
- <key>CreatedOnToolsVersion</key>
- <string>6.1.1</string>
- <key>TestTargetID</key>
- <string>6369A2691A9322E20015FC5C</string>
- </dict>
- </dict>
- </dict>
- <key>buildConfigurationList</key>
- <string>6369A2651A9322E20015FC5C</string>
- <key>compatibilityVersion</key>
- <string>Xcode 3.2</string>
- <key>developmentRegion</key>
- <string>English</string>
- <key>hasScannedForEncodings</key>
- <string>0</string>
- <key>isa</key>
- <string>PBXProject</string>
- <key>knownRegions</key>
- <array>
- <string>en</string>
- <string>Base</string>
- </array>
- <key>mainGroup</key>
- <string>6369A2611A9322E20015FC5C</string>
- <key>productRefGroup</key>
- <string>6369A26B1A9322E20015FC5C</string>
- <key>projectDirPath</key>
- <string></string>
- <key>projectReferences</key>
- <array/>
- <key>projectRoot</key>
- <string></string>
- <key>targets</key>
- <array>
- <string>6369A2691A9322E20015FC5C</string>
- <string>6369A2821A9322E20015FC5C</string>
- </array>
- </dict>
- <key>6369A2651A9322E20015FC5C</key>
- <dict>
- <key>buildConfigurations</key>
- <array>
- <string>6369A28B1A9322E20015FC5C</string>
- <string>6369A28C1A9322E20015FC5C</string>
- </array>
- <key>defaultConfigurationIsVisible</key>
- <string>0</string>
- <key>defaultConfigurationName</key>
- <string>Release</string>
- <key>isa</key>
- <string>XCConfigurationList</string>
- </dict>
- <key>6369A2661A9322E20015FC5C</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array>
- <string>6369A2761A9322E20015FC5C</string>
- <string>6369A2731A9322E20015FC5C</string>
- <string>6369A2701A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXSourcesBuildPhase</string>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- </dict>
- <key>6369A2671A9322E20015FC5C</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array>
- <string>FC81FE63CA655031F3524EC0</string>
- </array>
- <key>isa</key>
- <string>PBXFrameworksBuildPhase</string>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- </dict>
- <key>6369A2681A9322E20015FC5C</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array>
- <string>6369A2791A9322E20015FC5C</string>
- <string>6369A27E1A9322E20015FC5C</string>
- <string>6369A27B1A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXResourcesBuildPhase</string>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- </dict>
- <key>6369A2691A9322E20015FC5C</key>
- <dict>
- <key>buildConfigurationList</key>
- <string>6369A28D1A9322E20015FC5C</string>
- <key>buildPhases</key>
- <array>
- <string>41F7486D8F66994B0BFB84AF</string>
- <string>6369A2661A9322E20015FC5C</string>
- <string>6369A2671A9322E20015FC5C</string>
- <string>6369A2681A9322E20015FC5C</string>
- <string>04554623324BE4A838846086</string>
- </array>
- <key>buildRules</key>
- <array/>
- <key>dependencies</key>
- <array/>
- <key>isa</key>
- <string>PBXNativeTarget</string>
- <key>name</key>
- <string>Sample</string>
- <key>productName</key>
- <string>Sample</string>
- <key>productReference</key>
- <string>6369A26A1A9322E20015FC5C</string>
- <key>productType</key>
- <string>com.apple.product-type.application</string>
- </dict>
- <key>6369A26A1A9322E20015FC5C</key>
- <dict>
- <key>explicitFileType</key>
- <string>wrapper.application</string>
- <key>includeInIndex</key>
- <string>0</string>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>path</key>
- <string>Sample.app</string>
- <key>sourceTree</key>
- <string>BUILT_PRODUCTS_DIR</string>
- </dict>
- <key>6369A26B1A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A26A1A9322E20015FC5C</string>
- <string>6369A2831A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>name</key>
- <string>Products</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A26C1A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A2711A9322E20015FC5C</string>
- <string>6369A2721A9322E20015FC5C</string>
- <string>6369A2741A9322E20015FC5C</string>
- <string>6369A2751A9322E20015FC5C</string>
- <string>6369A2771A9322E20015FC5C</string>
- <string>6369A27A1A9322E20015FC5C</string>
- <string>6369A27C1A9322E20015FC5C</string>
- <string>6369A26D1A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>path</key>
- <string>Sample</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A26D1A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A26E1A9322E20015FC5C</string>
- <string>6369A26F1A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>name</key>
- <string>Supporting Files</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A26E1A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>text.plist.xml</string>
- <key>path</key>
- <string>Info.plist</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A26F1A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>sourcecode.c.objc</string>
- <key>path</key>
- <string>main.m</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2701A9322E20015FC5C</key>
- <dict>
- <key>fileRef</key>
- <string>6369A26F1A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A2711A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>sourcecode.c.h</string>
- <key>path</key>
- <string>AppDelegate.h</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2721A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>sourcecode.c.objc</string>
- <key>path</key>
- <string>AppDelegate.m</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2731A9322E20015FC5C</key>
- <dict>
- <key>fileRef</key>
- <string>6369A2721A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A2741A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>sourcecode.c.h</string>
- <key>path</key>
- <string>ViewController.h</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2751A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>sourcecode.c.objc</string>
- <key>path</key>
- <string>ViewController.m</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2761A9322E20015FC5C</key>
- <dict>
- <key>fileRef</key>
- <string>6369A2751A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A2771A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A2781A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXVariantGroup</string>
- <key>name</key>
- <string>Main.storyboard</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2781A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>file.storyboard</string>
- <key>name</key>
- <string>Base</string>
- <key>path</key>
- <string>Base.lproj/Main.storyboard</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2791A9322E20015FC5C</key>
- <dict>
- <key>fileRef</key>
- <string>6369A2771A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A27A1A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>folder.assetcatalog</string>
- <key>path</key>
- <string>Images.xcassets</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A27B1A9322E20015FC5C</key>
- <dict>
- <key>fileRef</key>
- <string>6369A27A1A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A27C1A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A27D1A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXVariantGroup</string>
- <key>name</key>
- <string>LaunchScreen.xib</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A27D1A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>file.xib</string>
- <key>name</key>
- <string>Base</string>
- <key>path</key>
- <string>Base.lproj/LaunchScreen.xib</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A27E1A9322E20015FC5C</key>
- <dict>
- <key>fileRef</key>
- <string>6369A27C1A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A27F1A9322E20015FC5C</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array>
- <string>6369A28A1A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXSourcesBuildPhase</string>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- </dict>
- <key>6369A2801A9322E20015FC5C</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array>
- <string>60BBBBB15823BBF7639D7AA9</string>
- </array>
- <key>isa</key>
- <string>PBXFrameworksBuildPhase</string>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- </dict>
- <key>6369A2811A9322E20015FC5C</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array/>
- <key>isa</key>
- <string>PBXResourcesBuildPhase</string>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- </dict>
- <key>6369A2821A9322E20015FC5C</key>
- <dict>
- <key>buildConfigurationList</key>
- <string>6369A2901A9322E20015FC5C</string>
- <key>buildPhases</key>
- <array>
- <string>75C393B2FDC60A22B2121058</string>
- <string>6369A27F1A9322E20015FC5C</string>
- <string>6369A2801A9322E20015FC5C</string>
- <string>6369A2811A9322E20015FC5C</string>
- <string>7B8CDC152F76D6014A96C798</string>
- </array>
- <key>buildRules</key>
- <array/>
- <key>dependencies</key>
- <array>
- <string>6369A2851A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXNativeTarget</string>
- <key>name</key>
- <string>SampleTests</string>
- <key>productName</key>
- <string>SampleTests</string>
- <key>productReference</key>
- <string>6369A2831A9322E20015FC5C</string>
- <key>productType</key>
- <string>com.apple.product-type.bundle.unit-test</string>
- </dict>
- <key>6369A2831A9322E20015FC5C</key>
- <dict>
- <key>explicitFileType</key>
- <string>wrapper.cfbundle</string>
- <key>includeInIndex</key>
- <string>0</string>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>path</key>
- <string>SampleTests.xctest</string>
- <key>sourceTree</key>
- <string>BUILT_PRODUCTS_DIR</string>
- </dict>
- <key>6369A2841A9322E20015FC5C</key>
- <dict>
- <key>containerPortal</key>
- <string>6369A2621A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXContainerItemProxy</string>
- <key>proxyType</key>
- <string>1</string>
- <key>remoteGlobalIDString</key>
- <string>6369A2691A9322E20015FC5C</string>
- <key>remoteInfo</key>
- <string>Sample</string>
- </dict>
- <key>6369A2851A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXTargetDependency</string>
- <key>target</key>
- <string>6369A2691A9322E20015FC5C</string>
- <key>targetProxy</key>
- <string>6369A2841A9322E20015FC5C</string>
- </dict>
- <key>6369A2861A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A2891A9322E20015FC5C</string>
- <string>6369A2871A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>path</key>
- <string>SampleTests</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2871A9322E20015FC5C</key>
- <dict>
- <key>children</key>
- <array>
- <string>6369A2881A9322E20015FC5C</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>name</key>
- <string>Supporting Files</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2881A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>text.plist.xml</string>
- <key>path</key>
- <string>Info.plist</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A2891A9322E20015FC5C</key>
- <dict>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>sourcecode.c.objc</string>
- <key>path</key>
- <string>SampleTests.m</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>6369A28A1A9322E20015FC5C</key>
- <dict>
- <key>fileRef</key>
- <string>6369A2891A9322E20015FC5C</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- <key>6369A28B1A9322E20015FC5C</key>
- <dict>
- <key>buildSettings</key>
- <dict>
- <key>ALWAYS_SEARCH_USER_PATHS</key>
- <string>NO</string>
- <key>CLANG_CXX_LANGUAGE_STANDARD</key>
- <string>gnu++0x</string>
- <key>CLANG_CXX_LIBRARY</key>
- <string>libc++</string>
- <key>CLANG_ENABLE_MODULES</key>
- <string>YES</string>
- <key>CLANG_ENABLE_OBJC_ARC</key>
- <string>YES</string>
- <key>CLANG_WARN_BOOL_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_CONSTANT_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_DIRECT_OBJC_ISA_USAGE</key>
- <string>YES_ERROR</string>
- <key>CLANG_WARN_EMPTY_BODY</key>
- <string>YES</string>
- <key>CLANG_WARN_ENUM_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_INT_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_OBJC_ROOT_CLASS</key>
- <string>YES_ERROR</string>
- <key>CLANG_WARN_UNREACHABLE_CODE</key>
- <string>YES</string>
- <key>CLANG_WARN__DUPLICATE_METHOD_MATCH</key>
- <string>YES</string>
- <key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
- <string>iPhone Developer</string>
- <key>COPY_PHASE_STRIP</key>
- <string>NO</string>
- <key>ENABLE_STRICT_OBJC_MSGSEND</key>
- <string>YES</string>
- <key>GCC_C_LANGUAGE_STANDARD</key>
- <string>gnu99</string>
- <key>GCC_DYNAMIC_NO_PIC</key>
- <string>NO</string>
- <key>GCC_OPTIMIZATION_LEVEL</key>
- <string>0</string>
- <key>GCC_PREPROCESSOR_DEFINITIONS</key>
- <array>
- <string>DEBUG=1</string>
- <string>$(inherited)</string>
- </array>
- <key>GCC_SYMBOLS_PRIVATE_EXTERN</key>
- <string>NO</string>
- <key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
- <string>YES</string>
- <key>GCC_WARN_ABOUT_RETURN_TYPE</key>
- <string>YES_ERROR</string>
- <key>GCC_WARN_UNDECLARED_SELECTOR</key>
- <string>YES</string>
- <key>GCC_WARN_UNINITIALIZED_AUTOS</key>
- <string>YES_AGGRESSIVE</string>
- <key>GCC_WARN_UNUSED_FUNCTION</key>
- <string>YES</string>
- <key>GCC_WARN_UNUSED_VARIABLE</key>
- <string>YES</string>
- <key>IPHONEOS_DEPLOYMENT_TARGET</key>
- <string>8.1</string>
- <key>MTL_ENABLE_DEBUG_INFO</key>
- <string>YES</string>
- <key>ONLY_ACTIVE_ARCH</key>
- <string>YES</string>
- <key>SDKROOT</key>
- <string>iphoneos</string>
- <key>TARGETED_DEVICE_FAMILY</key>
- <string>1,2</string>
- </dict>
- <key>isa</key>
- <string>XCBuildConfiguration</string>
- <key>name</key>
- <string>Debug</string>
- </dict>
- <key>6369A28C1A9322E20015FC5C</key>
- <dict>
- <key>buildSettings</key>
- <dict>
- <key>ALWAYS_SEARCH_USER_PATHS</key>
- <string>NO</string>
- <key>CLANG_CXX_LANGUAGE_STANDARD</key>
- <string>gnu++0x</string>
- <key>CLANG_CXX_LIBRARY</key>
- <string>libc++</string>
- <key>CLANG_ENABLE_MODULES</key>
- <string>YES</string>
- <key>CLANG_ENABLE_OBJC_ARC</key>
- <string>YES</string>
- <key>CLANG_WARN_BOOL_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_CONSTANT_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_DIRECT_OBJC_ISA_USAGE</key>
- <string>YES_ERROR</string>
- <key>CLANG_WARN_EMPTY_BODY</key>
- <string>YES</string>
- <key>CLANG_WARN_ENUM_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_INT_CONVERSION</key>
- <string>YES</string>
- <key>CLANG_WARN_OBJC_ROOT_CLASS</key>
- <string>YES_ERROR</string>
- <key>CLANG_WARN_UNREACHABLE_CODE</key>
- <string>YES</string>
- <key>CLANG_WARN__DUPLICATE_METHOD_MATCH</key>
- <string>YES</string>
- <key>CODE_SIGN_IDENTITY[sdk=iphoneos*]</key>
- <string>iPhone Developer</string>
- <key>COPY_PHASE_STRIP</key>
- <string>YES</string>
- <key>ENABLE_NS_ASSERTIONS</key>
- <string>NO</string>
- <key>ENABLE_STRICT_OBJC_MSGSEND</key>
- <string>YES</string>
- <key>GCC_C_LANGUAGE_STANDARD</key>
- <string>gnu99</string>
- <key>GCC_WARN_64_TO_32_BIT_CONVERSION</key>
- <string>YES</string>
- <key>GCC_WARN_ABOUT_RETURN_TYPE</key>
- <string>YES_ERROR</string>
- <key>GCC_WARN_UNDECLARED_SELECTOR</key>
- <string>YES</string>
- <key>GCC_WARN_UNINITIALIZED_AUTOS</key>
- <string>YES_AGGRESSIVE</string>
- <key>GCC_WARN_UNUSED_FUNCTION</key>
- <string>YES</string>
- <key>GCC_WARN_UNUSED_VARIABLE</key>
- <string>YES</string>
- <key>IPHONEOS_DEPLOYMENT_TARGET</key>
- <string>8.1</string>
- <key>MTL_ENABLE_DEBUG_INFO</key>
- <string>NO</string>
- <key>SDKROOT</key>
- <string>iphoneos</string>
- <key>TARGETED_DEVICE_FAMILY</key>
- <string>1,2</string>
- <key>VALIDATE_PRODUCT</key>
- <string>YES</string>
- </dict>
- <key>isa</key>
- <string>XCBuildConfiguration</string>
- <key>name</key>
- <string>Release</string>
- </dict>
- <key>6369A28D1A9322E20015FC5C</key>
- <dict>
- <key>buildConfigurations</key>
- <array>
- <string>6369A28E1A9322E20015FC5C</string>
- <string>6369A28F1A9322E20015FC5C</string>
- </array>
- <key>defaultConfigurationIsVisible</key>
- <string>0</string>
- <key>isa</key>
- <string>XCConfigurationList</string>
- </dict>
- <key>6369A28E1A9322E20015FC5C</key>
- <dict>
- <key>baseConfigurationReference</key>
- <string>AC29DD6FCDF962F519FEBB0D</string>
- <key>buildSettings</key>
- <dict>
- <key>ASSETCATALOG_COMPILER_APPICON_NAME</key>
- <string>AppIcon</string>
- <key>INFOPLIST_FILE</key>
- <string>Sample/Info.plist</string>
- <key>LD_RUNPATH_SEARCH_PATHS</key>
- <string>$(inherited) @executable_path/Frameworks</string>
- <key>PRODUCT_NAME</key>
- <string>$(TARGET_NAME)</string>
- </dict>
- <key>isa</key>
- <string>XCBuildConfiguration</string>
- <key>name</key>
- <string>Debug</string>
- </dict>
- <key>6369A28F1A9322E20015FC5C</key>
- <dict>
- <key>baseConfigurationReference</key>
- <string>C68330F8D451CC6ACEABA09F</string>
- <key>buildSettings</key>
- <dict>
- <key>ASSETCATALOG_COMPILER_APPICON_NAME</key>
- <string>AppIcon</string>
- <key>INFOPLIST_FILE</key>
- <string>Sample/Info.plist</string>
- <key>LD_RUNPATH_SEARCH_PATHS</key>
- <string>$(inherited) @executable_path/Frameworks</string>
- <key>PRODUCT_NAME</key>
- <string>$(TARGET_NAME)</string>
- </dict>
- <key>isa</key>
- <string>XCBuildConfiguration</string>
- <key>name</key>
- <string>Release</string>
- </dict>
- <key>6369A2901A9322E20015FC5C</key>
- <dict>
- <key>buildConfigurations</key>
- <array>
- <string>6369A2911A9322E20015FC5C</string>
- <string>6369A2921A9322E20015FC5C</string>
- </array>
- <key>defaultConfigurationIsVisible</key>
- <string>0</string>
- <key>isa</key>
- <string>XCConfigurationList</string>
- </dict>
- <key>6369A2911A9322E20015FC5C</key>
- <dict>
- <key>baseConfigurationReference</key>
- <string>AC29DD6FCDF962F519FEBB0D</string>
- <key>buildSettings</key>
- <dict>
- <key>BUNDLE_LOADER</key>
- <string>$(TEST_HOST)</string>
- <key>FRAMEWORK_SEARCH_PATHS</key>
- <array>
- <string>$(SDKROOT)/Developer/Library/Frameworks</string>
- <string>$(inherited)</string>
- </array>
- <key>GCC_PREPROCESSOR_DEFINITIONS</key>
- <array>
- <string>DEBUG=1</string>
- <string>$(inherited)</string>
- </array>
- <key>INFOPLIST_FILE</key>
- <string>SampleTests/Info.plist</string>
- <key>LD_RUNPATH_SEARCH_PATHS</key>
- <string>$(inherited) @executable_path/Frameworks @loader_path/Frameworks</string>
- <key>PRODUCT_NAME</key>
- <string>$(TARGET_NAME)</string>
- <key>TEST_HOST</key>
- <string>$(BUILT_PRODUCTS_DIR)/Sample.app/Sample</string>
- </dict>
- <key>isa</key>
- <string>XCBuildConfiguration</string>
- <key>name</key>
- <string>Debug</string>
- </dict>
- <key>6369A2921A9322E20015FC5C</key>
- <dict>
- <key>baseConfigurationReference</key>
- <string>C68330F8D451CC6ACEABA09F</string>
- <key>buildSettings</key>
- <dict>
- <key>BUNDLE_LOADER</key>
- <string>$(TEST_HOST)</string>
- <key>FRAMEWORK_SEARCH_PATHS</key>
- <array>
- <string>$(SDKROOT)/Developer/Library/Frameworks</string>
- <string>$(inherited)</string>
- </array>
- <key>INFOPLIST_FILE</key>
- <string>SampleTests/Info.plist</string>
- <key>LD_RUNPATH_SEARCH_PATHS</key>
- <string>$(inherited) @executable_path/Frameworks @loader_path/Frameworks</string>
- <key>PRODUCT_NAME</key>
- <string>$(TARGET_NAME)</string>
- <key>TEST_HOST</key>
- <string>$(BUILT_PRODUCTS_DIR)/Sample.app/Sample</string>
- </dict>
- <key>isa</key>
- <string>XCBuildConfiguration</string>
- <key>name</key>
- <string>Release</string>
- </dict>
- <key>75C393B2FDC60A22B2121058</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array/>
- <key>inputPaths</key>
- <array/>
- <key>isa</key>
- <string>PBXShellScriptBuildPhase</string>
- <key>name</key>
- <string>Check Pods Manifest.lock</string>
- <key>outputPaths</key>
- <array/>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- <key>shellPath</key>
- <string>/bin/sh</string>
- <key>shellScript</key>
- <string>diff "${PODS_ROOT}/../Podfile.lock" "${PODS_ROOT}/Manifest.lock" &gt; /dev/null
-if [[ $? != 0 ]] ; then
- cat &lt;&lt; EOM
-error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
-EOM
- exit 1
-fi
-</string>
- <key>showEnvVarsInLog</key>
- <string>0</string>
- </dict>
- <key>7B8CDC152F76D6014A96C798</key>
- <dict>
- <key>buildActionMask</key>
- <string>2147483647</string>
- <key>files</key>
- <array/>
- <key>inputPaths</key>
- <array/>
- <key>isa</key>
- <string>PBXShellScriptBuildPhase</string>
- <key>name</key>
- <string>Copy Pods Resources</string>
- <key>outputPaths</key>
- <array/>
- <key>runOnlyForDeploymentPostprocessing</key>
- <string>0</string>
- <key>shellPath</key>
- <string>/bin/sh</string>
- <key>shellScript</key>
- <string>"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh"
-</string>
- <key>showEnvVarsInLog</key>
- <string>0</string>
- </dict>
- <key>AB3331C9AE6488E61B2B094E</key>
- <dict>
- <key>children</key>
- <array>
- <string>AC29DD6FCDF962F519FEBB0D</string>
- <string>C68330F8D451CC6ACEABA09F</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>name</key>
- <string>Pods</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>AC29DD6FCDF962F519FEBB0D</key>
- <dict>
- <key>includeInIndex</key>
- <string>1</string>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>text.xcconfig</string>
- <key>name</key>
- <string>Pods.debug.xcconfig</string>
- <key>path</key>
- <string>Pods/Target Support Files/Pods/Pods.debug.xcconfig</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>C4C2C5219053E079C9EFB930</key>
- <dict>
- <key>children</key>
- <array>
- <string>2DC7B7C4C0410F43B9621631</string>
- </array>
- <key>isa</key>
- <string>PBXGroup</string>
- <key>name</key>
- <string>Frameworks</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>C68330F8D451CC6ACEABA09F</key>
- <dict>
- <key>includeInIndex</key>
- <string>1</string>
- <key>isa</key>
- <string>PBXFileReference</string>
- <key>lastKnownFileType</key>
- <string>text.xcconfig</string>
- <key>name</key>
- <string>Pods.release.xcconfig</string>
- <key>path</key>
- <string>Pods/Target Support Files/Pods/Pods.release.xcconfig</string>
- <key>sourceTree</key>
- <string>&lt;group&gt;</string>
- </dict>
- <key>FC81FE63CA655031F3524EC0</key>
- <dict>
- <key>fileRef</key>
- <string>2DC7B7C4C0410F43B9621631</string>
- <key>isa</key>
- <string>PBXBuildFile</string>
- </dict>
- </dict>
- <key>rootObject</key>
- <string>6369A2621A9322E20015FC5C</string>
-</dict>
-</plist>
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 60BBBBB15823BBF7639D7AA9 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC7B7C4C0410F43B9621631 /* libPods.a */; };
+ 6369A2701A9322E20015FC5C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A26F1A9322E20015FC5C /* main.m */; };
+ 6369A2731A9322E20015FC5C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2721A9322E20015FC5C /* AppDelegate.m */; };
+ 6369A2761A9322E20015FC5C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2751A9322E20015FC5C /* ViewController.m */; };
+ 6369A2791A9322E20015FC5C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6369A2771A9322E20015FC5C /* Main.storyboard */; };
+ 6369A27B1A9322E20015FC5C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6369A27A1A9322E20015FC5C /* Images.xcassets */; };
+ 6369A27E1A9322E20015FC5C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6369A27C1A9322E20015FC5C /* LaunchScreen.xib */; };
+ 6369A28A1A9322E20015FC5C /* SampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2891A9322E20015FC5C /* SampleTests.m */; };
+ 63D886A71AE73797000580D7 /* RemoteTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D886A61AE73797000580D7 /* RemoteTests.m */; };
+ FC81FE63CA655031F3524EC0 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC7B7C4C0410F43B9621631 /* libPods.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 6369A2841A9322E20015FC5C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 6369A2621A9322E20015FC5C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 6369A2691A9322E20015FC5C;
+ remoteInfo = Sample;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 2DC7B7C4C0410F43B9621631 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 6369A26A1A9322E20015FC5C /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 6369A26E1A9322E20015FC5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 6369A26F1A9322E20015FC5C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 6369A2711A9322E20015FC5C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 6369A2721A9322E20015FC5C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 6369A2741A9322E20015FC5C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+ 6369A2751A9322E20015FC5C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
+ 6369A2781A9322E20015FC5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 6369A27A1A9322E20015FC5C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
+ 6369A27D1A9322E20015FC5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
+ 6369A2831A9322E20015FC5C /* SampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 6369A2881A9322E20015FC5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 6369A2891A9322E20015FC5C /* SampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleTests.m; sourceTree = "<group>"; };
+ 63D886A61AE73797000580D7 /* RemoteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteTests.m; sourceTree = "<group>"; };
+ AC29DD6FCDF962F519FEBB0D /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
+ C68330F8D451CC6ACEABA09F /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 6369A2671A9322E20015FC5C /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ FC81FE63CA655031F3524EC0 /* libPods.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 6369A2801A9322E20015FC5C /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 60BBBBB15823BBF7639D7AA9 /* libPods.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 6369A2611A9322E20015FC5C = {
+ isa = PBXGroup;
+ children = (
+ 6369A26C1A9322E20015FC5C /* Sample */,
+ 6369A2861A9322E20015FC5C /* SampleTests */,
+ 6369A26B1A9322E20015FC5C /* Products */,
+ AB3331C9AE6488E61B2B094E /* Pods */,
+ C4C2C5219053E079C9EFB930 /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ 6369A26B1A9322E20015FC5C /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 6369A26A1A9322E20015FC5C /* Sample.app */,
+ 6369A2831A9322E20015FC5C /* SampleTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 6369A26C1A9322E20015FC5C /* Sample */ = {
+ isa = PBXGroup;
+ children = (
+ 6369A2711A9322E20015FC5C /* AppDelegate.h */,
+ 6369A2721A9322E20015FC5C /* AppDelegate.m */,
+ 6369A2741A9322E20015FC5C /* ViewController.h */,
+ 6369A2751A9322E20015FC5C /* ViewController.m */,
+ 6369A2771A9322E20015FC5C /* Main.storyboard */,
+ 6369A27A1A9322E20015FC5C /* Images.xcassets */,
+ 6369A27C1A9322E20015FC5C /* LaunchScreen.xib */,
+ 6369A26D1A9322E20015FC5C /* Supporting Files */,
+ );
+ path = Sample;
+ sourceTree = "<group>";
+ };
+ 6369A26D1A9322E20015FC5C /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 6369A26E1A9322E20015FC5C /* Info.plist */,
+ 6369A26F1A9322E20015FC5C /* main.m */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ 6369A2861A9322E20015FC5C /* SampleTests */ = {
+ isa = PBXGroup;
+ children = (
+ 63D886A61AE73797000580D7 /* RemoteTests.m */,
+ 6369A2891A9322E20015FC5C /* SampleTests.m */,
+ 6369A2871A9322E20015FC5C /* Supporting Files */,
+ );
+ path = SampleTests;
+ sourceTree = "<group>";
+ };
+ 6369A2871A9322E20015FC5C /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 6369A2881A9322E20015FC5C /* Info.plist */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ AB3331C9AE6488E61B2B094E /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ AC29DD6FCDF962F519FEBB0D /* Pods.debug.xcconfig */,
+ C68330F8D451CC6ACEABA09F /* Pods.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+ C4C2C5219053E079C9EFB930 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 2DC7B7C4C0410F43B9621631 /* libPods.a */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 6369A2691A9322E20015FC5C /* Sample */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 6369A28D1A9322E20015FC5C /* Build configuration list for PBXNativeTarget "Sample" */;
+ buildPhases = (
+ 41F7486D8F66994B0BFB84AF /* Check Pods Manifest.lock */,
+ 6369A2661A9322E20015FC5C /* Sources */,
+ 6369A2671A9322E20015FC5C /* Frameworks */,
+ 6369A2681A9322E20015FC5C /* Resources */,
+ 04554623324BE4A838846086 /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Sample;
+ productName = Sample;
+ productReference = 6369A26A1A9322E20015FC5C /* Sample.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 6369A2821A9322E20015FC5C /* SampleTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 6369A2901A9322E20015FC5C /* Build configuration list for PBXNativeTarget "SampleTests" */;
+ buildPhases = (
+ 75C393B2FDC60A22B2121058 /* Check Pods Manifest.lock */,
+ 6369A27F1A9322E20015FC5C /* Sources */,
+ 6369A2801A9322E20015FC5C /* Frameworks */,
+ 6369A2811A9322E20015FC5C /* Resources */,
+ 7B8CDC152F76D6014A96C798 /* Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 6369A2851A9322E20015FC5C /* PBXTargetDependency */,
+ );
+ name = SampleTests;
+ productName = SampleTests;
+ productReference = 6369A2831A9322E20015FC5C /* SampleTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 6369A2621A9322E20015FC5C /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0610;
+ ORGANIZATIONNAME = gRPC;
+ TargetAttributes = {
+ 6369A2691A9322E20015FC5C = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ 6369A2821A9322E20015FC5C = {
+ CreatedOnToolsVersion = 6.1.1;
+ TestTargetID = 6369A2691A9322E20015FC5C;
+ };
+ };
+ };
+ buildConfigurationList = 6369A2651A9322E20015FC5C /* Build configuration list for PBXProject "Sample" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 6369A2611A9322E20015FC5C;
+ productRefGroup = 6369A26B1A9322E20015FC5C /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 6369A2691A9322E20015FC5C /* Sample */,
+ 6369A2821A9322E20015FC5C /* SampleTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 6369A2681A9322E20015FC5C /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6369A2791A9322E20015FC5C /* Main.storyboard in Resources */,
+ 6369A27E1A9322E20015FC5C /* LaunchScreen.xib in Resources */,
+ 6369A27B1A9322E20015FC5C /* Images.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 6369A2811A9322E20015FC5C /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 04554623324BE4A838846086 /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 41F7486D8F66994B0BFB84AF /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 75C393B2FDC60A22B2121058 /* Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Check Pods Manifest.lock";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
+ showEnvVarsInLog = 0;
+ };
+ 7B8CDC152F76D6014A96C798 /* Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 6369A2661A9322E20015FC5C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6369A2761A9322E20015FC5C /* ViewController.m in Sources */,
+ 6369A2731A9322E20015FC5C /* AppDelegate.m in Sources */,
+ 6369A2701A9322E20015FC5C /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 6369A27F1A9322E20015FC5C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 6369A28A1A9322E20015FC5C /* SampleTests.m in Sources */,
+ 63D886A71AE73797000580D7 /* RemoteTests.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 6369A2851A9322E20015FC5C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 6369A2691A9322E20015FC5C /* Sample */;
+ targetProxy = 6369A2841A9322E20015FC5C /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 6369A2771A9322E20015FC5C /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 6369A2781A9322E20015FC5C /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ 6369A27C1A9322E20015FC5C /* LaunchScreen.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 6369A27D1A9322E20015FC5C /* Base */,
+ );
+ name = LaunchScreen.xib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 6369A28B1A9322E20015FC5C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 6369A28C1A9322E20015FC5C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 6369A28E1A9322E20015FC5C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = AC29DD6FCDF962F519FEBB0D /* Pods.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = Sample/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 6369A28F1A9322E20015FC5C /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C68330F8D451CC6ACEABA09F /* Pods.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = Sample/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ 6369A2911A9322E20015FC5C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = AC29DD6FCDF962F519FEBB0D /* Pods.debug.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ );
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ INFOPLIST_FILE = SampleTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sample.app/Sample";
+ };
+ name = Debug;
+ };
+ 6369A2921A9322E20015FC5C /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C68330F8D451CC6ACEABA09F /* Pods.release.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ );
+ INFOPLIST_FILE = SampleTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sample.app/Sample";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 6369A2651A9322E20015FC5C /* Build configuration list for PBXProject "Sample" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 6369A28B1A9322E20015FC5C /* Debug */,
+ 6369A28C1A9322E20015FC5C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 6369A28D1A9322E20015FC5C /* Build configuration list for PBXNativeTarget "Sample" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 6369A28E1A9322E20015FC5C /* Debug */,
+ 6369A28F1A9322E20015FC5C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 6369A2901A9322E20015FC5C /* Build configuration list for PBXNativeTarget "SampleTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 6369A2911A9322E20015FC5C /* Debug */,
+ 6369A2921A9322E20015FC5C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 6369A2621A9322E20015FC5C /* Project object */;
+}
diff --git a/src/objective-c/examples/Sample/Sample/AppDelegate.h b/src/objective-c/examples/Sample/Sample/AppDelegate.h
index 867e62842a..b1857f28e0 100644
--- a/src/objective-c/examples/Sample/Sample/AppDelegate.h
+++ b/src/objective-c/examples/Sample/Sample/AppDelegate.h
@@ -37,6 +37,5 @@
@property (strong, nonatomic) UIWindow *window;
-
@end
diff --git a/src/objective-c/examples/Sample/Sample/AppDelegate.m b/src/objective-c/examples/Sample/Sample/AppDelegate.m
index 66fceffd85..12e1ad9d67 100644
--- a/src/objective-c/examples/Sample/Sample/AppDelegate.m
+++ b/src/objective-c/examples/Sample/Sample/AppDelegate.m
@@ -34,37 +34,12 @@
#import "AppDelegate.h"
@interface AppDelegate ()
-
@end
@implementation AppDelegate
-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- // Override point for customization after application launch.
return YES;
}
-- (void)applicationWillResignActive:(UIApplication *)application {
- // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
- // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
-}
-
-- (void)applicationDidEnterBackground:(UIApplication *)application {
- // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
-}
-
-- (void)applicationWillEnterForeground:(UIApplication *)application {
- // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
-}
-
-- (void)applicationDidBecomeActive:(UIApplication *)application {
- // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
-}
-
-- (void)applicationWillTerminate:(UIApplication *)application {
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
-}
-
@end
diff --git a/src/objective-c/examples/Sample/Sample/ViewController.h b/src/objective-c/examples/Sample/Sample/ViewController.h
index 38cd7f92b6..c0b4aca77e 100644
--- a/src/objective-c/examples/Sample/Sample/ViewController.h
+++ b/src/objective-c/examples/Sample/Sample/ViewController.h
@@ -34,7 +34,4 @@
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
-
-
@end
-
diff --git a/src/objective-c/examples/Sample/Sample/ViewController.m b/src/objective-c/examples/Sample/Sample/ViewController.m
index 839e181070..c7d8e0d145 100644
--- a/src/objective-c/examples/Sample/Sample/ViewController.m
+++ b/src/objective-c/examples/Sample/Sample/ViewController.m
@@ -37,29 +37,34 @@
#import <gRPC/GRPCMethodName.h>
#import <gRPC/GRXWriter+Immediate.h>
#import <gRPC/GRXWriteable.h>
+#import <RemoteTest/Messages.pb.h>
@interface ViewController ()
-
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
GRPCMethodName *method = [[GRPCMethodName alloc] initWithPackage:@"grpc.testing"
interface:@"TestService"
- method:@"EmptyCall"];
+ method:@"UnaryCall"];
- id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[NSData data]];
+ RMTSimpleRequest *request = [[[[[[RMTSimpleRequestBuilder alloc] init]
+ setResponseSize:100]
+ setFillUsername:YES]
+ setFillOauthScope:YES]
+ build];
+ id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[request data]];
- GRPCCall *call = [[GRPCCall alloc] initWithHost:@"grpc-test.sandbox.google.com:443"
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:@"grpc-test.sandbox.google.com"
method:method
requestsWriter:requestsWriter];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- NSLog(@"Received response: %@", value);
+ RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value];
+ NSLog(@"Received response:\n%@", response);
} completionHandler:^(NSError *errorOrNil) {
NSLog(@"Finished with error: %@", errorOrNil);
}];
@@ -67,9 +72,4 @@
[call startWithWriteable:responsesWriteable];
}
-- (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
-}
-
@end
diff --git a/src/objective-c/examples/Sample/SampleTests/RemoteTests.m b/src/objective-c/examples/Sample/SampleTests/RemoteTests.m
new file mode 100644
index 0000000000..6091aa9d31
--- /dev/null
+++ b/src/objective-c/examples/Sample/SampleTests/RemoteTests.m
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+
+#import <gRPC/GRPCCall.h>
+#import <gRPC/GRPCMethodName.h>
+#import <gRPC/GRXWriter+Immediate.h>
+#import <gRPC/GRXWriteable.h>
+#import <RemoteTest/Messages.pb.h>
+
+@interface RemoteTests : XCTestCase
+@end
+
+@implementation RemoteTests
+
+- (void)testConnectionToRemoteServer {
+ __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Server reachable."];
+
+ // This method isn't implemented by the remote server.
+ GRPCMethodName *method = [[GRPCMethodName alloc] initWithPackage:@"grpc.testing"
+ interface:@"TestService"
+ method:@"Nonexistent"];
+
+ id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[NSData data]];
+
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:@"grpc-test.sandbox.google.com"
+ method:method
+ requestsWriter:requestsWriter];
+
+ id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTFail(@"Received unexpected response: %@", value);
+ } completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNotNil(errorOrNil, @"Finished without error!");
+ // TODO(jcanizales): The server should return code 12 UNIMPLEMENTED, not 5 NOT FOUND.
+ XCTAssertEqual(errorOrNil.code, 5, @"Finished with unexpected error: %@", errorOrNil);
+ [expectation fulfill];
+ }];
+
+ [call startWithWriteable:responsesWriteable];
+
+ [self waitForExpectationsWithTimeout:2. handler:nil];
+}
+
+- (void)testEmptyRPC {
+ __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
+ __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
+
+ GRPCMethodName *method = [[GRPCMethodName alloc] initWithPackage:@"grpc.testing"
+ interface:@"TestService"
+ method:@"EmptyCall"];
+
+ id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[NSData data]];
+
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:@"grpc-test.sandbox.google.com"
+ method:method
+ requestsWriter:requestsWriter];
+
+ id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
+ [response fulfill];
+ } completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
+
+ [call startWithWriteable:responsesWriteable];
+
+ [self waitForExpectationsWithTimeout:2. handler:nil];
+}
+
+- (void)testSimpleProtoRPC {
+ __weak XCTestExpectation *response = [self expectationWithDescription:@"Response received."];
+ __weak XCTestExpectation *expectedResponse =
+ [self expectationWithDescription:@"Expected response."];
+ __weak XCTestExpectation *completion = [self expectationWithDescription:@"RPC completed."];
+
+ GRPCMethodName *method = [[GRPCMethodName alloc] initWithPackage:@"grpc.testing"
+ interface:@"TestService"
+ method:@"UnaryCall"];
+
+ RMTSimpleRequest *request = [[[[[[RMTSimpleRequestBuilder alloc] init]
+ setResponseSize:100]
+ setFillUsername:YES]
+ setFillOauthScope:YES]
+ build];
+ id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[request data]];
+
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:@"grpc-test.sandbox.google.com"
+ method:method
+ requestsWriter:requestsWriter];
+
+ id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+ XCTAssertNotNil(value, @"nil value received as response.");
+ [response fulfill];
+ XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
+ RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value];
+ // We expect empty strings, not nil:
+ XCTAssertNotNil(response.username, @"Response's username is nil.");
+ XCTAssertNotNil(response.oauthScope, @"Response's OAuth scope is nil.");
+ [expectedResponse fulfill];
+ } completionHandler:^(NSError *errorOrNil) {
+ XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+ [completion fulfill];
+ }];
+
+ [call startWithWriteable:responsesWriteable];
+
+ [self waitForExpectationsWithTimeout:2. handler:nil];
+}
+
+@end
diff --git a/src/objective-c/examples/Sample/SampleTests/SampleTests.m b/src/objective-c/examples/Sample/SampleTests/SampleTests.m
index ca5e302a17..6d6875c233 100644
--- a/src/objective-c/examples/Sample/SampleTests/SampleTests.m
+++ b/src/objective-c/examples/Sample/SampleTests/SampleTests.m
@@ -58,7 +58,7 @@
id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[NSData data]];
- GRPCCall *call = [[GRPCCall alloc] initWithHost:@"127.0.0.1:8980"
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:@"http://127.0.0.1:8980"
method:method
requestsWriter:requestsWriter];
@@ -85,7 +85,7 @@
id<GRXWriter> requestsWriter = [GRXWriter emptyWriter];
- GRPCCall *call = [[GRPCCall alloc] initWithHost:@"127.0.0.1:8980"
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:@"http://127.0.0.1:8980"
method:method
requestsWriter:requestsWriter];
@@ -116,7 +116,7 @@
RGDPoint *point = [[[[[RGDPointBuilder alloc] init] setLatitude:28E7] setLongitude:-15E7] build];
id<GRXWriter> requestsWriter = [GRXWriter writerWithValue:[point data]];
- GRPCCall *call = [[GRPCCall alloc] initWithHost:@"127.0.0.1:8980"
+ GRPCCall *call = [[GRPCCall alloc] initWithHost:@"http://127.0.0.1:8980"
method:method
requestsWriter:requestsWriter];
diff --git a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
index 9ec95375e9..f8ec1e7da8 100644
--- a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
+++ b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php
@@ -38,7 +38,6 @@ class GeneratedCodeWithCallbackTest extends AbstractGeneratedCodeTest {
self::$client = new math\MathClient(new Grpc\BaseStub(
getenv('GRPC_TEST_HOST'), ['update_metadata' =>
function($a_hash,
- $opts = array(),
$client = array()) {
$a_copy = $a_hash;
$a_copy['foo'] = ['bar'];
diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py
index e88b70969c..826c586a1e 100644
--- a/src/python/src/grpc/_adapter/_low_test.py
+++ b/src/python/src/grpc/_adapter/_low_test.py
@@ -43,7 +43,6 @@ _BYTE_SEQUENCE_SEQUENCE = tuple(
bytes(bytearray((row + column) % 256 for column in range(row)))
for row in range(_STREAM_LENGTH))
-
class LonelyClientTest(unittest.TestCase):
def testLonelyClient(self):
@@ -296,7 +295,6 @@ class EchoTest(unittest.TestCase):
def testManyManyByteEchoes(self):
self._perform_echo_test(_BYTE_SEQUENCE_SEQUENCE)
-
class CancellationTest(unittest.TestCase):
def setUp(self):
@@ -392,7 +390,8 @@ class CancellationTest(unittest.TestCase):
finish_event = self.client_completion_queue.get(_FUTURE)
self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind)
- self.assertEqual(_low.Status(_low.Code.CANCELLED, ''), finish_event.status)
+ self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'),
+ finish_event.status)
server_timeout_none_event = self.server_completion_queue.get(0)
self.assertIsNone(server_timeout_none_event)