regenerate C# protos
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 4764e10..b90243c 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -1,5 +1,5 @@
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: test/proto/benchmarks/control.proto
+// source: src/proto/grpc/testing/control.proto
 #pragma warning disable 1591, 0612, 3021
 #region Designer generated code
 
@@ -9,78 +9,80 @@
 using scg = global::System.Collections.Generic;
 namespace Grpc.Testing {
 
+  /// <summary>Holder for reflection information generated from src/proto/grpc/testing/control.proto</summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public static partial class Control {
+  public static partial class ControlReflection {
 
     #region Descriptor
+    /// <summary>File descriptor for src/proto/grpc/testing/control.proto</summary>
     public static pbr::FileDescriptor Descriptor {
       get { return descriptor; }
     }
     private static pbr::FileDescriptor descriptor;
 
-    static Control() {
+    static ControlReflection() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
-            "CiN0ZXN0L3Byb3RvL2JlbmNobWFya3MvY29udHJvbC5wcm90bxIMZ3JwYy50", 
-            "ZXN0aW5nGiR0ZXN0L3Byb3RvL2JlbmNobWFya3MvcGF5bG9hZHMucHJvdG8a", 
-            "IXRlc3QvcHJvdG8vYmVuY2htYXJrcy9zdGF0cy5wcm90byIlCg1Qb2lzc29u", 
-            "UGFyYW1zEhQKDG9mZmVyZWRfbG9hZBgBIAEoASJBCg1Vbmlmb3JtUGFyYW1z", 
-            "EhcKD2ludGVyYXJyaXZhbF9sbxgBIAEoARIXCg9pbnRlcmFycml2YWxfaGkY", 
-            "AiABKAEiKwoTRGV0ZXJtaW5pc3RpY1BhcmFtcxIUCgxvZmZlcmVkX2xvYWQY", 
-            "ASABKAEiOAoMUGFyZXRvUGFyYW1zEhkKEWludGVyYXJyaXZhbF9iYXNlGAEg", 
-            "ASgBEg0KBWFscGhhGAIgASgBIhIKEENsb3NlZExvb3BQYXJhbXMijgIKCkxv", 
-            "YWRQYXJhbXMSNQoLY2xvc2VkX2xvb3AYASABKAsyHi5ncnBjLnRlc3Rpbmcu", 
-            "Q2xvc2VkTG9vcFBhcmFtc0gAEi4KB3BvaXNzb24YAiABKAsyGy5ncnBjLnRl", 
-            "c3RpbmcuUG9pc3NvblBhcmFtc0gAEi4KB3VuaWZvcm0YAyABKAsyGy5ncnBj", 
-            "LnRlc3RpbmcuVW5pZm9ybVBhcmFtc0gAEjMKBmRldGVybRgEIAEoCzIhLmdy", 
-            "cGMudGVzdGluZy5EZXRlcm1pbmlzdGljUGFyYW1zSAASLAoGcGFyZXRvGAUg", 
-            "ASgLMhouZ3JwYy50ZXN0aW5nLlBhcmV0b1BhcmFtc0gAQgYKBGxvYWQiQwoO", 
-            "U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy", 
-            "X2hvc3Rfb3ZlcnJpZGUYAiABKAkirwMKDENsaWVudENvbmZpZxIWCg5zZXJ2", 
-            "ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdycGMu", 
-            "dGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEoCzIc", 
-            "LmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGluZ19y", 
-            "cGNzX3Blcl9jaGFubmVsGAQgASgFEhcKD2NsaWVudF9jaGFubmVscxgFIAEo", 
-            "BRIcChRhc3luY19jbGllbnRfdGhyZWFkcxgHIAEoBRInCghycGNfdHlwZRgI", 
-            "IAEoDjIVLmdycGMudGVzdGluZy5ScGNUeXBlEi0KC2xvYWRfcGFyYW1zGAog", 
-            "ASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9jb25m", 
-            "aWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBoaXN0", 
-            "b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3JhbVBh", 
-            "cmFtcyI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRl", 
-            "c3RpbmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJoCgpD", 
-            "bGllbnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVu", 
-            "dENvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFya0gA", 
-            "QgkKB2FyZ3R5cGUi9wEKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlwZRgB", 
-            "IAEoDjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5X3Bh", 
-            "cmFtcxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIMCgRo", 
-            "b3N0GAMgASgJEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVyX3RocmVh", 
-            "ZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2FkX2NvbmZp", 
-            "ZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnImgKClNlcnZl", 
-            "ckFyZ3MSKwoFc2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2VydmVyQ29u", 
-            "ZmlnSAASIgoEbWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoH", 
-            "YXJndHlwZSJVCgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBj", 
-            "LnRlc3RpbmcuU2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVjb3JlcxgD", 
-            "IAEoBSovCgpDbGllbnRUeXBlEg8KC1NZTkNfQ0xJRU5UEAASEAoMQVNZTkNf", 
-            "Q0xJRU5UEAEqLwoKU2VydmVyVHlwZRIPCgtTWU5DX1NFUlZFUhAAEhAKDEFT", 
-            "WU5DX1NFUlZFUhABKiMKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJFQU1J", 
-            "TkcQAWIGcHJvdG8z"));
-      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-          new pbr::FileDescriptor[] { global::Grpc.Testing.Payloads.Descriptor, global::Grpc.Testing.Stats.Descriptor, },
+            "CiRzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL2NvbnRyb2wucHJvdG8SDGdycGMu",
+            "dGVzdGluZxolc3JjL3Byb3RvL2dycGMvdGVzdGluZy9wYXlsb2Fkcy5wcm90",
+            "bxoic3JjL3Byb3RvL2dycGMvdGVzdGluZy9zdGF0cy5wcm90byIlCg1Qb2lz",
+            "c29uUGFyYW1zEhQKDG9mZmVyZWRfbG9hZBgBIAEoASJBCg1Vbmlmb3JtUGFy",
+            "YW1zEhcKD2ludGVyYXJyaXZhbF9sbxgBIAEoARIXCg9pbnRlcmFycml2YWxf",
+            "aGkYAiABKAEiKwoTRGV0ZXJtaW5pc3RpY1BhcmFtcxIUCgxvZmZlcmVkX2xv",
+            "YWQYASABKAEiOAoMUGFyZXRvUGFyYW1zEhkKEWludGVyYXJyaXZhbF9iYXNl",
+            "GAEgASgBEg0KBWFscGhhGAIgASgBIhIKEENsb3NlZExvb3BQYXJhbXMijgIK",
+            "CkxvYWRQYXJhbXMSNQoLY2xvc2VkX2xvb3AYASABKAsyHi5ncnBjLnRlc3Rp",
+            "bmcuQ2xvc2VkTG9vcFBhcmFtc0gAEi4KB3BvaXNzb24YAiABKAsyGy5ncnBj",
+            "LnRlc3RpbmcuUG9pc3NvblBhcmFtc0gAEi4KB3VuaWZvcm0YAyABKAsyGy5n",
+            "cnBjLnRlc3RpbmcuVW5pZm9ybVBhcmFtc0gAEjMKBmRldGVybRgEIAEoCzIh",
+            "LmdycGMudGVzdGluZy5EZXRlcm1pbmlzdGljUGFyYW1zSAASLAoGcGFyZXRv",
+            "GAUgASgLMhouZ3JwYy50ZXN0aW5nLlBhcmV0b1BhcmFtc0gAQgYKBGxvYWQi",
+            "QwoOU2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2Vy",
+            "dmVyX2hvc3Rfb3ZlcnJpZGUYAiABKAkirwMKDENsaWVudENvbmZpZxIWCg5z",
+            "ZXJ2ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdy",
+            "cGMudGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEo",
+            "CzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGlu",
+            "Z19ycGNzX3Blcl9jaGFubmVsGAQgASgFEhcKD2NsaWVudF9jaGFubmVscxgF",
+            "IAEoBRIcChRhc3luY19jbGllbnRfdGhyZWFkcxgHIAEoBRInCghycGNfdHlw",
+            "ZRgIIAEoDjIVLmdycGMudGVzdGluZy5ScGNUeXBlEi0KC2xvYWRfcGFyYW1z",
+            "GAogASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9j",
+            "b25maWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBo",
+            "aXN0b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3Jh",
+            "bVBhcmFtcyI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBj",
+            "LnRlc3RpbmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJo",
+            "CgpDbGllbnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNs",
+            "aWVudENvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFy",
+            "a0gAQgkKB2FyZ3R5cGUi9wEKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlw",
+            "ZRgBIAEoDjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5",
+            "X3BhcmFtcxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIM",
+            "CgRob3N0GAMgASgJEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVyX3Ro",
+            "cmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2FkX2Nv",
+            "bmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnImgKClNl",
+            "cnZlckFyZ3MSKwoFc2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2VydmVy",
+            "Q29uZmlnSAASIgoEbWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJrSABC",
+            "CQoHYXJndHlwZSJVCgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5n",
+            "cnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVjb3Jl",
+            "cxgDIAEoBSovCgpDbGllbnRUeXBlEg8KC1NZTkNfQ0xJRU5UEAASEAoMQVNZ",
+            "TkNfQ0xJRU5UEAEqLwoKU2VydmVyVHlwZRIPCgtTWU5DX1NFUlZFUhAAEhAK",
+            "DEFTWU5DX1NFUlZFUhABKiMKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJF",
+            "QU1JTkcQAWIGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
           new pbr::GeneratedCodeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedCodeInfo[] {
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.PoissonParams), new[]{ "OfferedLoad" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.UniformParams), new[]{ "InterarrivalLo", "InterarrivalHi" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.DeterministicParams), new[]{ "OfferedLoad" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ParetoParams), new[]{ "InterarrivalBase", "Alpha" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClosedLoopParams), null, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.LoadParams), new[]{ "ClosedLoop", "Poisson", "Uniform", "Determ", "Pareto" }, new[]{ "Load" }, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SecurityParams), new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientConfig), new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientStatus), new[]{ "Stats" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Mark), new[]{ "Reset" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientArgs), new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerConfig), new[]{ "ServerType", "SecurityParams", "Host", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerArgs), new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerStatus), new[]{ "Stats", "Port", "Cores" }, null, null, null)
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.PoissonParams), global::Grpc.Testing.PoissonParams.Parser, new[]{ "OfferedLoad" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.UniformParams), global::Grpc.Testing.UniformParams.Parser, new[]{ "InterarrivalLo", "InterarrivalHi" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.DeterministicParams), global::Grpc.Testing.DeterministicParams.Parser, new[]{ "OfferedLoad" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ParetoParams), global::Grpc.Testing.ParetoParams.Parser, new[]{ "InterarrivalBase", "Alpha" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClosedLoopParams), global::Grpc.Testing.ClosedLoopParams.Parser, null, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson", "Uniform", "Determ", "Pareto" }, new[]{ "Load" }, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerConfig), global::Grpc.Testing.ServerConfig.Parser, new[]{ "ServerType", "SecurityParams", "Host", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerArgs), global::Grpc.Testing.ServerArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerStatus), global::Grpc.Testing.ServerStatus.Parser, new[]{ "Stats", "Port", "Cores" }, null, null, null)
           }));
     }
     #endregion
@@ -105,13 +107,17 @@
   #endregion
 
   #region Messages
+  /// <summary>
+  ///  Parameters of poisson process distribution, which is a good representation
+  ///  of activity coming in from independent identical stationary sources.
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class PoissonParams : pb::IMessage<PoissonParams> {
     private static readonly pb::MessageParser<PoissonParams> _parser = new pb::MessageParser<PoissonParams>(() => new PoissonParams());
     public static pb::MessageParser<PoissonParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[0]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[0]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -132,8 +138,12 @@
       return new PoissonParams(this);
     }
 
+    /// <summary>Field number for the "offered_load" field.</summary>
     public const int OfferedLoadFieldNumber = 1;
     private double offeredLoad_;
+    /// <summary>
+    ///  The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
+    /// </summary>
     public double OfferedLoad {
       get { return offeredLoad_; }
       set {
@@ -163,7 +173,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -213,7 +223,7 @@
     public static pb::MessageParser<UniformParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[1]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[1]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -235,6 +245,7 @@
       return new UniformParams(this);
     }
 
+    /// <summary>Field number for the "interarrival_lo" field.</summary>
     public const int InterarrivalLoFieldNumber = 1;
     private double interarrivalLo_;
     public double InterarrivalLo {
@@ -244,6 +255,7 @@
       }
     }
 
+    /// <summary>Field number for the "interarrival_hi" field.</summary>
     public const int InterarrivalHiFieldNumber = 2;
     private double interarrivalHi_;
     public double InterarrivalHi {
@@ -277,7 +289,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -341,7 +353,7 @@
     public static pb::MessageParser<DeterministicParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[2]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[2]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -362,6 +374,7 @@
       return new DeterministicParams(this);
     }
 
+    /// <summary>Field number for the "offered_load" field.</summary>
     public const int OfferedLoadFieldNumber = 1;
     private double offeredLoad_;
     public double OfferedLoad {
@@ -393,7 +406,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -443,7 +456,7 @@
     public static pb::MessageParser<ParetoParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[3]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[3]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -465,6 +478,7 @@
       return new ParetoParams(this);
     }
 
+    /// <summary>Field number for the "interarrival_base" field.</summary>
     public const int InterarrivalBaseFieldNumber = 1;
     private double interarrivalBase_;
     public double InterarrivalBase {
@@ -474,6 +488,7 @@
       }
     }
 
+    /// <summary>Field number for the "alpha" field.</summary>
     public const int AlphaFieldNumber = 2;
     private double alpha_;
     public double Alpha {
@@ -507,7 +522,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -565,13 +580,17 @@
 
   }
 
+  /// <summary>
+  ///  Once an RPC finishes, immediately start a new one.
+  ///  No configuration parameters needed.
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ClosedLoopParams : pb::IMessage<ClosedLoopParams> {
     private static readonly pb::MessageParser<ClosedLoopParams> _parser = new pb::MessageParser<ClosedLoopParams>(() => new ClosedLoopParams());
     public static pb::MessageParser<ClosedLoopParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[4]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -611,7 +630,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -647,7 +666,7 @@
     public static pb::MessageParser<LoadParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[5]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -685,6 +704,7 @@
       return new LoadParams(this);
     }
 
+    /// <summary>Field number for the "closed_loop" field.</summary>
     public const int ClosedLoopFieldNumber = 1;
     public global::Grpc.Testing.ClosedLoopParams ClosedLoop {
       get { return loadCase_ == LoadOneofCase.ClosedLoop ? (global::Grpc.Testing.ClosedLoopParams) load_ : null; }
@@ -694,6 +714,7 @@
       }
     }
 
+    /// <summary>Field number for the "poisson" field.</summary>
     public const int PoissonFieldNumber = 2;
     public global::Grpc.Testing.PoissonParams Poisson {
       get { return loadCase_ == LoadOneofCase.Poisson ? (global::Grpc.Testing.PoissonParams) load_ : null; }
@@ -703,6 +724,7 @@
       }
     }
 
+    /// <summary>Field number for the "uniform" field.</summary>
     public const int UniformFieldNumber = 3;
     public global::Grpc.Testing.UniformParams Uniform {
       get { return loadCase_ == LoadOneofCase.Uniform ? (global::Grpc.Testing.UniformParams) load_ : null; }
@@ -712,6 +734,7 @@
       }
     }
 
+    /// <summary>Field number for the "determ" field.</summary>
     public const int DetermFieldNumber = 4;
     public global::Grpc.Testing.DeterministicParams Determ {
       get { return loadCase_ == LoadOneofCase.Determ ? (global::Grpc.Testing.DeterministicParams) load_ : null; }
@@ -721,6 +744,7 @@
       }
     }
 
+    /// <summary>Field number for the "pareto" field.</summary>
     public const int ParetoFieldNumber = 5;
     public global::Grpc.Testing.ParetoParams Pareto {
       get { return loadCase_ == LoadOneofCase.Pareto ? (global::Grpc.Testing.ParetoParams) load_ : null; }
@@ -731,6 +755,7 @@
     }
 
     private object load_;
+    /// <summary>Enum of possible cases for the "load" oneof.</summary>
     public enum LoadOneofCase {
       None = 0,
       ClosedLoop = 1,
@@ -765,6 +790,7 @@
       if (!object.Equals(Uniform, other.Uniform)) return false;
       if (!object.Equals(Determ, other.Determ)) return false;
       if (!object.Equals(Pareto, other.Pareto)) return false;
+      if (LoadCase != other.LoadCase) return false;
       return true;
     }
 
@@ -775,11 +801,12 @@
       if (loadCase_ == LoadOneofCase.Uniform) hash ^= Uniform.GetHashCode();
       if (loadCase_ == LoadOneofCase.Determ) hash ^= Determ.GetHashCode();
       if (loadCase_ == LoadOneofCase.Pareto) hash ^= Pareto.GetHashCode();
+      hash ^= (int) loadCase_;
       return hash;
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -907,13 +934,16 @@
 
   }
 
+  /// <summary>
+  ///  presence of SecurityParams implies use of TLS
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class SecurityParams : pb::IMessage<SecurityParams> {
     private static readonly pb::MessageParser<SecurityParams> _parser = new pb::MessageParser<SecurityParams>(() => new SecurityParams());
     public static pb::MessageParser<SecurityParams> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[6]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -935,6 +965,7 @@
       return new SecurityParams(this);
     }
 
+    /// <summary>Field number for the "use_test_ca" field.</summary>
     public const int UseTestCaFieldNumber = 1;
     private bool useTestCa_;
     public bool UseTestCa {
@@ -944,6 +975,7 @@
       }
     }
 
+    /// <summary>Field number for the "server_host_override" field.</summary>
     public const int ServerHostOverrideFieldNumber = 2;
     private string serverHostOverride_ = "";
     public string ServerHostOverride {
@@ -977,7 +1009,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -1041,7 +1073,7 @@
     public static pb::MessageParser<ClientConfig> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[7]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1071,14 +1103,19 @@
       return new ClientConfig(this);
     }
 
+    /// <summary>Field number for the "server_targets" field.</summary>
     public const int ServerTargetsFieldNumber = 1;
     private static readonly pb::FieldCodec<string> _repeated_serverTargets_codec
         = pb::FieldCodec.ForString(10);
     private readonly pbc::RepeatedField<string> serverTargets_ = new pbc::RepeatedField<string>();
+    /// <summary>
+    ///  List of targets to connect to. At least one target needs to be specified.
+    /// </summary>
     public pbc::RepeatedField<string> ServerTargets {
       get { return serverTargets_; }
     }
 
+    /// <summary>Field number for the "client_type" field.</summary>
     public const int ClientTypeFieldNumber = 2;
     private global::Grpc.Testing.ClientType clientType_ = global::Grpc.Testing.ClientType.SYNC_CLIENT;
     public global::Grpc.Testing.ClientType ClientType {
@@ -1088,6 +1125,7 @@
       }
     }
 
+    /// <summary>Field number for the "security_params" field.</summary>
     public const int SecurityParamsFieldNumber = 3;
     private global::Grpc.Testing.SecurityParams securityParams_;
     public global::Grpc.Testing.SecurityParams SecurityParams {
@@ -1097,8 +1135,13 @@
       }
     }
 
+    /// <summary>Field number for the "outstanding_rpcs_per_channel" field.</summary>
     public const int OutstandingRpcsPerChannelFieldNumber = 4;
     private int outstandingRpcsPerChannel_;
+    /// <summary>
+    ///  How many concurrent RPCs to start for each channel.
+    ///  For synchronous client, use a separate thread for each outstanding RPC.
+    /// </summary>
     public int OutstandingRpcsPerChannel {
       get { return outstandingRpcsPerChannel_; }
       set {
@@ -1106,8 +1149,13 @@
       }
     }
 
+    /// <summary>Field number for the "client_channels" field.</summary>
     public const int ClientChannelsFieldNumber = 5;
     private int clientChannels_;
+    /// <summary>
+    ///  Number of independent client channels to create.
+    ///  i-th channel will connect to server_target[i % server_targets.size()]
+    /// </summary>
     public int ClientChannels {
       get { return clientChannels_; }
       set {
@@ -1115,8 +1163,12 @@
       }
     }
 
+    /// <summary>Field number for the "async_client_threads" field.</summary>
     public const int AsyncClientThreadsFieldNumber = 7;
     private int asyncClientThreads_;
+    /// <summary>
+    ///  Only for async client. Number of threads to use to start/manage RPCs.
+    /// </summary>
     public int AsyncClientThreads {
       get { return asyncClientThreads_; }
       set {
@@ -1124,6 +1176,7 @@
       }
     }
 
+    /// <summary>Field number for the "rpc_type" field.</summary>
     public const int RpcTypeFieldNumber = 8;
     private global::Grpc.Testing.RpcType rpcType_ = global::Grpc.Testing.RpcType.UNARY;
     public global::Grpc.Testing.RpcType RpcType {
@@ -1133,8 +1186,12 @@
       }
     }
 
+    /// <summary>Field number for the "load_params" field.</summary>
     public const int LoadParamsFieldNumber = 10;
     private global::Grpc.Testing.LoadParams loadParams_;
+    /// <summary>
+    ///  The requested load for the entire client (aggregated over all the threads).
+    /// </summary>
     public global::Grpc.Testing.LoadParams LoadParams {
       get { return loadParams_; }
       set {
@@ -1142,6 +1199,7 @@
       }
     }
 
+    /// <summary>Field number for the "payload_config" field.</summary>
     public const int PayloadConfigFieldNumber = 11;
     private global::Grpc.Testing.PayloadConfig payloadConfig_;
     public global::Grpc.Testing.PayloadConfig PayloadConfig {
@@ -1151,6 +1209,7 @@
       }
     }
 
+    /// <summary>Field number for the "histogram_params" field.</summary>
     public const int HistogramParamsFieldNumber = 12;
     private global::Grpc.Testing.HistogramParams histogramParams_;
     public global::Grpc.Testing.HistogramParams HistogramParams {
@@ -1200,7 +1259,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -1393,7 +1452,7 @@
     public static pb::MessageParser<ClientStatus> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[8]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1414,6 +1473,7 @@
       return new ClientStatus(this);
     }
 
+    /// <summary>Field number for the "stats" field.</summary>
     public const int StatsFieldNumber = 1;
     private global::Grpc.Testing.ClientStats stats_;
     public global::Grpc.Testing.ClientStats Stats {
@@ -1445,7 +1505,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -1495,13 +1555,16 @@
 
   }
 
+  /// <summary>
+  ///  Request current stats
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Mark : pb::IMessage<Mark> {
     private static readonly pb::MessageParser<Mark> _parser = new pb::MessageParser<Mark>(() => new Mark());
     public static pb::MessageParser<Mark> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[9]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1522,8 +1585,12 @@
       return new Mark(this);
     }
 
+    /// <summary>Field number for the "reset" field.</summary>
     public const int ResetFieldNumber = 1;
     private bool reset_;
+    /// <summary>
+    ///  if true, the stats will be reset after taking their snapshot.
+    /// </summary>
     public bool Reset {
       get { return reset_; }
       set {
@@ -1553,7 +1620,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -1603,7 +1670,7 @@
     public static pb::MessageParser<ClientArgs> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[10]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1632,6 +1699,7 @@
       return new ClientArgs(this);
     }
 
+    /// <summary>Field number for the "setup" field.</summary>
     public const int SetupFieldNumber = 1;
     public global::Grpc.Testing.ClientConfig Setup {
       get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ClientConfig) argtype_ : null; }
@@ -1641,6 +1709,7 @@
       }
     }
 
+    /// <summary>Field number for the "mark" field.</summary>
     public const int MarkFieldNumber = 2;
     public global::Grpc.Testing.Mark Mark {
       get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; }
@@ -1651,6 +1720,7 @@
     }
 
     private object argtype_;
+    /// <summary>Enum of possible cases for the "argtype" oneof.</summary>
     public enum ArgtypeOneofCase {
       None = 0,
       Setup = 1,
@@ -1679,6 +1749,7 @@
       }
       if (!object.Equals(Setup, other.Setup)) return false;
       if (!object.Equals(Mark, other.Mark)) return false;
+      if (ArgtypeCase != other.ArgtypeCase) return false;
       return true;
     }
 
@@ -1686,11 +1757,12 @@
       int hash = 1;
       if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
       if (argtypeCase_ == ArgtypeOneofCase.Mark) hash ^= Mark.GetHashCode();
+      hash ^= (int) argtypeCase_;
       return hash;
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -1767,7 +1839,7 @@
     public static pb::MessageParser<ServerConfig> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[11]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1794,6 +1866,7 @@
       return new ServerConfig(this);
     }
 
+    /// <summary>Field number for the "server_type" field.</summary>
     public const int ServerTypeFieldNumber = 1;
     private global::Grpc.Testing.ServerType serverType_ = global::Grpc.Testing.ServerType.SYNC_SERVER;
     public global::Grpc.Testing.ServerType ServerType {
@@ -1803,6 +1876,7 @@
       }
     }
 
+    /// <summary>Field number for the "security_params" field.</summary>
     public const int SecurityParamsFieldNumber = 2;
     private global::Grpc.Testing.SecurityParams securityParams_;
     public global::Grpc.Testing.SecurityParams SecurityParams {
@@ -1812,8 +1886,12 @@
       }
     }
 
+    /// <summary>Field number for the "host" field.</summary>
     public const int HostFieldNumber = 3;
     private string host_ = "";
+    /// <summary>
+    ///  Host on which to listen.
+    /// </summary>
     public string Host {
       get { return host_; }
       set {
@@ -1821,8 +1899,12 @@
       }
     }
 
+    /// <summary>Field number for the "port" field.</summary>
     public const int PortFieldNumber = 4;
     private int port_;
+    /// <summary>
+    ///  Port on which to listen. Zero means pick unused port.
+    /// </summary>
     public int Port {
       get { return port_; }
       set {
@@ -1830,8 +1912,12 @@
       }
     }
 
+    /// <summary>Field number for the "async_server_threads" field.</summary>
     public const int AsyncServerThreadsFieldNumber = 7;
     private int asyncServerThreads_;
+    /// <summary>
+    ///  Only for async server. Number of threads used to serve the requests.
+    /// </summary>
     public int AsyncServerThreads {
       get { return asyncServerThreads_; }
       set {
@@ -1839,8 +1925,12 @@
       }
     }
 
+    /// <summary>Field number for the "core_limit" field.</summary>
     public const int CoreLimitFieldNumber = 8;
     private int coreLimit_;
+    /// <summary>
+    ///  restrict core usage, currently unused
+    /// </summary>
     public int CoreLimit {
       get { return coreLimit_; }
       set {
@@ -1848,6 +1938,7 @@
       }
     }
 
+    /// <summary>Field number for the "payload_config" field.</summary>
     public const int PayloadConfigFieldNumber = 9;
     private global::Grpc.Testing.PayloadConfig payloadConfig_;
     public global::Grpc.Testing.PayloadConfig PayloadConfig {
@@ -1891,7 +1982,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -2037,7 +2128,7 @@
     public static pb::MessageParser<ServerArgs> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[12]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2066,6 +2157,7 @@
       return new ServerArgs(this);
     }
 
+    /// <summary>Field number for the "setup" field.</summary>
     public const int SetupFieldNumber = 1;
     public global::Grpc.Testing.ServerConfig Setup {
       get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ServerConfig) argtype_ : null; }
@@ -2075,6 +2167,7 @@
       }
     }
 
+    /// <summary>Field number for the "mark" field.</summary>
     public const int MarkFieldNumber = 2;
     public global::Grpc.Testing.Mark Mark {
       get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; }
@@ -2085,6 +2178,7 @@
     }
 
     private object argtype_;
+    /// <summary>Enum of possible cases for the "argtype" oneof.</summary>
     public enum ArgtypeOneofCase {
       None = 0,
       Setup = 1,
@@ -2113,6 +2207,7 @@
       }
       if (!object.Equals(Setup, other.Setup)) return false;
       if (!object.Equals(Mark, other.Mark)) return false;
+      if (ArgtypeCase != other.ArgtypeCase) return false;
       return true;
     }
 
@@ -2120,11 +2215,12 @@
       int hash = 1;
       if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
       if (argtypeCase_ == ArgtypeOneofCase.Mark) hash ^= Mark.GetHashCode();
+      hash ^= (int) argtypeCase_;
       return hash;
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -2201,7 +2297,7 @@
     public static pb::MessageParser<ServerStatus> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[13]; }
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2224,6 +2320,7 @@
       return new ServerStatus(this);
     }
 
+    /// <summary>Field number for the "stats" field.</summary>
     public const int StatsFieldNumber = 1;
     private global::Grpc.Testing.ServerStats stats_;
     public global::Grpc.Testing.ServerStats Stats {
@@ -2233,8 +2330,12 @@
       }
     }
 
+    /// <summary>Field number for the "port" field.</summary>
     public const int PortFieldNumber = 2;
     private int port_;
+    /// <summary>
+    ///  the port bound by the server
+    /// </summary>
     public int Port {
       get { return port_; }
       set {
@@ -2242,8 +2343,12 @@
       }
     }
 
+    /// <summary>Field number for the "cores" field.</summary>
     public const int CoresFieldNumber = 3;
     private int cores_;
+    /// <summary>
+    ///  Number of cores on the server. See gpr_cpu_num_cores.
+    /// </summary>
     public int Cores {
       get { return cores_; }
       set {
@@ -2277,7 +2382,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {