diff --git a/services/src/generated/main/grpc/io/grpc/channelz/v1/ChannelzGrpc.java b/services/src/generated/main/grpc/io/grpc/channelz/v1/ChannelzGrpc.java
new file mode 100644
index 0000000..ab285d7
--- /dev/null
+++ b/services/src/generated/main/grpc/io/grpc/channelz/v1/ChannelzGrpc.java
@@ -0,0 +1,762 @@
+package io.grpc.channelz.v1;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+/**
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler",
+    comments = "Source: io/grpc/channelz.proto")
+public final class ChannelzGrpc {
+
+  private ChannelzGrpc() {}
+
+  public static final String SERVICE_NAME = "grpc.channelz.Channelz";
+
+  // Static method descriptors that strictly reflect the proto.
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetTopChannelsMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetTopChannelsRequest,
+      io.grpc.channelz.v1.GetTopChannelsResponse> METHOD_GET_TOP_CHANNELS = getGetTopChannelsMethodHelper();
+
+  private static volatile io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetTopChannelsRequest,
+      io.grpc.channelz.v1.GetTopChannelsResponse> getGetTopChannelsMethod;
+
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetTopChannelsRequest,
+      io.grpc.channelz.v1.GetTopChannelsResponse> getGetTopChannelsMethod() {
+    return getGetTopChannelsMethodHelper();
+  }
+
+  private static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetTopChannelsRequest,
+      io.grpc.channelz.v1.GetTopChannelsResponse> getGetTopChannelsMethodHelper() {
+    io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetTopChannelsRequest, io.grpc.channelz.v1.GetTopChannelsResponse> getGetTopChannelsMethod;
+    if ((getGetTopChannelsMethod = ChannelzGrpc.getGetTopChannelsMethod) == null) {
+      synchronized (ChannelzGrpc.class) {
+        if ((getGetTopChannelsMethod = ChannelzGrpc.getGetTopChannelsMethod) == null) {
+          ChannelzGrpc.getGetTopChannelsMethod = getGetTopChannelsMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.channelz.v1.GetTopChannelsRequest, io.grpc.channelz.v1.GetTopChannelsResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.channelz.Channelz", "GetTopChannels"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetTopChannelsRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetTopChannelsResponse.getDefaultInstance()))
+                  .setSchemaDescriptor(new ChannelzMethodDescriptorSupplier("GetTopChannels"))
+                  .build();
+          }
+        }
+     }
+     return getGetTopChannelsMethod;
+  }
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetServersMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServersRequest,
+      io.grpc.channelz.v1.GetServersResponse> METHOD_GET_SERVERS = getGetServersMethodHelper();
+
+  private static volatile io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServersRequest,
+      io.grpc.channelz.v1.GetServersResponse> getGetServersMethod;
+
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServersRequest,
+      io.grpc.channelz.v1.GetServersResponse> getGetServersMethod() {
+    return getGetServersMethodHelper();
+  }
+
+  private static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServersRequest,
+      io.grpc.channelz.v1.GetServersResponse> getGetServersMethodHelper() {
+    io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServersRequest, io.grpc.channelz.v1.GetServersResponse> getGetServersMethod;
+    if ((getGetServersMethod = ChannelzGrpc.getGetServersMethod) == null) {
+      synchronized (ChannelzGrpc.class) {
+        if ((getGetServersMethod = ChannelzGrpc.getGetServersMethod) == null) {
+          ChannelzGrpc.getGetServersMethod = getGetServersMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.channelz.v1.GetServersRequest, io.grpc.channelz.v1.GetServersResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.channelz.Channelz", "GetServers"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetServersRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetServersResponse.getDefaultInstance()))
+                  .setSchemaDescriptor(new ChannelzMethodDescriptorSupplier("GetServers"))
+                  .build();
+          }
+        }
+     }
+     return getGetServersMethod;
+  }
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetServerSocketsMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServerSocketsRequest,
+      io.grpc.channelz.v1.GetServerSocketsResponse> METHOD_GET_SERVER_SOCKETS = getGetServerSocketsMethodHelper();
+
+  private static volatile io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServerSocketsRequest,
+      io.grpc.channelz.v1.GetServerSocketsResponse> getGetServerSocketsMethod;
+
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServerSocketsRequest,
+      io.grpc.channelz.v1.GetServerSocketsResponse> getGetServerSocketsMethod() {
+    return getGetServerSocketsMethodHelper();
+  }
+
+  private static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServerSocketsRequest,
+      io.grpc.channelz.v1.GetServerSocketsResponse> getGetServerSocketsMethodHelper() {
+    io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetServerSocketsRequest, io.grpc.channelz.v1.GetServerSocketsResponse> getGetServerSocketsMethod;
+    if ((getGetServerSocketsMethod = ChannelzGrpc.getGetServerSocketsMethod) == null) {
+      synchronized (ChannelzGrpc.class) {
+        if ((getGetServerSocketsMethod = ChannelzGrpc.getGetServerSocketsMethod) == null) {
+          ChannelzGrpc.getGetServerSocketsMethod = getGetServerSocketsMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.channelz.v1.GetServerSocketsRequest, io.grpc.channelz.v1.GetServerSocketsResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.channelz.Channelz", "GetServerSockets"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetServerSocketsRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetServerSocketsResponse.getDefaultInstance()))
+                  .setSchemaDescriptor(new ChannelzMethodDescriptorSupplier("GetServerSockets"))
+                  .build();
+          }
+        }
+     }
+     return getGetServerSocketsMethod;
+  }
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetChannelMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetChannelRequest,
+      io.grpc.channelz.v1.GetChannelResponse> METHOD_GET_CHANNEL = getGetChannelMethodHelper();
+
+  private static volatile io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetChannelRequest,
+      io.grpc.channelz.v1.GetChannelResponse> getGetChannelMethod;
+
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetChannelRequest,
+      io.grpc.channelz.v1.GetChannelResponse> getGetChannelMethod() {
+    return getGetChannelMethodHelper();
+  }
+
+  private static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetChannelRequest,
+      io.grpc.channelz.v1.GetChannelResponse> getGetChannelMethodHelper() {
+    io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetChannelRequest, io.grpc.channelz.v1.GetChannelResponse> getGetChannelMethod;
+    if ((getGetChannelMethod = ChannelzGrpc.getGetChannelMethod) == null) {
+      synchronized (ChannelzGrpc.class) {
+        if ((getGetChannelMethod = ChannelzGrpc.getGetChannelMethod) == null) {
+          ChannelzGrpc.getGetChannelMethod = getGetChannelMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.channelz.v1.GetChannelRequest, io.grpc.channelz.v1.GetChannelResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.channelz.Channelz", "GetChannel"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetChannelRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetChannelResponse.getDefaultInstance()))
+                  .setSchemaDescriptor(new ChannelzMethodDescriptorSupplier("GetChannel"))
+                  .build();
+          }
+        }
+     }
+     return getGetChannelMethod;
+  }
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetSubchannelMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSubchannelRequest,
+      io.grpc.channelz.v1.GetSubchannelResponse> METHOD_GET_SUBCHANNEL = getGetSubchannelMethodHelper();
+
+  private static volatile io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSubchannelRequest,
+      io.grpc.channelz.v1.GetSubchannelResponse> getGetSubchannelMethod;
+
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSubchannelRequest,
+      io.grpc.channelz.v1.GetSubchannelResponse> getGetSubchannelMethod() {
+    return getGetSubchannelMethodHelper();
+  }
+
+  private static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSubchannelRequest,
+      io.grpc.channelz.v1.GetSubchannelResponse> getGetSubchannelMethodHelper() {
+    io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSubchannelRequest, io.grpc.channelz.v1.GetSubchannelResponse> getGetSubchannelMethod;
+    if ((getGetSubchannelMethod = ChannelzGrpc.getGetSubchannelMethod) == null) {
+      synchronized (ChannelzGrpc.class) {
+        if ((getGetSubchannelMethod = ChannelzGrpc.getGetSubchannelMethod) == null) {
+          ChannelzGrpc.getGetSubchannelMethod = getGetSubchannelMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.channelz.v1.GetSubchannelRequest, io.grpc.channelz.v1.GetSubchannelResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.channelz.Channelz", "GetSubchannel"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetSubchannelRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetSubchannelResponse.getDefaultInstance()))
+                  .setSchemaDescriptor(new ChannelzMethodDescriptorSupplier("GetSubchannel"))
+                  .build();
+          }
+        }
+     }
+     return getGetSubchannelMethod;
+  }
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  @java.lang.Deprecated // Use {@link #getGetSocketMethod()} instead. 
+  public static final io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSocketRequest,
+      io.grpc.channelz.v1.GetSocketResponse> METHOD_GET_SOCKET = getGetSocketMethodHelper();
+
+  private static volatile io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSocketRequest,
+      io.grpc.channelz.v1.GetSocketResponse> getGetSocketMethod;
+
+  @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901")
+  public static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSocketRequest,
+      io.grpc.channelz.v1.GetSocketResponse> getGetSocketMethod() {
+    return getGetSocketMethodHelper();
+  }
+
+  private static io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSocketRequest,
+      io.grpc.channelz.v1.GetSocketResponse> getGetSocketMethodHelper() {
+    io.grpc.MethodDescriptor<io.grpc.channelz.v1.GetSocketRequest, io.grpc.channelz.v1.GetSocketResponse> getGetSocketMethod;
+    if ((getGetSocketMethod = ChannelzGrpc.getGetSocketMethod) == null) {
+      synchronized (ChannelzGrpc.class) {
+        if ((getGetSocketMethod = ChannelzGrpc.getGetSocketMethod) == null) {
+          ChannelzGrpc.getGetSocketMethod = getGetSocketMethod = 
+              io.grpc.MethodDescriptor.<io.grpc.channelz.v1.GetSocketRequest, io.grpc.channelz.v1.GetSocketResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(
+                  "grpc.channelz.Channelz", "GetSocket"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetSocketRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  io.grpc.channelz.v1.GetSocketResponse.getDefaultInstance()))
+                  .setSchemaDescriptor(new ChannelzMethodDescriptorSupplier("GetSocket"))
+                  .build();
+          }
+        }
+     }
+     return getGetSocketMethod;
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static ChannelzStub newStub(io.grpc.Channel channel) {
+    return new ChannelzStub(channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static ChannelzBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    return new ChannelzBlockingStub(channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static ChannelzFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    return new ChannelzFutureStub(channel);
+  }
+
+  /**
+   */
+  public static abstract class ChannelzImplBase implements io.grpc.BindableService {
+
+    /**
+     * <pre>
+     * Gets all root channels (e.g. channels the application has directly
+     * created). This does not include subchannels nor non-top level channels.
+     * </pre>
+     */
+    public void getTopChannels(io.grpc.channelz.v1.GetTopChannelsRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetTopChannelsResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getGetTopChannelsMethodHelper(), responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Gets all servers that exist in the process.
+     * </pre>
+     */
+    public void getServers(io.grpc.channelz.v1.GetServersRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetServersResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getGetServersMethodHelper(), responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Gets all server sockets that exist in the process.
+     * </pre>
+     */
+    public void getServerSockets(io.grpc.channelz.v1.GetServerSocketsRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetServerSocketsResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getGetServerSocketsMethodHelper(), responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Channel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public void getChannel(io.grpc.channelz.v1.GetChannelRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetChannelResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getGetChannelMethodHelper(), responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Subchannel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public void getSubchannel(io.grpc.channelz.v1.GetSubchannelRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetSubchannelResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getGetSubchannelMethodHelper(), responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Socket or else a NOT_FOUND code.
+     * </pre>
+     */
+    public void getSocket(io.grpc.channelz.v1.GetSocketRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetSocketResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getGetSocketMethodHelper(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getGetTopChannelsMethodHelper(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.channelz.v1.GetTopChannelsRequest,
+                io.grpc.channelz.v1.GetTopChannelsResponse>(
+                  this, METHODID_GET_TOP_CHANNELS)))
+          .addMethod(
+            getGetServersMethodHelper(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.channelz.v1.GetServersRequest,
+                io.grpc.channelz.v1.GetServersResponse>(
+                  this, METHODID_GET_SERVERS)))
+          .addMethod(
+            getGetServerSocketsMethodHelper(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.channelz.v1.GetServerSocketsRequest,
+                io.grpc.channelz.v1.GetServerSocketsResponse>(
+                  this, METHODID_GET_SERVER_SOCKETS)))
+          .addMethod(
+            getGetChannelMethodHelper(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.channelz.v1.GetChannelRequest,
+                io.grpc.channelz.v1.GetChannelResponse>(
+                  this, METHODID_GET_CHANNEL)))
+          .addMethod(
+            getGetSubchannelMethodHelper(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.channelz.v1.GetSubchannelRequest,
+                io.grpc.channelz.v1.GetSubchannelResponse>(
+                  this, METHODID_GET_SUBCHANNEL)))
+          .addMethod(
+            getGetSocketMethodHelper(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                io.grpc.channelz.v1.GetSocketRequest,
+                io.grpc.channelz.v1.GetSocketResponse>(
+                  this, METHODID_GET_SOCKET)))
+          .build();
+    }
+  }
+
+  /**
+   */
+  public static final class ChannelzStub extends io.grpc.stub.AbstractStub<ChannelzStub> {
+    private ChannelzStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private ChannelzStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ChannelzStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new ChannelzStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * Gets all root channels (e.g. channels the application has directly
+     * created). This does not include subchannels nor non-top level channels.
+     * </pre>
+     */
+    public void getTopChannels(io.grpc.channelz.v1.GetTopChannelsRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetTopChannelsResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getGetTopChannelsMethodHelper(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Gets all servers that exist in the process.
+     * </pre>
+     */
+    public void getServers(io.grpc.channelz.v1.GetServersRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetServersResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getGetServersMethodHelper(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Gets all server sockets that exist in the process.
+     * </pre>
+     */
+    public void getServerSockets(io.grpc.channelz.v1.GetServerSocketsRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetServerSocketsResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getGetServerSocketsMethodHelper(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Channel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public void getChannel(io.grpc.channelz.v1.GetChannelRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetChannelResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getGetChannelMethodHelper(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Subchannel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public void getSubchannel(io.grpc.channelz.v1.GetSubchannelRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetSubchannelResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getGetSubchannelMethodHelper(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Socket or else a NOT_FOUND code.
+     * </pre>
+     */
+    public void getSocket(io.grpc.channelz.v1.GetSocketRequest request,
+        io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetSocketResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getGetSocketMethodHelper(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   */
+  public static final class ChannelzBlockingStub extends io.grpc.stub.AbstractStub<ChannelzBlockingStub> {
+    private ChannelzBlockingStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private ChannelzBlockingStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ChannelzBlockingStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new ChannelzBlockingStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * Gets all root channels (e.g. channels the application has directly
+     * created). This does not include subchannels nor non-top level channels.
+     * </pre>
+     */
+    public io.grpc.channelz.v1.GetTopChannelsResponse getTopChannels(io.grpc.channelz.v1.GetTopChannelsRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getGetTopChannelsMethodHelper(), getCallOptions(), request);
+    }
+
+    /**
+     * <pre>
+     * Gets all servers that exist in the process.
+     * </pre>
+     */
+    public io.grpc.channelz.v1.GetServersResponse getServers(io.grpc.channelz.v1.GetServersRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getGetServersMethodHelper(), getCallOptions(), request);
+    }
+
+    /**
+     * <pre>
+     * Gets all server sockets that exist in the process.
+     * </pre>
+     */
+    public io.grpc.channelz.v1.GetServerSocketsResponse getServerSockets(io.grpc.channelz.v1.GetServerSocketsRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getGetServerSocketsMethodHelper(), getCallOptions(), request);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Channel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public io.grpc.channelz.v1.GetChannelResponse getChannel(io.grpc.channelz.v1.GetChannelRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getGetChannelMethodHelper(), getCallOptions(), request);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Subchannel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public io.grpc.channelz.v1.GetSubchannelResponse getSubchannel(io.grpc.channelz.v1.GetSubchannelRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getGetSubchannelMethodHelper(), getCallOptions(), request);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Socket or else a NOT_FOUND code.
+     * </pre>
+     */
+    public io.grpc.channelz.v1.GetSocketResponse getSocket(io.grpc.channelz.v1.GetSocketRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getGetSocketMethodHelper(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   */
+  public static final class ChannelzFutureStub extends io.grpc.stub.AbstractStub<ChannelzFutureStub> {
+    private ChannelzFutureStub(io.grpc.Channel channel) {
+      super(channel);
+    }
+
+    private ChannelzFutureStub(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ChannelzFutureStub build(io.grpc.Channel channel,
+        io.grpc.CallOptions callOptions) {
+      return new ChannelzFutureStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * Gets all root channels (e.g. channels the application has directly
+     * created). This does not include subchannels nor non-top level channels.
+     * </pre>
+     */
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.channelz.v1.GetTopChannelsResponse> getTopChannels(
+        io.grpc.channelz.v1.GetTopChannelsRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getGetTopChannelsMethodHelper(), getCallOptions()), request);
+    }
+
+    /**
+     * <pre>
+     * Gets all servers that exist in the process.
+     * </pre>
+     */
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.channelz.v1.GetServersResponse> getServers(
+        io.grpc.channelz.v1.GetServersRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getGetServersMethodHelper(), getCallOptions()), request);
+    }
+
+    /**
+     * <pre>
+     * Gets all server sockets that exist in the process.
+     * </pre>
+     */
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.channelz.v1.GetServerSocketsResponse> getServerSockets(
+        io.grpc.channelz.v1.GetServerSocketsRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getGetServerSocketsMethodHelper(), getCallOptions()), request);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Channel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.channelz.v1.GetChannelResponse> getChannel(
+        io.grpc.channelz.v1.GetChannelRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getGetChannelMethodHelper(), getCallOptions()), request);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Subchannel, or else a NOT_FOUND code.
+     * </pre>
+     */
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.channelz.v1.GetSubchannelResponse> getSubchannel(
+        io.grpc.channelz.v1.GetSubchannelRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getGetSubchannelMethodHelper(), getCallOptions()), request);
+    }
+
+    /**
+     * <pre>
+     * Returns a single Socket or else a NOT_FOUND code.
+     * </pre>
+     */
+    public com.google.common.util.concurrent.ListenableFuture<io.grpc.channelz.v1.GetSocketResponse> getSocket(
+        io.grpc.channelz.v1.GetSocketRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getGetSocketMethodHelper(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_GET_TOP_CHANNELS = 0;
+  private static final int METHODID_GET_SERVERS = 1;
+  private static final int METHODID_GET_SERVER_SOCKETS = 2;
+  private static final int METHODID_GET_CHANNEL = 3;
+  private static final int METHODID_GET_SUBCHANNEL = 4;
+  private static final int METHODID_GET_SOCKET = 5;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final ChannelzImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(ChannelzImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_GET_TOP_CHANNELS:
+          serviceImpl.getTopChannels((io.grpc.channelz.v1.GetTopChannelsRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetTopChannelsResponse>) responseObserver);
+          break;
+        case METHODID_GET_SERVERS:
+          serviceImpl.getServers((io.grpc.channelz.v1.GetServersRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetServersResponse>) responseObserver);
+          break;
+        case METHODID_GET_SERVER_SOCKETS:
+          serviceImpl.getServerSockets((io.grpc.channelz.v1.GetServerSocketsRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetServerSocketsResponse>) responseObserver);
+          break;
+        case METHODID_GET_CHANNEL:
+          serviceImpl.getChannel((io.grpc.channelz.v1.GetChannelRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetChannelResponse>) responseObserver);
+          break;
+        case METHODID_GET_SUBCHANNEL:
+          serviceImpl.getSubchannel((io.grpc.channelz.v1.GetSubchannelRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetSubchannelResponse>) responseObserver);
+          break;
+        case METHODID_GET_SOCKET:
+          serviceImpl.getSocket((io.grpc.channelz.v1.GetSocketRequest) request,
+              (io.grpc.stub.StreamObserver<io.grpc.channelz.v1.GetSocketResponse>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static abstract class ChannelzBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
+    ChannelzBaseDescriptorSupplier() {}
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.getDescriptor();
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
+      return getFileDescriptor().findServiceByName("Channelz");
+    }
+  }
+
+  private static final class ChannelzFileDescriptorSupplier
+      extends ChannelzBaseDescriptorSupplier {
+    ChannelzFileDescriptorSupplier() {}
+  }
+
+  private static final class ChannelzMethodDescriptorSupplier
+      extends ChannelzBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
+    private final String methodName;
+
+    ChannelzMethodDescriptorSupplier(String methodName) {
+      this.methodName = methodName;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
+      return getServiceDescriptor().findMethodByName(methodName);
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (ChannelzGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new ChannelzFileDescriptorSupplier())
+              .addMethod(getGetTopChannelsMethodHelper())
+              .addMethod(getGetServersMethodHelper())
+              .addMethod(getGetServerSocketsMethodHelper())
+              .addMethod(getGetChannelMethodHelper())
+              .addMethod(getGetSubchannelMethodHelper())
+              .addMethod(getGetSocketMethodHelper())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/Address.java b/services/src/generated/main/java/io/grpc/channelz/v1/Address.java
new file mode 100644
index 0000000..74bb914
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/Address.java
@@ -0,0 +1,2987 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.Address}
+ */
+public  final class Address extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.Address)
+    AddressOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use Address.newBuilder() to construct.
+  private Address(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private Address() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private Address(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.Address.TcpIpAddress.Builder subBuilder = null;
+            if (addressCase_ == 1) {
+              subBuilder = ((io.grpc.channelz.v1.Address.TcpIpAddress) address_).toBuilder();
+            }
+            address_ =
+                input.readMessage(io.grpc.channelz.v1.Address.TcpIpAddress.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom((io.grpc.channelz.v1.Address.TcpIpAddress) address_);
+              address_ = subBuilder.buildPartial();
+            }
+            addressCase_ = 1;
+            break;
+          }
+          case 18: {
+            io.grpc.channelz.v1.Address.UdsAddress.Builder subBuilder = null;
+            if (addressCase_ == 2) {
+              subBuilder = ((io.grpc.channelz.v1.Address.UdsAddress) address_).toBuilder();
+            }
+            address_ =
+                input.readMessage(io.grpc.channelz.v1.Address.UdsAddress.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom((io.grpc.channelz.v1.Address.UdsAddress) address_);
+              address_ = subBuilder.buildPartial();
+            }
+            addressCase_ = 2;
+            break;
+          }
+          case 26: {
+            io.grpc.channelz.v1.Address.OtherAddress.Builder subBuilder = null;
+            if (addressCase_ == 3) {
+              subBuilder = ((io.grpc.channelz.v1.Address.OtherAddress) address_).toBuilder();
+            }
+            address_ =
+                input.readMessage(io.grpc.channelz.v1.Address.OtherAddress.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom((io.grpc.channelz.v1.Address.OtherAddress) address_);
+              address_ = subBuilder.buildPartial();
+            }
+            addressCase_ = 3;
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.Address.class, io.grpc.channelz.v1.Address.Builder.class);
+  }
+
+  public interface TcpIpAddressOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:grpc.channelz.Address.TcpIpAddress)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <pre>
+     * Either the IPv4 or IPv6 address in bytes.  Will either be 4 bytes or 16
+     * bytes in length.
+     * </pre>
+     *
+     * <code>bytes ip_address = 1;</code>
+     */
+    com.google.protobuf.ByteString getIpAddress();
+
+    /**
+     * <pre>
+     * 0-64k, or -1 if not appropriate.
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    int getPort();
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.Address.TcpIpAddress}
+   */
+  public  static final class TcpIpAddress extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:grpc.channelz.Address.TcpIpAddress)
+      TcpIpAddressOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use TcpIpAddress.newBuilder() to construct.
+    private TcpIpAddress(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private TcpIpAddress() {
+      ipAddress_ = com.google.protobuf.ByteString.EMPTY;
+      port_ = 0;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private TcpIpAddress(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownFieldProto3(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+
+              ipAddress_ = input.readBytes();
+              break;
+            }
+            case 16: {
+
+              port_ = input.readInt32();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_TcpIpAddress_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_TcpIpAddress_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Address.TcpIpAddress.class, io.grpc.channelz.v1.Address.TcpIpAddress.Builder.class);
+    }
+
+    public static final int IP_ADDRESS_FIELD_NUMBER = 1;
+    private com.google.protobuf.ByteString ipAddress_;
+    /**
+     * <pre>
+     * Either the IPv4 or IPv6 address in bytes.  Will either be 4 bytes or 16
+     * bytes in length.
+     * </pre>
+     *
+     * <code>bytes ip_address = 1;</code>
+     */
+    public com.google.protobuf.ByteString getIpAddress() {
+      return ipAddress_;
+    }
+
+    public static final int PORT_FIELD_NUMBER = 2;
+    private int port_;
+    /**
+     * <pre>
+     * 0-64k, or -1 if not appropriate.
+     * </pre>
+     *
+     * <code>int32 port = 2;</code>
+     */
+    public int getPort() {
+      return port_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!ipAddress_.isEmpty()) {
+        output.writeBytes(1, ipAddress_);
+      }
+      if (port_ != 0) {
+        output.writeInt32(2, port_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!ipAddress_.isEmpty()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, ipAddress_);
+      }
+      if (port_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeInt32Size(2, port_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.grpc.channelz.v1.Address.TcpIpAddress)) {
+        return super.equals(obj);
+      }
+      io.grpc.channelz.v1.Address.TcpIpAddress other = (io.grpc.channelz.v1.Address.TcpIpAddress) obj;
+
+      boolean result = true;
+      result = result && getIpAddress()
+          .equals(other.getIpAddress());
+      result = result && (getPort()
+          == other.getPort());
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + IP_ADDRESS_FIELD_NUMBER;
+      hash = (53 * hash) + getIpAddress().hashCode();
+      hash = (37 * hash) + PORT_FIELD_NUMBER;
+      hash = (53 * hash) + getPort();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.TcpIpAddress parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(io.grpc.channelz.v1.Address.TcpIpAddress prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code grpc.channelz.Address.TcpIpAddress}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:grpc.channelz.Address.TcpIpAddress)
+        io.grpc.channelz.v1.Address.TcpIpAddressOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_TcpIpAddress_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_TcpIpAddress_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                io.grpc.channelz.v1.Address.TcpIpAddress.class, io.grpc.channelz.v1.Address.TcpIpAddress.Builder.class);
+      }
+
+      // Construct using io.grpc.channelz.v1.Address.TcpIpAddress.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        ipAddress_ = com.google.protobuf.ByteString.EMPTY;
+
+        port_ = 0;
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_TcpIpAddress_descriptor;
+      }
+
+      public io.grpc.channelz.v1.Address.TcpIpAddress getDefaultInstanceForType() {
+        return io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance();
+      }
+
+      public io.grpc.channelz.v1.Address.TcpIpAddress build() {
+        io.grpc.channelz.v1.Address.TcpIpAddress result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public io.grpc.channelz.v1.Address.TcpIpAddress buildPartial() {
+        io.grpc.channelz.v1.Address.TcpIpAddress result = new io.grpc.channelz.v1.Address.TcpIpAddress(this);
+        result.ipAddress_ = ipAddress_;
+        result.port_ = port_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof io.grpc.channelz.v1.Address.TcpIpAddress) {
+          return mergeFrom((io.grpc.channelz.v1.Address.TcpIpAddress)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(io.grpc.channelz.v1.Address.TcpIpAddress other) {
+        if (other == io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance()) return this;
+        if (other.getIpAddress() != com.google.protobuf.ByteString.EMPTY) {
+          setIpAddress(other.getIpAddress());
+        }
+        if (other.getPort() != 0) {
+          setPort(other.getPort());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        io.grpc.channelz.v1.Address.TcpIpAddress parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (io.grpc.channelz.v1.Address.TcpIpAddress) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private com.google.protobuf.ByteString ipAddress_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <pre>
+       * Either the IPv4 or IPv6 address in bytes.  Will either be 4 bytes or 16
+       * bytes in length.
+       * </pre>
+       *
+       * <code>bytes ip_address = 1;</code>
+       */
+      public com.google.protobuf.ByteString getIpAddress() {
+        return ipAddress_;
+      }
+      /**
+       * <pre>
+       * Either the IPv4 or IPv6 address in bytes.  Will either be 4 bytes or 16
+       * bytes in length.
+       * </pre>
+       *
+       * <code>bytes ip_address = 1;</code>
+       */
+      public Builder setIpAddress(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        ipAddress_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * Either the IPv4 or IPv6 address in bytes.  Will either be 4 bytes or 16
+       * bytes in length.
+       * </pre>
+       *
+       * <code>bytes ip_address = 1;</code>
+       */
+      public Builder clearIpAddress() {
+        
+        ipAddress_ = getDefaultInstance().getIpAddress();
+        onChanged();
+        return this;
+      }
+
+      private int port_ ;
+      /**
+       * <pre>
+       * 0-64k, or -1 if not appropriate.
+       * </pre>
+       *
+       * <code>int32 port = 2;</code>
+       */
+      public int getPort() {
+        return port_;
+      }
+      /**
+       * <pre>
+       * 0-64k, or -1 if not appropriate.
+       * </pre>
+       *
+       * <code>int32 port = 2;</code>
+       */
+      public Builder setPort(int value) {
+        
+        port_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * 0-64k, or -1 if not appropriate.
+       * </pre>
+       *
+       * <code>int32 port = 2;</code>
+       */
+      public Builder clearPort() {
+        
+        port_ = 0;
+        onChanged();
+        return this;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFieldsProto3(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:grpc.channelz.Address.TcpIpAddress)
+    }
+
+    // @@protoc_insertion_point(class_scope:grpc.channelz.Address.TcpIpAddress)
+    private static final io.grpc.channelz.v1.Address.TcpIpAddress DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new io.grpc.channelz.v1.Address.TcpIpAddress();
+    }
+
+    public static io.grpc.channelz.v1.Address.TcpIpAddress getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<TcpIpAddress>
+        PARSER = new com.google.protobuf.AbstractParser<TcpIpAddress>() {
+      public TcpIpAddress parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new TcpIpAddress(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<TcpIpAddress> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<TcpIpAddress> getParserForType() {
+      return PARSER;
+    }
+
+    public io.grpc.channelz.v1.Address.TcpIpAddress getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface UdsAddressOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:grpc.channelz.Address.UdsAddress)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>string filename = 1;</code>
+     */
+    java.lang.String getFilename();
+    /**
+     * <code>string filename = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getFilenameBytes();
+  }
+  /**
+   * <pre>
+   * A Unix Domain Socket address.
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.Address.UdsAddress}
+   */
+  public  static final class UdsAddress extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:grpc.channelz.Address.UdsAddress)
+      UdsAddressOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use UdsAddress.newBuilder() to construct.
+    private UdsAddress(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private UdsAddress() {
+      filename_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private UdsAddress(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownFieldProto3(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              filename_ = s;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_UdsAddress_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_UdsAddress_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Address.UdsAddress.class, io.grpc.channelz.v1.Address.UdsAddress.Builder.class);
+    }
+
+    public static final int FILENAME_FIELD_NUMBER = 1;
+    private volatile java.lang.Object filename_;
+    /**
+     * <code>string filename = 1;</code>
+     */
+    public java.lang.String getFilename() {
+      java.lang.Object ref = filename_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        filename_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string filename = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getFilenameBytes() {
+      java.lang.Object ref = filename_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        filename_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!getFilenameBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, filename_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getFilenameBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, filename_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.grpc.channelz.v1.Address.UdsAddress)) {
+        return super.equals(obj);
+      }
+      io.grpc.channelz.v1.Address.UdsAddress other = (io.grpc.channelz.v1.Address.UdsAddress) obj;
+
+      boolean result = true;
+      result = result && getFilename()
+          .equals(other.getFilename());
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + FILENAME_FIELD_NUMBER;
+      hash = (53 * hash) + getFilename().hashCode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.UdsAddress parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(io.grpc.channelz.v1.Address.UdsAddress prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * A Unix Domain Socket address.
+     * </pre>
+     *
+     * Protobuf type {@code grpc.channelz.Address.UdsAddress}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:grpc.channelz.Address.UdsAddress)
+        io.grpc.channelz.v1.Address.UdsAddressOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_UdsAddress_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_UdsAddress_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                io.grpc.channelz.v1.Address.UdsAddress.class, io.grpc.channelz.v1.Address.UdsAddress.Builder.class);
+      }
+
+      // Construct using io.grpc.channelz.v1.Address.UdsAddress.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        filename_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_UdsAddress_descriptor;
+      }
+
+      public io.grpc.channelz.v1.Address.UdsAddress getDefaultInstanceForType() {
+        return io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance();
+      }
+
+      public io.grpc.channelz.v1.Address.UdsAddress build() {
+        io.grpc.channelz.v1.Address.UdsAddress result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public io.grpc.channelz.v1.Address.UdsAddress buildPartial() {
+        io.grpc.channelz.v1.Address.UdsAddress result = new io.grpc.channelz.v1.Address.UdsAddress(this);
+        result.filename_ = filename_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof io.grpc.channelz.v1.Address.UdsAddress) {
+          return mergeFrom((io.grpc.channelz.v1.Address.UdsAddress)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(io.grpc.channelz.v1.Address.UdsAddress other) {
+        if (other == io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance()) return this;
+        if (!other.getFilename().isEmpty()) {
+          filename_ = other.filename_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        io.grpc.channelz.v1.Address.UdsAddress parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (io.grpc.channelz.v1.Address.UdsAddress) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object filename_ = "";
+      /**
+       * <code>string filename = 1;</code>
+       */
+      public java.lang.String getFilename() {
+        java.lang.Object ref = filename_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          filename_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string filename = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getFilenameBytes() {
+        java.lang.Object ref = filename_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          filename_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string filename = 1;</code>
+       */
+      public Builder setFilename(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        filename_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string filename = 1;</code>
+       */
+      public Builder clearFilename() {
+        
+        filename_ = getDefaultInstance().getFilename();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string filename = 1;</code>
+       */
+      public Builder setFilenameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        filename_ = value;
+        onChanged();
+        return this;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFieldsProto3(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:grpc.channelz.Address.UdsAddress)
+    }
+
+    // @@protoc_insertion_point(class_scope:grpc.channelz.Address.UdsAddress)
+    private static final io.grpc.channelz.v1.Address.UdsAddress DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new io.grpc.channelz.v1.Address.UdsAddress();
+    }
+
+    public static io.grpc.channelz.v1.Address.UdsAddress getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<UdsAddress>
+        PARSER = new com.google.protobuf.AbstractParser<UdsAddress>() {
+      public UdsAddress parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new UdsAddress(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<UdsAddress> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<UdsAddress> getParserForType() {
+      return PARSER;
+    }
+
+    public io.grpc.channelz.v1.Address.UdsAddress getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface OtherAddressOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:grpc.channelz.Address.OtherAddress)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    java.lang.String getName();
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getNameBytes();
+
+    /**
+     * <pre>
+     * The actual address message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    boolean hasValue();
+    /**
+     * <pre>
+     * The actual address message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    com.google.protobuf.Any getValue();
+    /**
+     * <pre>
+     * The actual address message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    com.google.protobuf.AnyOrBuilder getValueOrBuilder();
+  }
+  /**
+   * <pre>
+   * An address type not included above.
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.Address.OtherAddress}
+   */
+  public  static final class OtherAddress extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:grpc.channelz.Address.OtherAddress)
+      OtherAddressOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use OtherAddress.newBuilder() to construct.
+    private OtherAddress(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private OtherAddress() {
+      name_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private OtherAddress(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownFieldProto3(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              name_ = s;
+              break;
+            }
+            case 18: {
+              com.google.protobuf.Any.Builder subBuilder = null;
+              if (value_ != null) {
+                subBuilder = value_.toBuilder();
+              }
+              value_ = input.readMessage(com.google.protobuf.Any.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(value_);
+                value_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_OtherAddress_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_OtherAddress_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Address.OtherAddress.class, io.grpc.channelz.v1.Address.OtherAddress.Builder.class);
+    }
+
+    public static final int NAME_FIELD_NUMBER = 1;
+    private volatile java.lang.Object name_;
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      }
+    }
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int VALUE_FIELD_NUMBER = 2;
+    private com.google.protobuf.Any value_;
+    /**
+     * <pre>
+     * The actual address message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    public boolean hasValue() {
+      return value_ != null;
+    }
+    /**
+     * <pre>
+     * The actual address message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    public com.google.protobuf.Any getValue() {
+      return value_ == null ? com.google.protobuf.Any.getDefaultInstance() : value_;
+    }
+    /**
+     * <pre>
+     * The actual address message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    public com.google.protobuf.AnyOrBuilder getValueOrBuilder() {
+      return getValue();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!getNameBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
+      }
+      if (value_ != null) {
+        output.writeMessage(2, getValue());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getNameBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
+      }
+      if (value_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getValue());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.grpc.channelz.v1.Address.OtherAddress)) {
+        return super.equals(obj);
+      }
+      io.grpc.channelz.v1.Address.OtherAddress other = (io.grpc.channelz.v1.Address.OtherAddress) obj;
+
+      boolean result = true;
+      result = result && getName()
+          .equals(other.getName());
+      result = result && (hasValue() == other.hasValue());
+      if (hasValue()) {
+        result = result && getValue()
+            .equals(other.getValue());
+      }
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + NAME_FIELD_NUMBER;
+      hash = (53 * hash) + getName().hashCode();
+      if (hasValue()) {
+        hash = (37 * hash) + VALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getValue().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Address.OtherAddress parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(io.grpc.channelz.v1.Address.OtherAddress prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * An address type not included above.
+     * </pre>
+     *
+     * Protobuf type {@code grpc.channelz.Address.OtherAddress}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:grpc.channelz.Address.OtherAddress)
+        io.grpc.channelz.v1.Address.OtherAddressOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_OtherAddress_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_OtherAddress_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                io.grpc.channelz.v1.Address.OtherAddress.class, io.grpc.channelz.v1.Address.OtherAddress.Builder.class);
+      }
+
+      // Construct using io.grpc.channelz.v1.Address.OtherAddress.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        name_ = "";
+
+        if (valueBuilder_ == null) {
+          value_ = null;
+        } else {
+          value_ = null;
+          valueBuilder_ = null;
+        }
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_OtherAddress_descriptor;
+      }
+
+      public io.grpc.channelz.v1.Address.OtherAddress getDefaultInstanceForType() {
+        return io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance();
+      }
+
+      public io.grpc.channelz.v1.Address.OtherAddress build() {
+        io.grpc.channelz.v1.Address.OtherAddress result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public io.grpc.channelz.v1.Address.OtherAddress buildPartial() {
+        io.grpc.channelz.v1.Address.OtherAddress result = new io.grpc.channelz.v1.Address.OtherAddress(this);
+        result.name_ = name_;
+        if (valueBuilder_ == null) {
+          result.value_ = value_;
+        } else {
+          result.value_ = valueBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof io.grpc.channelz.v1.Address.OtherAddress) {
+          return mergeFrom((io.grpc.channelz.v1.Address.OtherAddress)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(io.grpc.channelz.v1.Address.OtherAddress other) {
+        if (other == io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance()) return this;
+        if (!other.getName().isEmpty()) {
+          name_ = other.name_;
+          onChanged();
+        }
+        if (other.hasValue()) {
+          mergeValue(other.getValue());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        io.grpc.channelz.v1.Address.OtherAddress parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (io.grpc.channelz.v1.Address.OtherAddress) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object name_ = "";
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public java.lang.String getName() {
+        java.lang.Object ref = name_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          name_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getNameBytes() {
+        java.lang.Object ref = name_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          name_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public Builder setName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        name_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public Builder clearName() {
+        
+        name_ = getDefaultInstance().getName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public Builder setNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        name_ = value;
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.Any value_ = null;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> valueBuilder_;
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public boolean hasValue() {
+        return valueBuilder_ != null || value_ != null;
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public com.google.protobuf.Any getValue() {
+        if (valueBuilder_ == null) {
+          return value_ == null ? com.google.protobuf.Any.getDefaultInstance() : value_;
+        } else {
+          return valueBuilder_.getMessage();
+        }
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder setValue(com.google.protobuf.Any value) {
+        if (valueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          value_ = value;
+          onChanged();
+        } else {
+          valueBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder setValue(
+          com.google.protobuf.Any.Builder builderForValue) {
+        if (valueBuilder_ == null) {
+          value_ = builderForValue.build();
+          onChanged();
+        } else {
+          valueBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder mergeValue(com.google.protobuf.Any value) {
+        if (valueBuilder_ == null) {
+          if (value_ != null) {
+            value_ =
+              com.google.protobuf.Any.newBuilder(value_).mergeFrom(value).buildPartial();
+          } else {
+            value_ = value;
+          }
+          onChanged();
+        } else {
+          valueBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder clearValue() {
+        if (valueBuilder_ == null) {
+          value_ = null;
+          onChanged();
+        } else {
+          value_ = null;
+          valueBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public com.google.protobuf.Any.Builder getValueBuilder() {
+        
+        onChanged();
+        return getValueFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public com.google.protobuf.AnyOrBuilder getValueOrBuilder() {
+        if (valueBuilder_ != null) {
+          return valueBuilder_.getMessageOrBuilder();
+        } else {
+          return value_ == null ?
+              com.google.protobuf.Any.getDefaultInstance() : value_;
+        }
+      }
+      /**
+       * <pre>
+       * The actual address message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> 
+          getValueFieldBuilder() {
+        if (valueBuilder_ == null) {
+          valueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder>(
+                  getValue(),
+                  getParentForChildren(),
+                  isClean());
+          value_ = null;
+        }
+        return valueBuilder_;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFieldsProto3(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:grpc.channelz.Address.OtherAddress)
+    }
+
+    // @@protoc_insertion_point(class_scope:grpc.channelz.Address.OtherAddress)
+    private static final io.grpc.channelz.v1.Address.OtherAddress DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new io.grpc.channelz.v1.Address.OtherAddress();
+    }
+
+    public static io.grpc.channelz.v1.Address.OtherAddress getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<OtherAddress>
+        PARSER = new com.google.protobuf.AbstractParser<OtherAddress>() {
+      public OtherAddress parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new OtherAddress(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<OtherAddress> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<OtherAddress> getParserForType() {
+      return PARSER;
+    }
+
+    public io.grpc.channelz.v1.Address.OtherAddress getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private int addressCase_ = 0;
+  private java.lang.Object address_;
+  public enum AddressCase
+      implements com.google.protobuf.Internal.EnumLite {
+    TCPIP_ADDRESS(1),
+    UDS_ADDRESS(2),
+    OTHER_ADDRESS(3),
+    ADDRESS_NOT_SET(0);
+    private final int value;
+    private AddressCase(int value) {
+      this.value = value;
+    }
+    /**
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static AddressCase valueOf(int value) {
+      return forNumber(value);
+    }
+
+    public static AddressCase forNumber(int value) {
+      switch (value) {
+        case 1: return TCPIP_ADDRESS;
+        case 2: return UDS_ADDRESS;
+        case 3: return OTHER_ADDRESS;
+        case 0: return ADDRESS_NOT_SET;
+        default: return null;
+      }
+    }
+    public int getNumber() {
+      return this.value;
+    }
+  };
+
+  public AddressCase
+  getAddressCase() {
+    return AddressCase.forNumber(
+        addressCase_);
+  }
+
+  public static final int TCPIP_ADDRESS_FIELD_NUMBER = 1;
+  /**
+   * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+   */
+  public boolean hasTcpipAddress() {
+    return addressCase_ == 1;
+  }
+  /**
+   * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+   */
+  public io.grpc.channelz.v1.Address.TcpIpAddress getTcpipAddress() {
+    if (addressCase_ == 1) {
+       return (io.grpc.channelz.v1.Address.TcpIpAddress) address_;
+    }
+    return io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance();
+  }
+  /**
+   * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+   */
+  public io.grpc.channelz.v1.Address.TcpIpAddressOrBuilder getTcpipAddressOrBuilder() {
+    if (addressCase_ == 1) {
+       return (io.grpc.channelz.v1.Address.TcpIpAddress) address_;
+    }
+    return io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance();
+  }
+
+  public static final int UDS_ADDRESS_FIELD_NUMBER = 2;
+  /**
+   * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+   */
+  public boolean hasUdsAddress() {
+    return addressCase_ == 2;
+  }
+  /**
+   * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+   */
+  public io.grpc.channelz.v1.Address.UdsAddress getUdsAddress() {
+    if (addressCase_ == 2) {
+       return (io.grpc.channelz.v1.Address.UdsAddress) address_;
+    }
+    return io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance();
+  }
+  /**
+   * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+   */
+  public io.grpc.channelz.v1.Address.UdsAddressOrBuilder getUdsAddressOrBuilder() {
+    if (addressCase_ == 2) {
+       return (io.grpc.channelz.v1.Address.UdsAddress) address_;
+    }
+    return io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance();
+  }
+
+  public static final int OTHER_ADDRESS_FIELD_NUMBER = 3;
+  /**
+   * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+   */
+  public boolean hasOtherAddress() {
+    return addressCase_ == 3;
+  }
+  /**
+   * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+   */
+  public io.grpc.channelz.v1.Address.OtherAddress getOtherAddress() {
+    if (addressCase_ == 3) {
+       return (io.grpc.channelz.v1.Address.OtherAddress) address_;
+    }
+    return io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance();
+  }
+  /**
+   * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+   */
+  public io.grpc.channelz.v1.Address.OtherAddressOrBuilder getOtherAddressOrBuilder() {
+    if (addressCase_ == 3) {
+       return (io.grpc.channelz.v1.Address.OtherAddress) address_;
+    }
+    return io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (addressCase_ == 1) {
+      output.writeMessage(1, (io.grpc.channelz.v1.Address.TcpIpAddress) address_);
+    }
+    if (addressCase_ == 2) {
+      output.writeMessage(2, (io.grpc.channelz.v1.Address.UdsAddress) address_);
+    }
+    if (addressCase_ == 3) {
+      output.writeMessage(3, (io.grpc.channelz.v1.Address.OtherAddress) address_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (addressCase_ == 1) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, (io.grpc.channelz.v1.Address.TcpIpAddress) address_);
+    }
+    if (addressCase_ == 2) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, (io.grpc.channelz.v1.Address.UdsAddress) address_);
+    }
+    if (addressCase_ == 3) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, (io.grpc.channelz.v1.Address.OtherAddress) address_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.Address)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.Address other = (io.grpc.channelz.v1.Address) obj;
+
+    boolean result = true;
+    result = result && getAddressCase().equals(
+        other.getAddressCase());
+    if (!result) return false;
+    switch (addressCase_) {
+      case 1:
+        result = result && getTcpipAddress()
+            .equals(other.getTcpipAddress());
+        break;
+      case 2:
+        result = result && getUdsAddress()
+            .equals(other.getUdsAddress());
+        break;
+      case 3:
+        result = result && getOtherAddress()
+            .equals(other.getOtherAddress());
+        break;
+      case 0:
+      default:
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    switch (addressCase_) {
+      case 1:
+        hash = (37 * hash) + TCPIP_ADDRESS_FIELD_NUMBER;
+        hash = (53 * hash) + getTcpipAddress().hashCode();
+        break;
+      case 2:
+        hash = (37 * hash) + UDS_ADDRESS_FIELD_NUMBER;
+        hash = (53 * hash) + getUdsAddress().hashCode();
+        break;
+      case 3:
+        hash = (37 * hash) + OTHER_ADDRESS_FIELD_NUMBER;
+        hash = (53 * hash) + getOtherAddress().hashCode();
+        break;
+      case 0:
+      default:
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.Address parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Address parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Address parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Address parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.Address prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.Address}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.Address)
+      io.grpc.channelz.v1.AddressOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Address.class, io.grpc.channelz.v1.Address.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.Address.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      addressCase_ = 0;
+      address_ = null;
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Address_descriptor;
+    }
+
+    public io.grpc.channelz.v1.Address getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.Address.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.Address build() {
+      io.grpc.channelz.v1.Address result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.Address buildPartial() {
+      io.grpc.channelz.v1.Address result = new io.grpc.channelz.v1.Address(this);
+      if (addressCase_ == 1) {
+        if (tcpipAddressBuilder_ == null) {
+          result.address_ = address_;
+        } else {
+          result.address_ = tcpipAddressBuilder_.build();
+        }
+      }
+      if (addressCase_ == 2) {
+        if (udsAddressBuilder_ == null) {
+          result.address_ = address_;
+        } else {
+          result.address_ = udsAddressBuilder_.build();
+        }
+      }
+      if (addressCase_ == 3) {
+        if (otherAddressBuilder_ == null) {
+          result.address_ = address_;
+        } else {
+          result.address_ = otherAddressBuilder_.build();
+        }
+      }
+      result.addressCase_ = addressCase_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.Address) {
+        return mergeFrom((io.grpc.channelz.v1.Address)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.Address other) {
+      if (other == io.grpc.channelz.v1.Address.getDefaultInstance()) return this;
+      switch (other.getAddressCase()) {
+        case TCPIP_ADDRESS: {
+          mergeTcpipAddress(other.getTcpipAddress());
+          break;
+        }
+        case UDS_ADDRESS: {
+          mergeUdsAddress(other.getUdsAddress());
+          break;
+        }
+        case OTHER_ADDRESS: {
+          mergeOtherAddress(other.getOtherAddress());
+          break;
+        }
+        case ADDRESS_NOT_SET: {
+          break;
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.Address parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.Address) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int addressCase_ = 0;
+    private java.lang.Object address_;
+    public AddressCase
+        getAddressCase() {
+      return AddressCase.forNumber(
+          addressCase_);
+    }
+
+    public Builder clearAddress() {
+      addressCase_ = 0;
+      address_ = null;
+      onChanged();
+      return this;
+    }
+
+
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address.TcpIpAddress, io.grpc.channelz.v1.Address.TcpIpAddress.Builder, io.grpc.channelz.v1.Address.TcpIpAddressOrBuilder> tcpipAddressBuilder_;
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public boolean hasTcpipAddress() {
+      return addressCase_ == 1;
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public io.grpc.channelz.v1.Address.TcpIpAddress getTcpipAddress() {
+      if (tcpipAddressBuilder_ == null) {
+        if (addressCase_ == 1) {
+          return (io.grpc.channelz.v1.Address.TcpIpAddress) address_;
+        }
+        return io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance();
+      } else {
+        if (addressCase_ == 1) {
+          return tcpipAddressBuilder_.getMessage();
+        }
+        return io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public Builder setTcpipAddress(io.grpc.channelz.v1.Address.TcpIpAddress value) {
+      if (tcpipAddressBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        address_ = value;
+        onChanged();
+      } else {
+        tcpipAddressBuilder_.setMessage(value);
+      }
+      addressCase_ = 1;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public Builder setTcpipAddress(
+        io.grpc.channelz.v1.Address.TcpIpAddress.Builder builderForValue) {
+      if (tcpipAddressBuilder_ == null) {
+        address_ = builderForValue.build();
+        onChanged();
+      } else {
+        tcpipAddressBuilder_.setMessage(builderForValue.build());
+      }
+      addressCase_ = 1;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public Builder mergeTcpipAddress(io.grpc.channelz.v1.Address.TcpIpAddress value) {
+      if (tcpipAddressBuilder_ == null) {
+        if (addressCase_ == 1 &&
+            address_ != io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance()) {
+          address_ = io.grpc.channelz.v1.Address.TcpIpAddress.newBuilder((io.grpc.channelz.v1.Address.TcpIpAddress) address_)
+              .mergeFrom(value).buildPartial();
+        } else {
+          address_ = value;
+        }
+        onChanged();
+      } else {
+        if (addressCase_ == 1) {
+          tcpipAddressBuilder_.mergeFrom(value);
+        }
+        tcpipAddressBuilder_.setMessage(value);
+      }
+      addressCase_ = 1;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public Builder clearTcpipAddress() {
+      if (tcpipAddressBuilder_ == null) {
+        if (addressCase_ == 1) {
+          addressCase_ = 0;
+          address_ = null;
+          onChanged();
+        }
+      } else {
+        if (addressCase_ == 1) {
+          addressCase_ = 0;
+          address_ = null;
+        }
+        tcpipAddressBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public io.grpc.channelz.v1.Address.TcpIpAddress.Builder getTcpipAddressBuilder() {
+      return getTcpipAddressFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    public io.grpc.channelz.v1.Address.TcpIpAddressOrBuilder getTcpipAddressOrBuilder() {
+      if ((addressCase_ == 1) && (tcpipAddressBuilder_ != null)) {
+        return tcpipAddressBuilder_.getMessageOrBuilder();
+      } else {
+        if (addressCase_ == 1) {
+          return (io.grpc.channelz.v1.Address.TcpIpAddress) address_;
+        }
+        return io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address.TcpIpAddress, io.grpc.channelz.v1.Address.TcpIpAddress.Builder, io.grpc.channelz.v1.Address.TcpIpAddressOrBuilder> 
+        getTcpipAddressFieldBuilder() {
+      if (tcpipAddressBuilder_ == null) {
+        if (!(addressCase_ == 1)) {
+          address_ = io.grpc.channelz.v1.Address.TcpIpAddress.getDefaultInstance();
+        }
+        tcpipAddressBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Address.TcpIpAddress, io.grpc.channelz.v1.Address.TcpIpAddress.Builder, io.grpc.channelz.v1.Address.TcpIpAddressOrBuilder>(
+                (io.grpc.channelz.v1.Address.TcpIpAddress) address_,
+                getParentForChildren(),
+                isClean());
+        address_ = null;
+      }
+      addressCase_ = 1;
+      onChanged();;
+      return tcpipAddressBuilder_;
+    }
+
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address.UdsAddress, io.grpc.channelz.v1.Address.UdsAddress.Builder, io.grpc.channelz.v1.Address.UdsAddressOrBuilder> udsAddressBuilder_;
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public boolean hasUdsAddress() {
+      return addressCase_ == 2;
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public io.grpc.channelz.v1.Address.UdsAddress getUdsAddress() {
+      if (udsAddressBuilder_ == null) {
+        if (addressCase_ == 2) {
+          return (io.grpc.channelz.v1.Address.UdsAddress) address_;
+        }
+        return io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance();
+      } else {
+        if (addressCase_ == 2) {
+          return udsAddressBuilder_.getMessage();
+        }
+        return io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public Builder setUdsAddress(io.grpc.channelz.v1.Address.UdsAddress value) {
+      if (udsAddressBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        address_ = value;
+        onChanged();
+      } else {
+        udsAddressBuilder_.setMessage(value);
+      }
+      addressCase_ = 2;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public Builder setUdsAddress(
+        io.grpc.channelz.v1.Address.UdsAddress.Builder builderForValue) {
+      if (udsAddressBuilder_ == null) {
+        address_ = builderForValue.build();
+        onChanged();
+      } else {
+        udsAddressBuilder_.setMessage(builderForValue.build());
+      }
+      addressCase_ = 2;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public Builder mergeUdsAddress(io.grpc.channelz.v1.Address.UdsAddress value) {
+      if (udsAddressBuilder_ == null) {
+        if (addressCase_ == 2 &&
+            address_ != io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance()) {
+          address_ = io.grpc.channelz.v1.Address.UdsAddress.newBuilder((io.grpc.channelz.v1.Address.UdsAddress) address_)
+              .mergeFrom(value).buildPartial();
+        } else {
+          address_ = value;
+        }
+        onChanged();
+      } else {
+        if (addressCase_ == 2) {
+          udsAddressBuilder_.mergeFrom(value);
+        }
+        udsAddressBuilder_.setMessage(value);
+      }
+      addressCase_ = 2;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public Builder clearUdsAddress() {
+      if (udsAddressBuilder_ == null) {
+        if (addressCase_ == 2) {
+          addressCase_ = 0;
+          address_ = null;
+          onChanged();
+        }
+      } else {
+        if (addressCase_ == 2) {
+          addressCase_ = 0;
+          address_ = null;
+        }
+        udsAddressBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public io.grpc.channelz.v1.Address.UdsAddress.Builder getUdsAddressBuilder() {
+      return getUdsAddressFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    public io.grpc.channelz.v1.Address.UdsAddressOrBuilder getUdsAddressOrBuilder() {
+      if ((addressCase_ == 2) && (udsAddressBuilder_ != null)) {
+        return udsAddressBuilder_.getMessageOrBuilder();
+      } else {
+        if (addressCase_ == 2) {
+          return (io.grpc.channelz.v1.Address.UdsAddress) address_;
+        }
+        return io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address.UdsAddress, io.grpc.channelz.v1.Address.UdsAddress.Builder, io.grpc.channelz.v1.Address.UdsAddressOrBuilder> 
+        getUdsAddressFieldBuilder() {
+      if (udsAddressBuilder_ == null) {
+        if (!(addressCase_ == 2)) {
+          address_ = io.grpc.channelz.v1.Address.UdsAddress.getDefaultInstance();
+        }
+        udsAddressBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Address.UdsAddress, io.grpc.channelz.v1.Address.UdsAddress.Builder, io.grpc.channelz.v1.Address.UdsAddressOrBuilder>(
+                (io.grpc.channelz.v1.Address.UdsAddress) address_,
+                getParentForChildren(),
+                isClean());
+        address_ = null;
+      }
+      addressCase_ = 2;
+      onChanged();;
+      return udsAddressBuilder_;
+    }
+
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address.OtherAddress, io.grpc.channelz.v1.Address.OtherAddress.Builder, io.grpc.channelz.v1.Address.OtherAddressOrBuilder> otherAddressBuilder_;
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public boolean hasOtherAddress() {
+      return addressCase_ == 3;
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public io.grpc.channelz.v1.Address.OtherAddress getOtherAddress() {
+      if (otherAddressBuilder_ == null) {
+        if (addressCase_ == 3) {
+          return (io.grpc.channelz.v1.Address.OtherAddress) address_;
+        }
+        return io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance();
+      } else {
+        if (addressCase_ == 3) {
+          return otherAddressBuilder_.getMessage();
+        }
+        return io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public Builder setOtherAddress(io.grpc.channelz.v1.Address.OtherAddress value) {
+      if (otherAddressBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        address_ = value;
+        onChanged();
+      } else {
+        otherAddressBuilder_.setMessage(value);
+      }
+      addressCase_ = 3;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public Builder setOtherAddress(
+        io.grpc.channelz.v1.Address.OtherAddress.Builder builderForValue) {
+      if (otherAddressBuilder_ == null) {
+        address_ = builderForValue.build();
+        onChanged();
+      } else {
+        otherAddressBuilder_.setMessage(builderForValue.build());
+      }
+      addressCase_ = 3;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public Builder mergeOtherAddress(io.grpc.channelz.v1.Address.OtherAddress value) {
+      if (otherAddressBuilder_ == null) {
+        if (addressCase_ == 3 &&
+            address_ != io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance()) {
+          address_ = io.grpc.channelz.v1.Address.OtherAddress.newBuilder((io.grpc.channelz.v1.Address.OtherAddress) address_)
+              .mergeFrom(value).buildPartial();
+        } else {
+          address_ = value;
+        }
+        onChanged();
+      } else {
+        if (addressCase_ == 3) {
+          otherAddressBuilder_.mergeFrom(value);
+        }
+        otherAddressBuilder_.setMessage(value);
+      }
+      addressCase_ = 3;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public Builder clearOtherAddress() {
+      if (otherAddressBuilder_ == null) {
+        if (addressCase_ == 3) {
+          addressCase_ = 0;
+          address_ = null;
+          onChanged();
+        }
+      } else {
+        if (addressCase_ == 3) {
+          addressCase_ = 0;
+          address_ = null;
+        }
+        otherAddressBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public io.grpc.channelz.v1.Address.OtherAddress.Builder getOtherAddressBuilder() {
+      return getOtherAddressFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    public io.grpc.channelz.v1.Address.OtherAddressOrBuilder getOtherAddressOrBuilder() {
+      if ((addressCase_ == 3) && (otherAddressBuilder_ != null)) {
+        return otherAddressBuilder_.getMessageOrBuilder();
+      } else {
+        if (addressCase_ == 3) {
+          return (io.grpc.channelz.v1.Address.OtherAddress) address_;
+        }
+        return io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address.OtherAddress, io.grpc.channelz.v1.Address.OtherAddress.Builder, io.grpc.channelz.v1.Address.OtherAddressOrBuilder> 
+        getOtherAddressFieldBuilder() {
+      if (otherAddressBuilder_ == null) {
+        if (!(addressCase_ == 3)) {
+          address_ = io.grpc.channelz.v1.Address.OtherAddress.getDefaultInstance();
+        }
+        otherAddressBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Address.OtherAddress, io.grpc.channelz.v1.Address.OtherAddress.Builder, io.grpc.channelz.v1.Address.OtherAddressOrBuilder>(
+                (io.grpc.channelz.v1.Address.OtherAddress) address_,
+                getParentForChildren(),
+                isClean());
+        address_ = null;
+      }
+      addressCase_ = 3;
+      onChanged();;
+      return otherAddressBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.Address)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.Address)
+  private static final io.grpc.channelz.v1.Address DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.Address();
+  }
+
+  public static io.grpc.channelz.v1.Address getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<Address>
+      PARSER = new com.google.protobuf.AbstractParser<Address>() {
+    public Address parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new Address(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<Address> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<Address> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.Address getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/AddressOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/AddressOrBuilder.java
new file mode 100644
index 0000000..15e4164
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/AddressOrBuilder.java
@@ -0,0 +1,50 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface AddressOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.Address)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+   */
+  boolean hasTcpipAddress();
+  /**
+   * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+   */
+  io.grpc.channelz.v1.Address.TcpIpAddress getTcpipAddress();
+  /**
+   * <code>.grpc.channelz.Address.TcpIpAddress tcpip_address = 1;</code>
+   */
+  io.grpc.channelz.v1.Address.TcpIpAddressOrBuilder getTcpipAddressOrBuilder();
+
+  /**
+   * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+   */
+  boolean hasUdsAddress();
+  /**
+   * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+   */
+  io.grpc.channelz.v1.Address.UdsAddress getUdsAddress();
+  /**
+   * <code>.grpc.channelz.Address.UdsAddress uds_address = 2;</code>
+   */
+  io.grpc.channelz.v1.Address.UdsAddressOrBuilder getUdsAddressOrBuilder();
+
+  /**
+   * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+   */
+  boolean hasOtherAddress();
+  /**
+   * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+   */
+  io.grpc.channelz.v1.Address.OtherAddress getOtherAddress();
+  /**
+   * <code>.grpc.channelz.Address.OtherAddress other_address = 3;</code>
+   */
+  io.grpc.channelz.v1.Address.OtherAddressOrBuilder getOtherAddressOrBuilder();
+
+  public io.grpc.channelz.v1.Address.AddressCase getAddressCase();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/Channel.java b/services/src/generated/main/java/io/grpc/channelz/v1/Channel.java
new file mode 100644
index 0000000..cbd2ad0
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/Channel.java
@@ -0,0 +1,2280 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * <pre>
+ * Channel is a logical grouping of channels, subchannels, and sockets.
+ * </pre>
+ *
+ * Protobuf type {@code grpc.channelz.Channel}
+ */
+public  final class Channel extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.Channel)
+    ChannelOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use Channel.newBuilder() to construct.
+  private Channel(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private Channel() {
+    channelRef_ = java.util.Collections.emptyList();
+    subchannelRef_ = java.util.Collections.emptyList();
+    socket_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private Channel(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.ChannelRef.Builder subBuilder = null;
+            if (ref_ != null) {
+              subBuilder = ref_.toBuilder();
+            }
+            ref_ = input.readMessage(io.grpc.channelz.v1.ChannelRef.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(ref_);
+              ref_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            io.grpc.channelz.v1.ChannelData.Builder subBuilder = null;
+            if (data_ != null) {
+              subBuilder = data_.toBuilder();
+            }
+            data_ = input.readMessage(io.grpc.channelz.v1.ChannelData.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(data_);
+              data_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 26: {
+            if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+              channelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.ChannelRef>();
+              mutable_bitField0_ |= 0x00000004;
+            }
+            channelRef_.add(
+                input.readMessage(io.grpc.channelz.v1.ChannelRef.parser(), extensionRegistry));
+            break;
+          }
+          case 34: {
+            if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+              subchannelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.SubchannelRef>();
+              mutable_bitField0_ |= 0x00000008;
+            }
+            subchannelRef_.add(
+                input.readMessage(io.grpc.channelz.v1.SubchannelRef.parser(), extensionRegistry));
+            break;
+          }
+          case 42: {
+            if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+              socket_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>();
+              mutable_bitField0_ |= 0x00000010;
+            }
+            socket_.add(
+                input.readMessage(io.grpc.channelz.v1.SocketRef.parser(), extensionRegistry));
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+        channelRef_ = java.util.Collections.unmodifiableList(channelRef_);
+      }
+      if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+        subchannelRef_ = java.util.Collections.unmodifiableList(subchannelRef_);
+      }
+      if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+        socket_ = java.util.Collections.unmodifiableList(socket_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Channel_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Channel_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.Channel.class, io.grpc.channelz.v1.Channel.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int REF_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.ChannelRef ref_;
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+   */
+  public boolean hasRef() {
+    return ref_ != null;
+  }
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.ChannelRef getRef() {
+    return ref_ == null ? io.grpc.channelz.v1.ChannelRef.getDefaultInstance() : ref_;
+  }
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.ChannelRefOrBuilder getRefOrBuilder() {
+    return getRef();
+  }
+
+  public static final int DATA_FIELD_NUMBER = 2;
+  private io.grpc.channelz.v1.ChannelData data_;
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  public boolean hasData() {
+    return data_ != null;
+  }
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.ChannelData getData() {
+    return data_ == null ? io.grpc.channelz.v1.ChannelData.getDefaultInstance() : data_;
+  }
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.ChannelDataOrBuilder getDataOrBuilder() {
+    return getData();
+  }
+
+  public static final int CHANNEL_REF_FIELD_NUMBER = 3;
+  private java.util.List<io.grpc.channelz.v1.ChannelRef> channelRef_;
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.ChannelRef> getChannelRefList() {
+    return channelRef_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.ChannelRefOrBuilder> 
+      getChannelRefOrBuilderList() {
+    return channelRef_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public int getChannelRefCount() {
+    return channelRef_.size();
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public io.grpc.channelz.v1.ChannelRef getChannelRef(int index) {
+    return channelRef_.get(index);
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public io.grpc.channelz.v1.ChannelRefOrBuilder getChannelRefOrBuilder(
+      int index) {
+    return channelRef_.get(index);
+  }
+
+  public static final int SUBCHANNEL_REF_FIELD_NUMBER = 4;
+  private java.util.List<io.grpc.channelz.v1.SubchannelRef> subchannelRef_;
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.SubchannelRef> getSubchannelRefList() {
+    return subchannelRef_;
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+      getSubchannelRefOrBuilderList() {
+    return subchannelRef_;
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public int getSubchannelRefCount() {
+    return subchannelRef_.size();
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public io.grpc.channelz.v1.SubchannelRef getSubchannelRef(int index) {
+    return subchannelRef_.get(index);
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public io.grpc.channelz.v1.SubchannelRefOrBuilder getSubchannelRefOrBuilder(
+      int index) {
+    return subchannelRef_.get(index);
+  }
+
+  public static final int SOCKET_FIELD_NUMBER = 5;
+  private java.util.List<io.grpc.channelz.v1.SocketRef> socket_;
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.SocketRef> getSocketList() {
+    return socket_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getSocketOrBuilderList() {
+    return socket_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public int getSocketCount() {
+    return socket_.size();
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public io.grpc.channelz.v1.SocketRef getSocket(int index) {
+    return socket_.get(index);
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public io.grpc.channelz.v1.SocketRefOrBuilder getSocketOrBuilder(
+      int index) {
+    return socket_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (ref_ != null) {
+      output.writeMessage(1, getRef());
+    }
+    if (data_ != null) {
+      output.writeMessage(2, getData());
+    }
+    for (int i = 0; i < channelRef_.size(); i++) {
+      output.writeMessage(3, channelRef_.get(i));
+    }
+    for (int i = 0; i < subchannelRef_.size(); i++) {
+      output.writeMessage(4, subchannelRef_.get(i));
+    }
+    for (int i = 0; i < socket_.size(); i++) {
+      output.writeMessage(5, socket_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (ref_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getRef());
+    }
+    if (data_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, getData());
+    }
+    for (int i = 0; i < channelRef_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, channelRef_.get(i));
+    }
+    for (int i = 0; i < subchannelRef_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(4, subchannelRef_.get(i));
+    }
+    for (int i = 0; i < socket_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(5, socket_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.Channel)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.Channel other = (io.grpc.channelz.v1.Channel) obj;
+
+    boolean result = true;
+    result = result && (hasRef() == other.hasRef());
+    if (hasRef()) {
+      result = result && getRef()
+          .equals(other.getRef());
+    }
+    result = result && (hasData() == other.hasData());
+    if (hasData()) {
+      result = result && getData()
+          .equals(other.getData());
+    }
+    result = result && getChannelRefList()
+        .equals(other.getChannelRefList());
+    result = result && getSubchannelRefList()
+        .equals(other.getSubchannelRefList());
+    result = result && getSocketList()
+        .equals(other.getSocketList());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasRef()) {
+      hash = (37 * hash) + REF_FIELD_NUMBER;
+      hash = (53 * hash) + getRef().hashCode();
+    }
+    if (hasData()) {
+      hash = (37 * hash) + DATA_FIELD_NUMBER;
+      hash = (53 * hash) + getData().hashCode();
+    }
+    if (getChannelRefCount() > 0) {
+      hash = (37 * hash) + CHANNEL_REF_FIELD_NUMBER;
+      hash = (53 * hash) + getChannelRefList().hashCode();
+    }
+    if (getSubchannelRefCount() > 0) {
+      hash = (37 * hash) + SUBCHANNEL_REF_FIELD_NUMBER;
+      hash = (53 * hash) + getSubchannelRefList().hashCode();
+    }
+    if (getSocketCount() > 0) {
+      hash = (37 * hash) + SOCKET_FIELD_NUMBER;
+      hash = (53 * hash) + getSocketList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Channel parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Channel parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Channel parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.Channel prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * Channel is a logical grouping of channels, subchannels, and sockets.
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.Channel}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.Channel)
+      io.grpc.channelz.v1.ChannelOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Channel_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Channel_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Channel.class, io.grpc.channelz.v1.Channel.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.Channel.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getChannelRefFieldBuilder();
+        getSubchannelRefFieldBuilder();
+        getSocketFieldBuilder();
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (refBuilder_ == null) {
+        ref_ = null;
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+      if (dataBuilder_ == null) {
+        data_ = null;
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+      if (channelRefBuilder_ == null) {
+        channelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+      } else {
+        channelRefBuilder_.clear();
+      }
+      if (subchannelRefBuilder_ == null) {
+        subchannelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000008);
+      } else {
+        subchannelRefBuilder_.clear();
+      }
+      if (socketBuilder_ == null) {
+        socket_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000010);
+      } else {
+        socketBuilder_.clear();
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Channel_descriptor;
+    }
+
+    public io.grpc.channelz.v1.Channel getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.Channel.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.Channel build() {
+      io.grpc.channelz.v1.Channel result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.Channel buildPartial() {
+      io.grpc.channelz.v1.Channel result = new io.grpc.channelz.v1.Channel(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (refBuilder_ == null) {
+        result.ref_ = ref_;
+      } else {
+        result.ref_ = refBuilder_.build();
+      }
+      if (dataBuilder_ == null) {
+        result.data_ = data_;
+      } else {
+        result.data_ = dataBuilder_.build();
+      }
+      if (channelRefBuilder_ == null) {
+        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          channelRef_ = java.util.Collections.unmodifiableList(channelRef_);
+          bitField0_ = (bitField0_ & ~0x00000004);
+        }
+        result.channelRef_ = channelRef_;
+      } else {
+        result.channelRef_ = channelRefBuilder_.build();
+      }
+      if (subchannelRefBuilder_ == null) {
+        if (((bitField0_ & 0x00000008) == 0x00000008)) {
+          subchannelRef_ = java.util.Collections.unmodifiableList(subchannelRef_);
+          bitField0_ = (bitField0_ & ~0x00000008);
+        }
+        result.subchannelRef_ = subchannelRef_;
+      } else {
+        result.subchannelRef_ = subchannelRefBuilder_.build();
+      }
+      if (socketBuilder_ == null) {
+        if (((bitField0_ & 0x00000010) == 0x00000010)) {
+          socket_ = java.util.Collections.unmodifiableList(socket_);
+          bitField0_ = (bitField0_ & ~0x00000010);
+        }
+        result.socket_ = socket_;
+      } else {
+        result.socket_ = socketBuilder_.build();
+      }
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.Channel) {
+        return mergeFrom((io.grpc.channelz.v1.Channel)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.Channel other) {
+      if (other == io.grpc.channelz.v1.Channel.getDefaultInstance()) return this;
+      if (other.hasRef()) {
+        mergeRef(other.getRef());
+      }
+      if (other.hasData()) {
+        mergeData(other.getData());
+      }
+      if (channelRefBuilder_ == null) {
+        if (!other.channelRef_.isEmpty()) {
+          if (channelRef_.isEmpty()) {
+            channelRef_ = other.channelRef_;
+            bitField0_ = (bitField0_ & ~0x00000004);
+          } else {
+            ensureChannelRefIsMutable();
+            channelRef_.addAll(other.channelRef_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.channelRef_.isEmpty()) {
+          if (channelRefBuilder_.isEmpty()) {
+            channelRefBuilder_.dispose();
+            channelRefBuilder_ = null;
+            channelRef_ = other.channelRef_;
+            bitField0_ = (bitField0_ & ~0x00000004);
+            channelRefBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getChannelRefFieldBuilder() : null;
+          } else {
+            channelRefBuilder_.addAllMessages(other.channelRef_);
+          }
+        }
+      }
+      if (subchannelRefBuilder_ == null) {
+        if (!other.subchannelRef_.isEmpty()) {
+          if (subchannelRef_.isEmpty()) {
+            subchannelRef_ = other.subchannelRef_;
+            bitField0_ = (bitField0_ & ~0x00000008);
+          } else {
+            ensureSubchannelRefIsMutable();
+            subchannelRef_.addAll(other.subchannelRef_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.subchannelRef_.isEmpty()) {
+          if (subchannelRefBuilder_.isEmpty()) {
+            subchannelRefBuilder_.dispose();
+            subchannelRefBuilder_ = null;
+            subchannelRef_ = other.subchannelRef_;
+            bitField0_ = (bitField0_ & ~0x00000008);
+            subchannelRefBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getSubchannelRefFieldBuilder() : null;
+          } else {
+            subchannelRefBuilder_.addAllMessages(other.subchannelRef_);
+          }
+        }
+      }
+      if (socketBuilder_ == null) {
+        if (!other.socket_.isEmpty()) {
+          if (socket_.isEmpty()) {
+            socket_ = other.socket_;
+            bitField0_ = (bitField0_ & ~0x00000010);
+          } else {
+            ensureSocketIsMutable();
+            socket_.addAll(other.socket_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.socket_.isEmpty()) {
+          if (socketBuilder_.isEmpty()) {
+            socketBuilder_.dispose();
+            socketBuilder_ = null;
+            socket_ = other.socket_;
+            bitField0_ = (bitField0_ & ~0x00000010);
+            socketBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getSocketFieldBuilder() : null;
+          } else {
+            socketBuilder_.addAllMessages(other.socket_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.Channel parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.Channel) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private io.grpc.channelz.v1.ChannelRef ref_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder> refBuilder_;
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public boolean hasRef() {
+      return refBuilder_ != null || ref_ != null;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef getRef() {
+      if (refBuilder_ == null) {
+        return ref_ == null ? io.grpc.channelz.v1.ChannelRef.getDefaultInstance() : ref_;
+      } else {
+        return refBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public Builder setRef(io.grpc.channelz.v1.ChannelRef value) {
+      if (refBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ref_ = value;
+        onChanged();
+      } else {
+        refBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public Builder setRef(
+        io.grpc.channelz.v1.ChannelRef.Builder builderForValue) {
+      if (refBuilder_ == null) {
+        ref_ = builderForValue.build();
+        onChanged();
+      } else {
+        refBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public Builder mergeRef(io.grpc.channelz.v1.ChannelRef value) {
+      if (refBuilder_ == null) {
+        if (ref_ != null) {
+          ref_ =
+            io.grpc.channelz.v1.ChannelRef.newBuilder(ref_).mergeFrom(value).buildPartial();
+        } else {
+          ref_ = value;
+        }
+        onChanged();
+      } else {
+        refBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public Builder clearRef() {
+      if (refBuilder_ == null) {
+        ref_ = null;
+        onChanged();
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef.Builder getRefBuilder() {
+      
+      onChanged();
+      return getRefFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRefOrBuilder getRefOrBuilder() {
+      if (refBuilder_ != null) {
+        return refBuilder_.getMessageOrBuilder();
+      } else {
+        return ref_ == null ?
+            io.grpc.channelz.v1.ChannelRef.getDefaultInstance() : ref_;
+      }
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder> 
+        getRefFieldBuilder() {
+      if (refBuilder_ == null) {
+        refBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder>(
+                getRef(),
+                getParentForChildren(),
+                isClean());
+        ref_ = null;
+      }
+      return refBuilder_;
+    }
+
+    private io.grpc.channelz.v1.ChannelData data_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelData, io.grpc.channelz.v1.ChannelData.Builder, io.grpc.channelz.v1.ChannelDataOrBuilder> dataBuilder_;
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public boolean hasData() {
+      return dataBuilder_ != null || data_ != null;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ChannelData getData() {
+      if (dataBuilder_ == null) {
+        return data_ == null ? io.grpc.channelz.v1.ChannelData.getDefaultInstance() : data_;
+      } else {
+        return dataBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder setData(io.grpc.channelz.v1.ChannelData value) {
+      if (dataBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        data_ = value;
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder setData(
+        io.grpc.channelz.v1.ChannelData.Builder builderForValue) {
+      if (dataBuilder_ == null) {
+        data_ = builderForValue.build();
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder mergeData(io.grpc.channelz.v1.ChannelData value) {
+      if (dataBuilder_ == null) {
+        if (data_ != null) {
+          data_ =
+            io.grpc.channelz.v1.ChannelData.newBuilder(data_).mergeFrom(value).buildPartial();
+        } else {
+          data_ = value;
+        }
+        onChanged();
+      } else {
+        dataBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder clearData() {
+      if (dataBuilder_ == null) {
+        data_ = null;
+        onChanged();
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ChannelData.Builder getDataBuilder() {
+      
+      onChanged();
+      return getDataFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ChannelDataOrBuilder getDataOrBuilder() {
+      if (dataBuilder_ != null) {
+        return dataBuilder_.getMessageOrBuilder();
+      } else {
+        return data_ == null ?
+            io.grpc.channelz.v1.ChannelData.getDefaultInstance() : data_;
+      }
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelData, io.grpc.channelz.v1.ChannelData.Builder, io.grpc.channelz.v1.ChannelDataOrBuilder> 
+        getDataFieldBuilder() {
+      if (dataBuilder_ == null) {
+        dataBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.ChannelData, io.grpc.channelz.v1.ChannelData.Builder, io.grpc.channelz.v1.ChannelDataOrBuilder>(
+                getData(),
+                getParentForChildren(),
+                isClean());
+        data_ = null;
+      }
+      return dataBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.ChannelRef> channelRef_ =
+      java.util.Collections.emptyList();
+    private void ensureChannelRefIsMutable() {
+      if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+        channelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.ChannelRef>(channelRef_);
+        bitField0_ |= 0x00000004;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder> channelRefBuilder_;
+
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.ChannelRef> getChannelRefList() {
+      if (channelRefBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(channelRef_);
+      } else {
+        return channelRefBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public int getChannelRefCount() {
+      if (channelRefBuilder_ == null) {
+        return channelRef_.size();
+      } else {
+        return channelRefBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef getChannelRef(int index) {
+      if (channelRefBuilder_ == null) {
+        return channelRef_.get(index);
+      } else {
+        return channelRefBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder setChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef value) {
+      if (channelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelRefIsMutable();
+        channelRef_.set(index, value);
+        onChanged();
+      } else {
+        channelRefBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder setChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef.Builder builderForValue) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        channelRefBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(io.grpc.channelz.v1.ChannelRef value) {
+      if (channelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelRefIsMutable();
+        channelRef_.add(value);
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef value) {
+      if (channelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelRefIsMutable();
+        channelRef_.add(index, value);
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(
+        io.grpc.channelz.v1.ChannelRef.Builder builderForValue) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.add(builderForValue.build());
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef.Builder builderForValue) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addAllChannelRef(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.ChannelRef> values) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, channelRef_);
+        onChanged();
+      } else {
+        channelRefBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder clearChannelRef() {
+      if (channelRefBuilder_ == null) {
+        channelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+        onChanged();
+      } else {
+        channelRefBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder removeChannelRef(int index) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.remove(index);
+        onChanged();
+      } else {
+        channelRefBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef.Builder getChannelRefBuilder(
+        int index) {
+      return getChannelRefFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRefOrBuilder getChannelRefOrBuilder(
+        int index) {
+      if (channelRefBuilder_ == null) {
+        return channelRef_.get(index);  } else {
+        return channelRefBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.ChannelRefOrBuilder> 
+         getChannelRefOrBuilderList() {
+      if (channelRefBuilder_ != null) {
+        return channelRefBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(channelRef_);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef.Builder addChannelRefBuilder() {
+      return getChannelRefFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.ChannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef.Builder addChannelRefBuilder(
+        int index) {
+      return getChannelRefFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.ChannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.ChannelRef.Builder> 
+         getChannelRefBuilderList() {
+      return getChannelRefFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder> 
+        getChannelRefFieldBuilder() {
+      if (channelRefBuilder_ == null) {
+        channelRefBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder>(
+                channelRef_,
+                ((bitField0_ & 0x00000004) == 0x00000004),
+                getParentForChildren(),
+                isClean());
+        channelRef_ = null;
+      }
+      return channelRefBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.SubchannelRef> subchannelRef_ =
+      java.util.Collections.emptyList();
+    private void ensureSubchannelRefIsMutable() {
+      if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+        subchannelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.SubchannelRef>(subchannelRef_);
+        bitField0_ |= 0x00000008;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder> subchannelRefBuilder_;
+
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SubchannelRef> getSubchannelRefList() {
+      if (subchannelRefBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(subchannelRef_);
+      } else {
+        return subchannelRefBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public int getSubchannelRefCount() {
+      if (subchannelRefBuilder_ == null) {
+        return subchannelRef_.size();
+      } else {
+        return subchannelRefBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef getSubchannelRef(int index) {
+      if (subchannelRefBuilder_ == null) {
+        return subchannelRef_.get(index);
+      } else {
+        return subchannelRefBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder setSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef value) {
+      if (subchannelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.set(index, value);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder setSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef.Builder builderForValue) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        subchannelRefBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(io.grpc.channelz.v1.SubchannelRef value) {
+      if (subchannelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(value);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef value) {
+      if (subchannelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(index, value);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(
+        io.grpc.channelz.v1.SubchannelRef.Builder builderForValue) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(builderForValue.build());
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef.Builder builderForValue) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addAllSubchannelRef(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.SubchannelRef> values) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, subchannelRef_);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder clearSubchannelRef() {
+      if (subchannelRefBuilder_ == null) {
+        subchannelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000008);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder removeSubchannelRef(int index) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.remove(index);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef.Builder getSubchannelRefBuilder(
+        int index) {
+      return getSubchannelRefFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRefOrBuilder getSubchannelRefOrBuilder(
+        int index) {
+      if (subchannelRefBuilder_ == null) {
+        return subchannelRef_.get(index);  } else {
+        return subchannelRefBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+         getSubchannelRefOrBuilderList() {
+      if (subchannelRefBuilder_ != null) {
+        return subchannelRefBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(subchannelRef_);
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef.Builder addSubchannelRefBuilder() {
+      return getSubchannelRefFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.SubchannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef.Builder addSubchannelRefBuilder(
+        int index) {
+      return getSubchannelRefFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.SubchannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SubchannelRef.Builder> 
+         getSubchannelRefBuilderList() {
+      return getSubchannelRefFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+        getSubchannelRefFieldBuilder() {
+      if (subchannelRefBuilder_ == null) {
+        subchannelRefBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder>(
+                subchannelRef_,
+                ((bitField0_ & 0x00000008) == 0x00000008),
+                getParentForChildren(),
+                isClean());
+        subchannelRef_ = null;
+      }
+      return subchannelRefBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.SocketRef> socket_ =
+      java.util.Collections.emptyList();
+    private void ensureSocketIsMutable() {
+      if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+        socket_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>(socket_);
+        bitField0_ |= 0x00000010;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> socketBuilder_;
+
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef> getSocketList() {
+      if (socketBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(socket_);
+      } else {
+        return socketBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public int getSocketCount() {
+      if (socketBuilder_ == null) {
+        return socket_.size();
+      } else {
+        return socketBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef getSocket(int index) {
+      if (socketBuilder_ == null) {
+        return socket_.get(index);
+      } else {
+        return socketBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder setSocket(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (socketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketIsMutable();
+        socket_.set(index, value);
+        onChanged();
+      } else {
+        socketBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder setSocket(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        socketBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(io.grpc.channelz.v1.SocketRef value) {
+      if (socketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketIsMutable();
+        socket_.add(value);
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (socketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketIsMutable();
+        socket_.add(index, value);
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(
+        io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.add(builderForValue.build());
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addAllSocket(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.SocketRef> values) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, socket_);
+        onChanged();
+      } else {
+        socketBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder clearSocket() {
+      if (socketBuilder_ == null) {
+        socket_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000010);
+        onChanged();
+      } else {
+        socketBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder removeSocket(int index) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.remove(index);
+        onChanged();
+      } else {
+        socketBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder getSocketBuilder(
+        int index) {
+      return getSocketFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRefOrBuilder getSocketOrBuilder(
+        int index) {
+      if (socketBuilder_ == null) {
+        return socket_.get(index);  } else {
+        return socketBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+         getSocketOrBuilderList() {
+      if (socketBuilder_ != null) {
+        return socketBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(socket_);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addSocketBuilder() {
+      return getSocketFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addSocketBuilder(
+        int index) {
+      return getSocketFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef.Builder> 
+         getSocketBuilderList() {
+      return getSocketFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> 
+        getSocketFieldBuilder() {
+      if (socketBuilder_ == null) {
+        socketBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder>(
+                socket_,
+                ((bitField0_ & 0x00000010) == 0x00000010),
+                getParentForChildren(),
+                isClean());
+        socket_ = null;
+      }
+      return socketBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.Channel)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.Channel)
+  private static final io.grpc.channelz.v1.Channel DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.Channel();
+  }
+
+  public static io.grpc.channelz.v1.Channel getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<Channel>
+      PARSER = new com.google.protobuf.AbstractParser<Channel>() {
+    public Channel parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new Channel(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<Channel> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<Channel> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.Channel getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelData.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelData.java
new file mode 100644
index 0000000..3f0c384
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelData.java
@@ -0,0 +1,1396 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.ChannelData}
+ */
+public  final class ChannelData extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.ChannelData)
+    ChannelDataOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ChannelData.newBuilder() to construct.
+  private ChannelData(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ChannelData() {
+    state_ = 0;
+    target_ = "";
+    callsStarted_ = 0L;
+    callsSucceeded_ = 0L;
+    callsFailed_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ChannelData(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+            int rawValue = input.readEnum();
+
+            state_ = rawValue;
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            target_ = s;
+            break;
+          }
+          case 26: {
+            io.grpc.channelz.v1.ChannelTrace.Builder subBuilder = null;
+            if (trace_ != null) {
+              subBuilder = trace_.toBuilder();
+            }
+            trace_ = input.readMessage(io.grpc.channelz.v1.ChannelTrace.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(trace_);
+              trace_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 32: {
+
+            callsStarted_ = input.readInt64();
+            break;
+          }
+          case 40: {
+
+            callsSucceeded_ = input.readInt64();
+            break;
+          }
+          case 48: {
+
+            callsFailed_ = input.readInt64();
+            break;
+          }
+          case 58: {
+            com.google.protobuf.Timestamp.Builder subBuilder = null;
+            if (lastCallStartedTimestamp_ != null) {
+              subBuilder = lastCallStartedTimestamp_.toBuilder();
+            }
+            lastCallStartedTimestamp_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(lastCallStartedTimestamp_);
+              lastCallStartedTimestamp_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelData_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelData_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.ChannelData.class, io.grpc.channelz.v1.ChannelData.Builder.class);
+  }
+
+  /**
+   * Protobuf enum {@code grpc.channelz.ChannelData.State}
+   */
+  public enum State
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>UNKNOWN = 0;</code>
+     */
+    UNKNOWN(0),
+    /**
+     * <code>IDLE = 1;</code>
+     */
+    IDLE(1),
+    /**
+     * <code>CONNECTING = 2;</code>
+     */
+    CONNECTING(2),
+    /**
+     * <code>READY = 3;</code>
+     */
+    READY(3),
+    /**
+     * <code>TRANSIENT_FAILURE = 4;</code>
+     */
+    TRANSIENT_FAILURE(4),
+    /**
+     * <code>SHUTDOWN = 5;</code>
+     */
+    SHUTDOWN(5),
+    UNRECOGNIZED(-1),
+    ;
+
+    /**
+     * <code>UNKNOWN = 0;</code>
+     */
+    public static final int UNKNOWN_VALUE = 0;
+    /**
+     * <code>IDLE = 1;</code>
+     */
+    public static final int IDLE_VALUE = 1;
+    /**
+     * <code>CONNECTING = 2;</code>
+     */
+    public static final int CONNECTING_VALUE = 2;
+    /**
+     * <code>READY = 3;</code>
+     */
+    public static final int READY_VALUE = 3;
+    /**
+     * <code>TRANSIENT_FAILURE = 4;</code>
+     */
+    public static final int TRANSIENT_FAILURE_VALUE = 4;
+    /**
+     * <code>SHUTDOWN = 5;</code>
+     */
+    public static final int SHUTDOWN_VALUE = 5;
+
+
+    public final int getNumber() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    /**
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static State valueOf(int value) {
+      return forNumber(value);
+    }
+
+    public static State forNumber(int value) {
+      switch (value) {
+        case 0: return UNKNOWN;
+        case 1: return IDLE;
+        case 2: return CONNECTING;
+        case 3: return READY;
+        case 4: return TRANSIENT_FAILURE;
+        case 5: return SHUTDOWN;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<State>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        State> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<State>() {
+            public State findValueByNumber(int number) {
+              return State.forNumber(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      return getDescriptor().getValues().get(ordinal());
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelData.getDescriptor().getEnumTypes().get(0);
+    }
+
+    private static final State[] VALUES = values();
+
+    public static State valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int value;
+
+    private State(int value) {
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:grpc.channelz.ChannelData.State)
+  }
+
+  public static final int STATE_FIELD_NUMBER = 1;
+  private int state_;
+  /**
+   * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+   */
+  public int getStateValue() {
+    return state_;
+  }
+  /**
+   * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+   */
+  public io.grpc.channelz.v1.ChannelData.State getState() {
+    io.grpc.channelz.v1.ChannelData.State result = io.grpc.channelz.v1.ChannelData.State.valueOf(state_);
+    return result == null ? io.grpc.channelz.v1.ChannelData.State.UNRECOGNIZED : result;
+  }
+
+  public static final int TARGET_FIELD_NUMBER = 2;
+  private volatile java.lang.Object target_;
+  /**
+   * <pre>
+   * The target this channel originally tried to connect to.  May be absent
+   * </pre>
+   *
+   * <code>string target = 2;</code>
+   */
+  public java.lang.String getTarget() {
+    java.lang.Object ref = target_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      target_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * The target this channel originally tried to connect to.  May be absent
+   * </pre>
+   *
+   * <code>string target = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getTargetBytes() {
+    java.lang.Object ref = target_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      target_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int TRACE_FIELD_NUMBER = 3;
+  private io.grpc.channelz.v1.ChannelTrace trace_;
+  /**
+   * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+   */
+  public boolean hasTrace() {
+    return trace_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+   */
+  public io.grpc.channelz.v1.ChannelTrace getTrace() {
+    return trace_ == null ? io.grpc.channelz.v1.ChannelTrace.getDefaultInstance() : trace_;
+  }
+  /**
+   * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+   */
+  public io.grpc.channelz.v1.ChannelTraceOrBuilder getTraceOrBuilder() {
+    return getTrace();
+  }
+
+  public static final int CALLS_STARTED_FIELD_NUMBER = 4;
+  private long callsStarted_;
+  /**
+   * <pre>
+   * The number of calls started on the channel
+   * </pre>
+   *
+   * <code>int64 calls_started = 4;</code>
+   */
+  public long getCallsStarted() {
+    return callsStarted_;
+  }
+
+  public static final int CALLS_SUCCEEDED_FIELD_NUMBER = 5;
+  private long callsSucceeded_;
+  /**
+   * <pre>
+   * The number of calls that have completed with an OK status
+   * </pre>
+   *
+   * <code>int64 calls_succeeded = 5;</code>
+   */
+  public long getCallsSucceeded() {
+    return callsSucceeded_;
+  }
+
+  public static final int CALLS_FAILED_FIELD_NUMBER = 6;
+  private long callsFailed_;
+  /**
+   * <pre>
+   * The number of calls that have a completed with a non-OK status
+   * </pre>
+   *
+   * <code>int64 calls_failed = 6;</code>
+   */
+  public long getCallsFailed() {
+    return callsFailed_;
+  }
+
+  public static final int LAST_CALL_STARTED_TIMESTAMP_FIELD_NUMBER = 7;
+  private com.google.protobuf.Timestamp lastCallStartedTimestamp_;
+  /**
+   * <pre>
+   * The last time a call was started on the channel.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+   */
+  public boolean hasLastCallStartedTimestamp() {
+    return lastCallStartedTimestamp_ != null;
+  }
+  /**
+   * <pre>
+   * The last time a call was started on the channel.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+   */
+  public com.google.protobuf.Timestamp getLastCallStartedTimestamp() {
+    return lastCallStartedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastCallStartedTimestamp_;
+  }
+  /**
+   * <pre>
+   * The last time a call was started on the channel.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+   */
+  public com.google.protobuf.TimestampOrBuilder getLastCallStartedTimestampOrBuilder() {
+    return getLastCallStartedTimestamp();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (state_ != io.grpc.channelz.v1.ChannelData.State.UNKNOWN.getNumber()) {
+      output.writeEnum(1, state_);
+    }
+    if (!getTargetBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, target_);
+    }
+    if (trace_ != null) {
+      output.writeMessage(3, getTrace());
+    }
+    if (callsStarted_ != 0L) {
+      output.writeInt64(4, callsStarted_);
+    }
+    if (callsSucceeded_ != 0L) {
+      output.writeInt64(5, callsSucceeded_);
+    }
+    if (callsFailed_ != 0L) {
+      output.writeInt64(6, callsFailed_);
+    }
+    if (lastCallStartedTimestamp_ != null) {
+      output.writeMessage(7, getLastCallStartedTimestamp());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (state_ != io.grpc.channelz.v1.ChannelData.State.UNKNOWN.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(1, state_);
+    }
+    if (!getTargetBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, target_);
+    }
+    if (trace_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, getTrace());
+    }
+    if (callsStarted_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(4, callsStarted_);
+    }
+    if (callsSucceeded_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(5, callsSucceeded_);
+    }
+    if (callsFailed_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(6, callsFailed_);
+    }
+    if (lastCallStartedTimestamp_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(7, getLastCallStartedTimestamp());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.ChannelData)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.ChannelData other = (io.grpc.channelz.v1.ChannelData) obj;
+
+    boolean result = true;
+    result = result && state_ == other.state_;
+    result = result && getTarget()
+        .equals(other.getTarget());
+    result = result && (hasTrace() == other.hasTrace());
+    if (hasTrace()) {
+      result = result && getTrace()
+          .equals(other.getTrace());
+    }
+    result = result && (getCallsStarted()
+        == other.getCallsStarted());
+    result = result && (getCallsSucceeded()
+        == other.getCallsSucceeded());
+    result = result && (getCallsFailed()
+        == other.getCallsFailed());
+    result = result && (hasLastCallStartedTimestamp() == other.hasLastCallStartedTimestamp());
+    if (hasLastCallStartedTimestamp()) {
+      result = result && getLastCallStartedTimestamp()
+          .equals(other.getLastCallStartedTimestamp());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + STATE_FIELD_NUMBER;
+    hash = (53 * hash) + state_;
+    hash = (37 * hash) + TARGET_FIELD_NUMBER;
+    hash = (53 * hash) + getTarget().hashCode();
+    if (hasTrace()) {
+      hash = (37 * hash) + TRACE_FIELD_NUMBER;
+      hash = (53 * hash) + getTrace().hashCode();
+    }
+    hash = (37 * hash) + CALLS_STARTED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getCallsStarted());
+    hash = (37 * hash) + CALLS_SUCCEEDED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getCallsSucceeded());
+    hash = (37 * hash) + CALLS_FAILED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getCallsFailed());
+    if (hasLastCallStartedTimestamp()) {
+      hash = (37 * hash) + LAST_CALL_STARTED_TIMESTAMP_FIELD_NUMBER;
+      hash = (53 * hash) + getLastCallStartedTimestamp().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelData parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.ChannelData prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.ChannelData}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.ChannelData)
+      io.grpc.channelz.v1.ChannelDataOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelData_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelData_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.ChannelData.class, io.grpc.channelz.v1.ChannelData.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.ChannelData.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      state_ = 0;
+
+      target_ = "";
+
+      if (traceBuilder_ == null) {
+        trace_ = null;
+      } else {
+        trace_ = null;
+        traceBuilder_ = null;
+      }
+      callsStarted_ = 0L;
+
+      callsSucceeded_ = 0L;
+
+      callsFailed_ = 0L;
+
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestamp_ = null;
+      } else {
+        lastCallStartedTimestamp_ = null;
+        lastCallStartedTimestampBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelData_descriptor;
+    }
+
+    public io.grpc.channelz.v1.ChannelData getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.ChannelData.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.ChannelData build() {
+      io.grpc.channelz.v1.ChannelData result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.ChannelData buildPartial() {
+      io.grpc.channelz.v1.ChannelData result = new io.grpc.channelz.v1.ChannelData(this);
+      result.state_ = state_;
+      result.target_ = target_;
+      if (traceBuilder_ == null) {
+        result.trace_ = trace_;
+      } else {
+        result.trace_ = traceBuilder_.build();
+      }
+      result.callsStarted_ = callsStarted_;
+      result.callsSucceeded_ = callsSucceeded_;
+      result.callsFailed_ = callsFailed_;
+      if (lastCallStartedTimestampBuilder_ == null) {
+        result.lastCallStartedTimestamp_ = lastCallStartedTimestamp_;
+      } else {
+        result.lastCallStartedTimestamp_ = lastCallStartedTimestampBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.ChannelData) {
+        return mergeFrom((io.grpc.channelz.v1.ChannelData)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.ChannelData other) {
+      if (other == io.grpc.channelz.v1.ChannelData.getDefaultInstance()) return this;
+      if (other.state_ != 0) {
+        setStateValue(other.getStateValue());
+      }
+      if (!other.getTarget().isEmpty()) {
+        target_ = other.target_;
+        onChanged();
+      }
+      if (other.hasTrace()) {
+        mergeTrace(other.getTrace());
+      }
+      if (other.getCallsStarted() != 0L) {
+        setCallsStarted(other.getCallsStarted());
+      }
+      if (other.getCallsSucceeded() != 0L) {
+        setCallsSucceeded(other.getCallsSucceeded());
+      }
+      if (other.getCallsFailed() != 0L) {
+        setCallsFailed(other.getCallsFailed());
+      }
+      if (other.hasLastCallStartedTimestamp()) {
+        mergeLastCallStartedTimestamp(other.getLastCallStartedTimestamp());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.ChannelData parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.ChannelData) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private int state_ = 0;
+    /**
+     * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+     */
+    public int getStateValue() {
+      return state_;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+     */
+    public Builder setStateValue(int value) {
+      state_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+     */
+    public io.grpc.channelz.v1.ChannelData.State getState() {
+      io.grpc.channelz.v1.ChannelData.State result = io.grpc.channelz.v1.ChannelData.State.valueOf(state_);
+      return result == null ? io.grpc.channelz.v1.ChannelData.State.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+     */
+    public Builder setState(io.grpc.channelz.v1.ChannelData.State value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      state_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+     */
+    public Builder clearState() {
+      
+      state_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object target_ = "";
+    /**
+     * <pre>
+     * The target this channel originally tried to connect to.  May be absent
+     * </pre>
+     *
+     * <code>string target = 2;</code>
+     */
+    public java.lang.String getTarget() {
+      java.lang.Object ref = target_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        target_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The target this channel originally tried to connect to.  May be absent
+     * </pre>
+     *
+     * <code>string target = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTargetBytes() {
+      java.lang.Object ref = target_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        target_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The target this channel originally tried to connect to.  May be absent
+     * </pre>
+     *
+     * <code>string target = 2;</code>
+     */
+    public Builder setTarget(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      target_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The target this channel originally tried to connect to.  May be absent
+     * </pre>
+     *
+     * <code>string target = 2;</code>
+     */
+    public Builder clearTarget() {
+      
+      target_ = getDefaultInstance().getTarget();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The target this channel originally tried to connect to.  May be absent
+     * </pre>
+     *
+     * <code>string target = 2;</code>
+     */
+    public Builder setTargetBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      target_ = value;
+      onChanged();
+      return this;
+    }
+
+    private io.grpc.channelz.v1.ChannelTrace trace_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelTrace, io.grpc.channelz.v1.ChannelTrace.Builder, io.grpc.channelz.v1.ChannelTraceOrBuilder> traceBuilder_;
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public boolean hasTrace() {
+      return traceBuilder_ != null || trace_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelTrace getTrace() {
+      if (traceBuilder_ == null) {
+        return trace_ == null ? io.grpc.channelz.v1.ChannelTrace.getDefaultInstance() : trace_;
+      } else {
+        return traceBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public Builder setTrace(io.grpc.channelz.v1.ChannelTrace value) {
+      if (traceBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        trace_ = value;
+        onChanged();
+      } else {
+        traceBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public Builder setTrace(
+        io.grpc.channelz.v1.ChannelTrace.Builder builderForValue) {
+      if (traceBuilder_ == null) {
+        trace_ = builderForValue.build();
+        onChanged();
+      } else {
+        traceBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public Builder mergeTrace(io.grpc.channelz.v1.ChannelTrace value) {
+      if (traceBuilder_ == null) {
+        if (trace_ != null) {
+          trace_ =
+            io.grpc.channelz.v1.ChannelTrace.newBuilder(trace_).mergeFrom(value).buildPartial();
+        } else {
+          trace_ = value;
+        }
+        onChanged();
+      } else {
+        traceBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public Builder clearTrace() {
+      if (traceBuilder_ == null) {
+        trace_ = null;
+        onChanged();
+      } else {
+        trace_ = null;
+        traceBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelTrace.Builder getTraceBuilder() {
+      
+      onChanged();
+      return getTraceFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelTraceOrBuilder getTraceOrBuilder() {
+      if (traceBuilder_ != null) {
+        return traceBuilder_.getMessageOrBuilder();
+      } else {
+        return trace_ == null ?
+            io.grpc.channelz.v1.ChannelTrace.getDefaultInstance() : trace_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelTrace, io.grpc.channelz.v1.ChannelTrace.Builder, io.grpc.channelz.v1.ChannelTraceOrBuilder> 
+        getTraceFieldBuilder() {
+      if (traceBuilder_ == null) {
+        traceBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.ChannelTrace, io.grpc.channelz.v1.ChannelTrace.Builder, io.grpc.channelz.v1.ChannelTraceOrBuilder>(
+                getTrace(),
+                getParentForChildren(),
+                isClean());
+        trace_ = null;
+      }
+      return traceBuilder_;
+    }
+
+    private long callsStarted_ ;
+    /**
+     * <pre>
+     * The number of calls started on the channel
+     * </pre>
+     *
+     * <code>int64 calls_started = 4;</code>
+     */
+    public long getCallsStarted() {
+      return callsStarted_;
+    }
+    /**
+     * <pre>
+     * The number of calls started on the channel
+     * </pre>
+     *
+     * <code>int64 calls_started = 4;</code>
+     */
+    public Builder setCallsStarted(long value) {
+      
+      callsStarted_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of calls started on the channel
+     * </pre>
+     *
+     * <code>int64 calls_started = 4;</code>
+     */
+    public Builder clearCallsStarted() {
+      
+      callsStarted_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long callsSucceeded_ ;
+    /**
+     * <pre>
+     * The number of calls that have completed with an OK status
+     * </pre>
+     *
+     * <code>int64 calls_succeeded = 5;</code>
+     */
+    public long getCallsSucceeded() {
+      return callsSucceeded_;
+    }
+    /**
+     * <pre>
+     * The number of calls that have completed with an OK status
+     * </pre>
+     *
+     * <code>int64 calls_succeeded = 5;</code>
+     */
+    public Builder setCallsSucceeded(long value) {
+      
+      callsSucceeded_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of calls that have completed with an OK status
+     * </pre>
+     *
+     * <code>int64 calls_succeeded = 5;</code>
+     */
+    public Builder clearCallsSucceeded() {
+      
+      callsSucceeded_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long callsFailed_ ;
+    /**
+     * <pre>
+     * The number of calls that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 calls_failed = 6;</code>
+     */
+    public long getCallsFailed() {
+      return callsFailed_;
+    }
+    /**
+     * <pre>
+     * The number of calls that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 calls_failed = 6;</code>
+     */
+    public Builder setCallsFailed(long value) {
+      
+      callsFailed_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of calls that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 calls_failed = 6;</code>
+     */
+    public Builder clearCallsFailed() {
+      
+      callsFailed_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.Timestamp lastCallStartedTimestamp_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lastCallStartedTimestampBuilder_;
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public boolean hasLastCallStartedTimestamp() {
+      return lastCallStartedTimestampBuilder_ != null || lastCallStartedTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public com.google.protobuf.Timestamp getLastCallStartedTimestamp() {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        return lastCallStartedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastCallStartedTimestamp_;
+      } else {
+        return lastCallStartedTimestampBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public Builder setLastCallStartedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        lastCallStartedTimestamp_ = value;
+        onChanged();
+      } else {
+        lastCallStartedTimestampBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public Builder setLastCallStartedTimestamp(
+        com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestamp_ = builderForValue.build();
+        onChanged();
+      } else {
+        lastCallStartedTimestampBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public Builder mergeLastCallStartedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        if (lastCallStartedTimestamp_ != null) {
+          lastCallStartedTimestamp_ =
+            com.google.protobuf.Timestamp.newBuilder(lastCallStartedTimestamp_).mergeFrom(value).buildPartial();
+        } else {
+          lastCallStartedTimestamp_ = value;
+        }
+        onChanged();
+      } else {
+        lastCallStartedTimestampBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public Builder clearLastCallStartedTimestamp() {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestamp_ = null;
+        onChanged();
+      } else {
+        lastCallStartedTimestamp_ = null;
+        lastCallStartedTimestampBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public com.google.protobuf.Timestamp.Builder getLastCallStartedTimestampBuilder() {
+      
+      onChanged();
+      return getLastCallStartedTimestampFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getLastCallStartedTimestampOrBuilder() {
+      if (lastCallStartedTimestampBuilder_ != null) {
+        return lastCallStartedTimestampBuilder_.getMessageOrBuilder();
+      } else {
+        return lastCallStartedTimestamp_ == null ?
+            com.google.protobuf.Timestamp.getDefaultInstance() : lastCallStartedTimestamp_;
+      }
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the channel.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
+        getLastCallStartedTimestampFieldBuilder() {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
+                getLastCallStartedTimestamp(),
+                getParentForChildren(),
+                isClean());
+        lastCallStartedTimestamp_ = null;
+      }
+      return lastCallStartedTimestampBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.ChannelData)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.ChannelData)
+  private static final io.grpc.channelz.v1.ChannelData DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.ChannelData();
+  }
+
+  public static io.grpc.channelz.v1.ChannelData getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ChannelData>
+      PARSER = new com.google.protobuf.AbstractParser<ChannelData>() {
+    public ChannelData parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ChannelData(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ChannelData> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ChannelData> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.ChannelData getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelDataOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelDataOrBuilder.java
new file mode 100644
index 0000000..5186df1
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelDataOrBuilder.java
@@ -0,0 +1,101 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ChannelDataOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.ChannelData)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+   */
+  int getStateValue();
+  /**
+   * <code>.grpc.channelz.ChannelData.State state = 1;</code>
+   */
+  io.grpc.channelz.v1.ChannelData.State getState();
+
+  /**
+   * <pre>
+   * The target this channel originally tried to connect to.  May be absent
+   * </pre>
+   *
+   * <code>string target = 2;</code>
+   */
+  java.lang.String getTarget();
+  /**
+   * <pre>
+   * The target this channel originally tried to connect to.  May be absent
+   * </pre>
+   *
+   * <code>string target = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getTargetBytes();
+
+  /**
+   * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+   */
+  boolean hasTrace();
+  /**
+   * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+   */
+  io.grpc.channelz.v1.ChannelTrace getTrace();
+  /**
+   * <code>.grpc.channelz.ChannelTrace trace = 3;</code>
+   */
+  io.grpc.channelz.v1.ChannelTraceOrBuilder getTraceOrBuilder();
+
+  /**
+   * <pre>
+   * The number of calls started on the channel
+   * </pre>
+   *
+   * <code>int64 calls_started = 4;</code>
+   */
+  long getCallsStarted();
+
+  /**
+   * <pre>
+   * The number of calls that have completed with an OK status
+   * </pre>
+   *
+   * <code>int64 calls_succeeded = 5;</code>
+   */
+  long getCallsSucceeded();
+
+  /**
+   * <pre>
+   * The number of calls that have a completed with a non-OK status
+   * </pre>
+   *
+   * <code>int64 calls_failed = 6;</code>
+   */
+  long getCallsFailed();
+
+  /**
+   * <pre>
+   * The last time a call was started on the channel.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+   */
+  boolean hasLastCallStartedTimestamp();
+  /**
+   * <pre>
+   * The last time a call was started on the channel.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+   */
+  com.google.protobuf.Timestamp getLastCallStartedTimestamp();
+  /**
+   * <pre>
+   * The last time a call was started on the channel.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 7;</code>
+   */
+  com.google.protobuf.TimestampOrBuilder getLastCallStartedTimestampOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelOrBuilder.java
new file mode 100644
index 0000000..1ad2584
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelOrBuilder.java
@@ -0,0 +1,216 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ChannelOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.Channel)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+   */
+  boolean hasRef();
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.ChannelRef getRef();
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.ChannelRefOrBuilder getRefOrBuilder();
+
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  boolean hasData();
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  io.grpc.channelz.v1.ChannelData getData();
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  io.grpc.channelz.v1.ChannelDataOrBuilder getDataOrBuilder();
+
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.ChannelRef> 
+      getChannelRefList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  io.grpc.channelz.v1.ChannelRef getChannelRef(int index);
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  int getChannelRefCount();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.ChannelRefOrBuilder> 
+      getChannelRefOrBuilderList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  io.grpc.channelz.v1.ChannelRefOrBuilder getChannelRefOrBuilder(
+      int index);
+
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.SubchannelRef> 
+      getSubchannelRefList();
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  io.grpc.channelz.v1.SubchannelRef getSubchannelRef(int index);
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  int getSubchannelRefCount();
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+      getSubchannelRefOrBuilderList();
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  io.grpc.channelz.v1.SubchannelRefOrBuilder getSubchannelRefOrBuilder(
+      int index);
+
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.SocketRef> 
+      getSocketList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  io.grpc.channelz.v1.SocketRef getSocket(int index);
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  int getSocketCount();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getSocketOrBuilderList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  io.grpc.channelz.v1.SocketRefOrBuilder getSocketOrBuilder(
+      int index);
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelRef.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelRef.java
new file mode 100644
index 0000000..58f64b6
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelRef.java
@@ -0,0 +1,619 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.ChannelRef}
+ */
+public  final class ChannelRef extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.ChannelRef)
+    ChannelRefOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ChannelRef.newBuilder() to construct.
+  private ChannelRef(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ChannelRef() {
+    channelId_ = 0L;
+    name_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ChannelRef(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            channelId_ = input.readInt64();
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelRef_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelRef_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.ChannelRef.class, io.grpc.channelz.v1.ChannelRef.Builder.class);
+  }
+
+  public static final int CHANNEL_ID_FIELD_NUMBER = 1;
+  private long channelId_;
+  /**
+   * <pre>
+   * The globally unique id for this channel.  Must be a positive number.
+   * </pre>
+   *
+   * <code>int64 channel_id = 1;</code>
+   */
+  public long getChannelId() {
+    return channelId_;
+  }
+
+  public static final int NAME_FIELD_NUMBER = 2;
+  private volatile java.lang.Object name_;
+  /**
+   * <pre>
+   * An optional name associated with the channel.
+   * </pre>
+   *
+   * <code>string name = 2;</code>
+   */
+  public java.lang.String getName() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * An optional name associated with the channel.
+   * </pre>
+   *
+   * <code>string name = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (channelId_ != 0L) {
+      output.writeInt64(1, channelId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, name_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (channelId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, channelId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.ChannelRef)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.ChannelRef other = (io.grpc.channelz.v1.ChannelRef) obj;
+
+    boolean result = true;
+    result = result && (getChannelId()
+        == other.getChannelId());
+    result = result && getName()
+        .equals(other.getName());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + CHANNEL_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getChannelId());
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelRef parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.ChannelRef prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.ChannelRef}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.ChannelRef)
+      io.grpc.channelz.v1.ChannelRefOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelRef_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelRef_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.ChannelRef.class, io.grpc.channelz.v1.ChannelRef.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.ChannelRef.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      channelId_ = 0L;
+
+      name_ = "";
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelRef_descriptor;
+    }
+
+    public io.grpc.channelz.v1.ChannelRef getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.ChannelRef.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.ChannelRef build() {
+      io.grpc.channelz.v1.ChannelRef result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.ChannelRef buildPartial() {
+      io.grpc.channelz.v1.ChannelRef result = new io.grpc.channelz.v1.ChannelRef(this);
+      result.channelId_ = channelId_;
+      result.name_ = name_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.ChannelRef) {
+        return mergeFrom((io.grpc.channelz.v1.ChannelRef)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.ChannelRef other) {
+      if (other == io.grpc.channelz.v1.ChannelRef.getDefaultInstance()) return this;
+      if (other.getChannelId() != 0L) {
+        setChannelId(other.getChannelId());
+      }
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.ChannelRef parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.ChannelRef) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long channelId_ ;
+    /**
+     * <pre>
+     * The globally unique id for this channel.  Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 channel_id = 1;</code>
+     */
+    public long getChannelId() {
+      return channelId_;
+    }
+    /**
+     * <pre>
+     * The globally unique id for this channel.  Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 channel_id = 1;</code>
+     */
+    public Builder setChannelId(long value) {
+      
+      channelId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The globally unique id for this channel.  Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 channel_id = 1;</code>
+     */
+    public Builder clearChannelId() {
+      
+      channelId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object name_ = "";
+    /**
+     * <pre>
+     * An optional name associated with the channel.
+     * </pre>
+     *
+     * <code>string name = 2;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the channel.
+     * </pre>
+     *
+     * <code>string name = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the channel.
+     * </pre>
+     *
+     * <code>string name = 2;</code>
+     */
+    public Builder setName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the channel.
+     * </pre>
+     *
+     * <code>string name = 2;</code>
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the channel.
+     * </pre>
+     *
+     * <code>string name = 2;</code>
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.ChannelRef)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.ChannelRef)
+  private static final io.grpc.channelz.v1.ChannelRef DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.ChannelRef();
+  }
+
+  public static io.grpc.channelz.v1.ChannelRef getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ChannelRef>
+      PARSER = new com.google.protobuf.AbstractParser<ChannelRef>() {
+    public ChannelRef parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ChannelRef(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ChannelRef> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ChannelRef> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.ChannelRef getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelRefOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelRefOrBuilder.java
new file mode 100644
index 0000000..184d536
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelRefOrBuilder.java
@@ -0,0 +1,36 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ChannelRefOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.ChannelRef)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * The globally unique id for this channel.  Must be a positive number.
+   * </pre>
+   *
+   * <code>int64 channel_id = 1;</code>
+   */
+  long getChannelId();
+
+  /**
+   * <pre>
+   * An optional name associated with the channel.
+   * </pre>
+   *
+   * <code>string name = 2;</code>
+   */
+  java.lang.String getName();
+  /**
+   * <pre>
+   * An optional name associated with the channel.
+   * </pre>
+   *
+   * <code>string name = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelTrace.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelTrace.java
new file mode 100644
index 0000000..8674301
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelTrace.java
@@ -0,0 +1,396 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * <pre>
+ * TODO: fill this in.
+ * </pre>
+ *
+ * Protobuf type {@code grpc.channelz.ChannelTrace}
+ */
+public  final class ChannelTrace extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.ChannelTrace)
+    ChannelTraceOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ChannelTrace.newBuilder() to construct.
+  private ChannelTrace(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ChannelTrace() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ChannelTrace(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelTrace_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelTrace_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.ChannelTrace.class, io.grpc.channelz.v1.ChannelTrace.Builder.class);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.ChannelTrace)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.ChannelTrace other = (io.grpc.channelz.v1.ChannelTrace) obj;
+
+    boolean result = true;
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ChannelTrace parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.ChannelTrace prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * TODO: fill this in.
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.ChannelTrace}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.ChannelTrace)
+      io.grpc.channelz.v1.ChannelTraceOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelTrace_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelTrace_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.ChannelTrace.class, io.grpc.channelz.v1.ChannelTrace.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.ChannelTrace.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ChannelTrace_descriptor;
+    }
+
+    public io.grpc.channelz.v1.ChannelTrace getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.ChannelTrace.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.ChannelTrace build() {
+      io.grpc.channelz.v1.ChannelTrace result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.ChannelTrace buildPartial() {
+      io.grpc.channelz.v1.ChannelTrace result = new io.grpc.channelz.v1.ChannelTrace(this);
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.ChannelTrace) {
+        return mergeFrom((io.grpc.channelz.v1.ChannelTrace)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.ChannelTrace other) {
+      if (other == io.grpc.channelz.v1.ChannelTrace.getDefaultInstance()) return this;
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.ChannelTrace parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.ChannelTrace) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.ChannelTrace)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.ChannelTrace)
+  private static final io.grpc.channelz.v1.ChannelTrace DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.ChannelTrace();
+  }
+
+  public static io.grpc.channelz.v1.ChannelTrace getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ChannelTrace>
+      PARSER = new com.google.protobuf.AbstractParser<ChannelTrace>() {
+    public ChannelTrace parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ChannelTrace(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ChannelTrace> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ChannelTrace> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.ChannelTrace getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelTraceOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelTraceOrBuilder.java
new file mode 100644
index 0000000..05804db
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelTraceOrBuilder.java
@@ -0,0 +1,9 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ChannelTraceOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.ChannelTrace)
+    com.google.protobuf.MessageOrBuilder {
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ChannelzProto.java b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelzProto.java
new file mode 100644
index 0000000..8d1de39
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ChannelzProto.java
@@ -0,0 +1,583 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public final class ChannelzProto {
+  private ChannelzProto() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Channel_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Channel_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Subchannel_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Subchannel_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_ChannelData_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_ChannelData_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_ChannelTrace_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_ChannelTrace_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_ChannelRef_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_ChannelRef_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_SubchannelRef_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_SubchannelRef_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_SocketRef_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_SocketRef_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_ServerRef_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_ServerRef_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Server_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Server_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_ServerData_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_ServerData_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_ServerChannelTrace_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_ServerChannelTrace_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Socket_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Socket_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_SocketData_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_SocketData_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Address_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Address_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Address_TcpIpAddress_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Address_TcpIpAddress_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Address_UdsAddress_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Address_UdsAddress_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Address_OtherAddress_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Address_OtherAddress_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Security_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Security_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Security_Tls_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Security_Tls_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_Security_OtherSecurity_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_Security_OtherSecurity_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_SocketOption_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_SocketOption_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_SocketOptionTimeout_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_SocketOptionTimeout_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_SocketOptionLinger_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_SocketOptionLinger_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_SocketOptionTcpInfo_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_SocketOptionTcpInfo_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetServersRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetServersRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetServersResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetServersResponse_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetServerSocketsRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetServerSocketsRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetServerSocketsResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetServerSocketsResponse_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetTopChannelsRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetTopChannelsRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetTopChannelsResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetTopChannelsResponse_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetChannelRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetChannelRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetChannelResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetChannelResponse_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetSubchannelRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetSubchannelRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetSubchannelResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetSubchannelResponse_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetSocketRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetSocketRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_grpc_channelz_GetSocketResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_grpc_channelz_GetSocketResponse_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\026io/grpc/channelz.proto\022\rgrpc.channelz\032" +
+      "\031google/protobuf/any.proto\032\036google/proto" +
+      "buf/duration.proto\032\037google/protobuf/time" +
+      "stamp.proto\032\036google/protobuf/wrappers.pr" +
+      "oto\"\353\001\n\007Channel\022&\n\003ref\030\001 \001(\0132\031.grpc.chan" +
+      "nelz.ChannelRef\022(\n\004data\030\002 \001(\0132\032.grpc.cha" +
+      "nnelz.ChannelData\022.\n\013channel_ref\030\003 \003(\0132\031" +
+      ".grpc.channelz.ChannelRef\0224\n\016subchannel_" +
+      "ref\030\004 \003(\0132\034.grpc.channelz.SubchannelRef\022" +
+      "(\n\006socket\030\005 \003(\0132\030.grpc.channelz.SocketRe" +
+      "f\"\361\001\n\nSubchannel\022)\n\003ref\030\001 \001(\0132\034.grpc.cha" +
+      "nnelz.SubchannelRef\022(\n\004data\030\002 \001(\0132\032.grpc" +
+      ".channelz.ChannelData\022.\n\013channel_ref\030\003 \003" +
+      "(\0132\031.grpc.channelz.ChannelRef\0224\n\016subchan" +
+      "nel_ref\030\004 \003(\0132\034.grpc.channelz.Subchannel" +
+      "Ref\022(\n\006socket\030\005 \003(\0132\030.grpc.channelz.Sock" +
+      "etRef\"\341\002\n\013ChannelData\022/\n\005state\030\001 \001(\0162 .g" +
+      "rpc.channelz.ChannelData.State\022\016\n\006target" +
+      "\030\002 \001(\t\022*\n\005trace\030\003 \001(\0132\033.grpc.channelz.Ch" +
+      "annelTrace\022\025\n\rcalls_started\030\004 \001(\003\022\027\n\017cal" +
+      "ls_succeeded\030\005 \001(\003\022\024\n\014calls_failed\030\006 \001(\003" +
+      "\022?\n\033last_call_started_timestamp\030\007 \001(\0132\032." +
+      "google.protobuf.Timestamp\"^\n\005State\022\013\n\007UN" +
+      "KNOWN\020\000\022\010\n\004IDLE\020\001\022\016\n\nCONNECTING\020\002\022\t\n\005REA" +
+      "DY\020\003\022\025\n\021TRANSIENT_FAILURE\020\004\022\014\n\010SHUTDOWN\020" +
+      "\005\"\016\n\014ChannelTrace\"F\n\nChannelRef\022\022\n\nchann" +
+      "el_id\030\001 \001(\003\022\014\n\004name\030\002 \001(\tJ\004\010\003\020\004J\004\010\004\020\005J\004\010" +
+      "\005\020\006J\004\010\006\020\007\"X\n\rSubchannelRef\022\025\n\rsubchannel" +
+      "_id\030\007 \001(\003\022\014\n\004name\030\010 \001(\tJ\004\010\001\020\002J\004\010\002\020\003J\004\010\003\020" +
+      "\004J\004\010\004\020\005J\004\010\005\020\006J\004\010\006\020\007\"P\n\tSocketRef\022\021\n\tsock" +
+      "et_id\030\003 \001(\003\022\014\n\004name\030\004 \001(\tJ\004\010\001\020\002J\004\010\002\020\003J\004\010" +
+      "\005\020\006J\004\010\006\020\007J\004\010\007\020\010J\004\010\010\020\t\"P\n\tServerRef\022\021\n\tse" +
+      "rver_id\030\005 \001(\003\022\014\n\004name\030\006 \001(\tJ\004\010\001\020\002J\004\010\002\020\003J" +
+      "\004\010\003\020\004J\004\010\004\020\005J\004\010\007\020\010J\004\010\010\020\t\"\211\001\n\006Server\022%\n\003re" +
+      "f\030\001 \001(\0132\030.grpc.channelz.ServerRef\022\'\n\004dat" +
+      "a\030\002 \001(\0132\031.grpc.channelz.ServerData\022/\n\rli" +
+      "sten_socket\030\003 \003(\0132\030.grpc.channelz.Socket" +
+      "Ref\"\305\001\n\nServerData\0220\n\005trace\030\001 \001(\0132!.grpc" +
+      ".channelz.ServerChannelTrace\022\025\n\rcalls_st" +
+      "arted\030\002 \001(\003\022\027\n\017calls_succeeded\030\003 \001(\003\022\024\n\014" +
+      "calls_failed\030\004 \001(\003\022?\n\033last_call_started_" +
+      "timestamp\030\005 \001(\0132\032.google.protobuf.Timest" +
+      "amp\"\024\n\022ServerChannelTrace\"\347\001\n\006Socket\022%\n\003" +
+      "ref\030\001 \001(\0132\030.grpc.channelz.SocketRef\022\'\n\004d" +
+      "ata\030\002 \001(\0132\031.grpc.channelz.SocketData\022%\n\005" +
+      "local\030\003 \001(\0132\026.grpc.channelz.Address\022&\n\006r" +
+      "emote\030\004 \001(\0132\026.grpc.channelz.Address\022)\n\010s" +
+      "ecurity\030\005 \001(\0132\027.grpc.channelz.Security\022\023" +
+      "\n\013remote_name\030\006 \001(\t\"\353\004\n\nSocketData\022\027\n\017st" +
+      "reams_started\030\001 \001(\003\022\031\n\021streams_succeeded" +
+      "\030\002 \001(\003\022\026\n\016streams_failed\030\003 \001(\003\022\025\n\rmessag" +
+      "es_sent\030\004 \001(\003\022\031\n\021messages_received\030\005 \001(\003" +
+      "\022\030\n\020keep_alives_sent\030\006 \001(\003\022G\n#last_local" +
+      "_stream_created_timestamp\030\007 \001(\0132\032.google" +
+      ".protobuf.Timestamp\022H\n$last_remote_strea" +
+      "m_created_timestamp\030\010 \001(\0132\032.google.proto" +
+      "buf.Timestamp\022?\n\033last_message_sent_times" +
+      "tamp\030\t \001(\0132\032.google.protobuf.Timestamp\022C" +
+      "\n\037last_message_received_timestamp\030\n \001(\0132" +
+      "\032.google.protobuf.Timestamp\022>\n\031local_flo" +
+      "w_control_window\030\013 \001(\0132\033.google.protobuf" +
+      ".Int64Value\022?\n\032remote_flow_control_windo" +
+      "w\030\014 \001(\0132\033.google.protobuf.Int64Value\022+\n\006" +
+      "option\030\r \003(\0132\033.grpc.channelz.SocketOptio" +
+      "n\"\337\002\n\007Address\022<\n\rtcpip_address\030\001 \001(\0132#.g" +
+      "rpc.channelz.Address.TcpIpAddressH\000\0228\n\013u" +
+      "ds_address\030\002 \001(\0132!.grpc.channelz.Address" +
+      ".UdsAddressH\000\022<\n\rother_address\030\003 \001(\0132#.g" +
+      "rpc.channelz.Address.OtherAddressH\000\0320\n\014T" +
+      "cpIpAddress\022\022\n\nip_address\030\001 \001(\014\022\014\n\004port\030" +
+      "\002 \001(\005\032\036\n\nUdsAddress\022\020\n\010filename\030\001 \001(\t\032A\n" +
+      "\014OtherAddress\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001" +
+      "(\0132\024.google.protobuf.AnyB\t\n\007address\"\237\002\n\010" +
+      "Security\022*\n\003tls\030\001 \001(\0132\033.grpc.channelz.Se" +
+      "curity.TlsH\000\0226\n\005other\030\002 \001(\0132%.grpc.chann" +
+      "elz.Security.OtherSecurityH\000\032b\n\003Tls\022\024\n\014k" +
+      "ey_exchange\030\001 \001(\t\022\016\n\006cipher\030\002 \001(\t\022\031\n\021loc" +
+      "al_certificate\030\003 \001(\014\022\032\n\022remote_certifica" +
+      "te\030\004 \001(\014\032B\n\rOtherSecurity\022\014\n\004name\030\001 \001(\t\022" +
+      "#\n\005value\030\002 \001(\0132\024.google.protobuf.AnyB\007\n\005" +
+      "model\"U\n\014SocketOption\022\014\n\004name\030\001 \001(\t\022\r\n\005v" +
+      "alue\030\002 \001(\t\022(\n\nadditional\030\003 \001(\0132\024.google." +
+      "protobuf.Any\"B\n\023SocketOptionTimeout\022+\n\010d" +
+      "uration\030\001 \001(\0132\031.google.protobuf.Duration" +
+      "\"Q\n\022SocketOptionLinger\022\016\n\006active\030\001 \001(\010\022+" +
+      "\n\010duration\030\002 \001(\0132\031.google.protobuf.Durat" +
+      "ion\"\256\005\n\023SocketOptionTcpInfo\022\022\n\ntcpi_stat" +
+      "e\030\001 \001(\r\022\025\n\rtcpi_ca_state\030\002 \001(\r\022\030\n\020tcpi_r" +
+      "etransmits\030\003 \001(\r\022\023\n\013tcpi_probes\030\004 \001(\r\022\024\n" +
+      "\014tcpi_backoff\030\005 \001(\r\022\024\n\014tcpi_options\030\006 \001(" +
+      "\r\022\027\n\017tcpi_snd_wscale\030\007 \001(\r\022\027\n\017tcpi_rcv_w" +
+      "scale\030\010 \001(\r\022\020\n\010tcpi_rto\030\t \001(\r\022\020\n\010tcpi_at" +
+      "o\030\n \001(\r\022\024\n\014tcpi_snd_mss\030\013 \001(\r\022\024\n\014tcpi_rc" +
+      "v_mss\030\014 \001(\r\022\024\n\014tcpi_unacked\030\r \001(\r\022\023\n\013tcp" +
+      "i_sacked\030\016 \001(\r\022\021\n\ttcpi_lost\030\017 \001(\r\022\024\n\014tcp" +
+      "i_retrans\030\020 \001(\r\022\024\n\014tcpi_fackets\030\021 \001(\r\022\033\n" +
+      "\023tcpi_last_data_sent\030\022 \001(\r\022\032\n\022tcpi_last_" +
+      "ack_sent\030\023 \001(\r\022\033\n\023tcpi_last_data_recv\030\024 " +
+      "\001(\r\022\032\n\022tcpi_last_ack_recv\030\025 \001(\r\022\021\n\ttcpi_" +
+      "pmtu\030\026 \001(\r\022\031\n\021tcpi_rcv_ssthresh\030\027 \001(\r\022\020\n" +
+      "\010tcpi_rtt\030\030 \001(\r\022\023\n\013tcpi_rttvar\030\031 \001(\r\022\031\n\021" +
+      "tcpi_snd_ssthresh\030\032 \001(\r\022\025\n\rtcpi_snd_cwnd" +
+      "\030\033 \001(\r\022\023\n\013tcpi_advmss\030\034 \001(\r\022\027\n\017tcpi_reor" +
+      "dering\030\035 \001(\r\",\n\021GetServersRequest\022\027\n\017sta" +
+      "rt_server_id\030\001 \001(\003\"H\n\022GetServersResponse" +
+      "\022%\n\006server\030\001 \003(\0132\025.grpc.channelz.Server\022" +
+      "\013\n\003end\030\002 \001(\010\"E\n\027GetServerSocketsRequest\022" +
+      "\021\n\tserver_id\030\001 \001(\003\022\027\n\017start_socket_id\030\002 " +
+      "\001(\003\"U\n\030GetServerSocketsResponse\022,\n\nsocke" +
+      "t_ref\030\001 \003(\0132\030.grpc.channelz.SocketRef\022\013\n" +
+      "\003end\030\002 \001(\010\"1\n\025GetTopChannelsRequest\022\030\n\020s" +
+      "tart_channel_id\030\001 \001(\003\"N\n\026GetTopChannelsR" +
+      "esponse\022\'\n\007channel\030\001 \003(\0132\026.grpc.channelz" +
+      ".Channel\022\013\n\003end\030\002 \001(\010\"\'\n\021GetChannelReque" +
+      "st\022\022\n\nchannel_id\030\001 \001(\003\"=\n\022GetChannelResp" +
+      "onse\022\'\n\007channel\030\001 \001(\0132\026.grpc.channelz.Ch" +
+      "annel\"-\n\024GetSubchannelRequest\022\025\n\rsubchan" +
+      "nel_id\030\001 \001(\003\"F\n\025GetSubchannelResponse\022-\n" +
+      "\nsubchannel\030\001 \001(\0132\031.grpc.channelz.Subcha" +
+      "nnel\"%\n\020GetSocketRequest\022\021\n\tsocket_id\030\001 " +
+      "\001(\003\":\n\021GetSocketResponse\022%\n\006socket\030\001 \001(\013" +
+      "2\025.grpc.channelz.Socket2\240\004\n\010Channelz\022]\n\016" +
+      "GetTopChannels\022$.grpc.channelz.GetTopCha" +
+      "nnelsRequest\032%.grpc.channelz.GetTopChann" +
+      "elsResponse\022Q\n\nGetServers\022 .grpc.channel" +
+      "z.GetServersRequest\032!.grpc.channelz.GetS" +
+      "erversResponse\022c\n\020GetServerSockets\022&.grp" +
+      "c.channelz.GetServerSocketsRequest\032\'.grp" +
+      "c.channelz.GetServerSocketsResponse\022Q\n\nG" +
+      "etChannel\022 .grpc.channelz.GetChannelRequ" +
+      "est\032!.grpc.channelz.GetChannelResponse\022Z" +
+      "\n\rGetSubchannel\022#.grpc.channelz.GetSubch" +
+      "annelRequest\032$.grpc.channelz.GetSubchann" +
+      "elResponse\022N\n\tGetSocket\022\037.grpc.channelz." +
+      "GetSocketRequest\032 .grpc.channelz.GetSock" +
+      "etResponseB&\n\023io.grpc.channelz.v1B\rChann" +
+      "elzProtoP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          com.google.protobuf.AnyProto.getDescriptor(),
+          com.google.protobuf.DurationProto.getDescriptor(),
+          com.google.protobuf.TimestampProto.getDescriptor(),
+          com.google.protobuf.WrappersProto.getDescriptor(),
+        }, assigner);
+    internal_static_grpc_channelz_Channel_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_grpc_channelz_Channel_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Channel_descriptor,
+        new java.lang.String[] { "Ref", "Data", "ChannelRef", "SubchannelRef", "Socket", });
+    internal_static_grpc_channelz_Subchannel_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_grpc_channelz_Subchannel_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Subchannel_descriptor,
+        new java.lang.String[] { "Ref", "Data", "ChannelRef", "SubchannelRef", "Socket", });
+    internal_static_grpc_channelz_ChannelData_descriptor =
+      getDescriptor().getMessageTypes().get(2);
+    internal_static_grpc_channelz_ChannelData_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_ChannelData_descriptor,
+        new java.lang.String[] { "State", "Target", "Trace", "CallsStarted", "CallsSucceeded", "CallsFailed", "LastCallStartedTimestamp", });
+    internal_static_grpc_channelz_ChannelTrace_descriptor =
+      getDescriptor().getMessageTypes().get(3);
+    internal_static_grpc_channelz_ChannelTrace_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_ChannelTrace_descriptor,
+        new java.lang.String[] { });
+    internal_static_grpc_channelz_ChannelRef_descriptor =
+      getDescriptor().getMessageTypes().get(4);
+    internal_static_grpc_channelz_ChannelRef_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_ChannelRef_descriptor,
+        new java.lang.String[] { "ChannelId", "Name", });
+    internal_static_grpc_channelz_SubchannelRef_descriptor =
+      getDescriptor().getMessageTypes().get(5);
+    internal_static_grpc_channelz_SubchannelRef_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_SubchannelRef_descriptor,
+        new java.lang.String[] { "SubchannelId", "Name", });
+    internal_static_grpc_channelz_SocketRef_descriptor =
+      getDescriptor().getMessageTypes().get(6);
+    internal_static_grpc_channelz_SocketRef_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_SocketRef_descriptor,
+        new java.lang.String[] { "SocketId", "Name", });
+    internal_static_grpc_channelz_ServerRef_descriptor =
+      getDescriptor().getMessageTypes().get(7);
+    internal_static_grpc_channelz_ServerRef_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_ServerRef_descriptor,
+        new java.lang.String[] { "ServerId", "Name", });
+    internal_static_grpc_channelz_Server_descriptor =
+      getDescriptor().getMessageTypes().get(8);
+    internal_static_grpc_channelz_Server_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Server_descriptor,
+        new java.lang.String[] { "Ref", "Data", "ListenSocket", });
+    internal_static_grpc_channelz_ServerData_descriptor =
+      getDescriptor().getMessageTypes().get(9);
+    internal_static_grpc_channelz_ServerData_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_ServerData_descriptor,
+        new java.lang.String[] { "Trace", "CallsStarted", "CallsSucceeded", "CallsFailed", "LastCallStartedTimestamp", });
+    internal_static_grpc_channelz_ServerChannelTrace_descriptor =
+      getDescriptor().getMessageTypes().get(10);
+    internal_static_grpc_channelz_ServerChannelTrace_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_ServerChannelTrace_descriptor,
+        new java.lang.String[] { });
+    internal_static_grpc_channelz_Socket_descriptor =
+      getDescriptor().getMessageTypes().get(11);
+    internal_static_grpc_channelz_Socket_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Socket_descriptor,
+        new java.lang.String[] { "Ref", "Data", "Local", "Remote", "Security", "RemoteName", });
+    internal_static_grpc_channelz_SocketData_descriptor =
+      getDescriptor().getMessageTypes().get(12);
+    internal_static_grpc_channelz_SocketData_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_SocketData_descriptor,
+        new java.lang.String[] { "StreamsStarted", "StreamsSucceeded", "StreamsFailed", "MessagesSent", "MessagesReceived", "KeepAlivesSent", "LastLocalStreamCreatedTimestamp", "LastRemoteStreamCreatedTimestamp", "LastMessageSentTimestamp", "LastMessageReceivedTimestamp", "LocalFlowControlWindow", "RemoteFlowControlWindow", "Option", });
+    internal_static_grpc_channelz_Address_descriptor =
+      getDescriptor().getMessageTypes().get(13);
+    internal_static_grpc_channelz_Address_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Address_descriptor,
+        new java.lang.String[] { "TcpipAddress", "UdsAddress", "OtherAddress", "Address", });
+    internal_static_grpc_channelz_Address_TcpIpAddress_descriptor =
+      internal_static_grpc_channelz_Address_descriptor.getNestedTypes().get(0);
+    internal_static_grpc_channelz_Address_TcpIpAddress_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Address_TcpIpAddress_descriptor,
+        new java.lang.String[] { "IpAddress", "Port", });
+    internal_static_grpc_channelz_Address_UdsAddress_descriptor =
+      internal_static_grpc_channelz_Address_descriptor.getNestedTypes().get(1);
+    internal_static_grpc_channelz_Address_UdsAddress_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Address_UdsAddress_descriptor,
+        new java.lang.String[] { "Filename", });
+    internal_static_grpc_channelz_Address_OtherAddress_descriptor =
+      internal_static_grpc_channelz_Address_descriptor.getNestedTypes().get(2);
+    internal_static_grpc_channelz_Address_OtherAddress_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Address_OtherAddress_descriptor,
+        new java.lang.String[] { "Name", "Value", });
+    internal_static_grpc_channelz_Security_descriptor =
+      getDescriptor().getMessageTypes().get(14);
+    internal_static_grpc_channelz_Security_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Security_descriptor,
+        new java.lang.String[] { "Tls", "Other", "Model", });
+    internal_static_grpc_channelz_Security_Tls_descriptor =
+      internal_static_grpc_channelz_Security_descriptor.getNestedTypes().get(0);
+    internal_static_grpc_channelz_Security_Tls_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Security_Tls_descriptor,
+        new java.lang.String[] { "KeyExchange", "Cipher", "LocalCertificate", "RemoteCertificate", });
+    internal_static_grpc_channelz_Security_OtherSecurity_descriptor =
+      internal_static_grpc_channelz_Security_descriptor.getNestedTypes().get(1);
+    internal_static_grpc_channelz_Security_OtherSecurity_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_Security_OtherSecurity_descriptor,
+        new java.lang.String[] { "Name", "Value", });
+    internal_static_grpc_channelz_SocketOption_descriptor =
+      getDescriptor().getMessageTypes().get(15);
+    internal_static_grpc_channelz_SocketOption_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_SocketOption_descriptor,
+        new java.lang.String[] { "Name", "Value", "Additional", });
+    internal_static_grpc_channelz_SocketOptionTimeout_descriptor =
+      getDescriptor().getMessageTypes().get(16);
+    internal_static_grpc_channelz_SocketOptionTimeout_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_SocketOptionTimeout_descriptor,
+        new java.lang.String[] { "Duration", });
+    internal_static_grpc_channelz_SocketOptionLinger_descriptor =
+      getDescriptor().getMessageTypes().get(17);
+    internal_static_grpc_channelz_SocketOptionLinger_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_SocketOptionLinger_descriptor,
+        new java.lang.String[] { "Active", "Duration", });
+    internal_static_grpc_channelz_SocketOptionTcpInfo_descriptor =
+      getDescriptor().getMessageTypes().get(18);
+    internal_static_grpc_channelz_SocketOptionTcpInfo_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_SocketOptionTcpInfo_descriptor,
+        new java.lang.String[] { "TcpiState", "TcpiCaState", "TcpiRetransmits", "TcpiProbes", "TcpiBackoff", "TcpiOptions", "TcpiSndWscale", "TcpiRcvWscale", "TcpiRto", "TcpiAto", "TcpiSndMss", "TcpiRcvMss", "TcpiUnacked", "TcpiSacked", "TcpiLost", "TcpiRetrans", "TcpiFackets", "TcpiLastDataSent", "TcpiLastAckSent", "TcpiLastDataRecv", "TcpiLastAckRecv", "TcpiPmtu", "TcpiRcvSsthresh", "TcpiRtt", "TcpiRttvar", "TcpiSndSsthresh", "TcpiSndCwnd", "TcpiAdvmss", "TcpiReordering", });
+    internal_static_grpc_channelz_GetServersRequest_descriptor =
+      getDescriptor().getMessageTypes().get(19);
+    internal_static_grpc_channelz_GetServersRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetServersRequest_descriptor,
+        new java.lang.String[] { "StartServerId", });
+    internal_static_grpc_channelz_GetServersResponse_descriptor =
+      getDescriptor().getMessageTypes().get(20);
+    internal_static_grpc_channelz_GetServersResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetServersResponse_descriptor,
+        new java.lang.String[] { "Server", "End", });
+    internal_static_grpc_channelz_GetServerSocketsRequest_descriptor =
+      getDescriptor().getMessageTypes().get(21);
+    internal_static_grpc_channelz_GetServerSocketsRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetServerSocketsRequest_descriptor,
+        new java.lang.String[] { "ServerId", "StartSocketId", });
+    internal_static_grpc_channelz_GetServerSocketsResponse_descriptor =
+      getDescriptor().getMessageTypes().get(22);
+    internal_static_grpc_channelz_GetServerSocketsResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetServerSocketsResponse_descriptor,
+        new java.lang.String[] { "SocketRef", "End", });
+    internal_static_grpc_channelz_GetTopChannelsRequest_descriptor =
+      getDescriptor().getMessageTypes().get(23);
+    internal_static_grpc_channelz_GetTopChannelsRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetTopChannelsRequest_descriptor,
+        new java.lang.String[] { "StartChannelId", });
+    internal_static_grpc_channelz_GetTopChannelsResponse_descriptor =
+      getDescriptor().getMessageTypes().get(24);
+    internal_static_grpc_channelz_GetTopChannelsResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetTopChannelsResponse_descriptor,
+        new java.lang.String[] { "Channel", "End", });
+    internal_static_grpc_channelz_GetChannelRequest_descriptor =
+      getDescriptor().getMessageTypes().get(25);
+    internal_static_grpc_channelz_GetChannelRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetChannelRequest_descriptor,
+        new java.lang.String[] { "ChannelId", });
+    internal_static_grpc_channelz_GetChannelResponse_descriptor =
+      getDescriptor().getMessageTypes().get(26);
+    internal_static_grpc_channelz_GetChannelResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetChannelResponse_descriptor,
+        new java.lang.String[] { "Channel", });
+    internal_static_grpc_channelz_GetSubchannelRequest_descriptor =
+      getDescriptor().getMessageTypes().get(27);
+    internal_static_grpc_channelz_GetSubchannelRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetSubchannelRequest_descriptor,
+        new java.lang.String[] { "SubchannelId", });
+    internal_static_grpc_channelz_GetSubchannelResponse_descriptor =
+      getDescriptor().getMessageTypes().get(28);
+    internal_static_grpc_channelz_GetSubchannelResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetSubchannelResponse_descriptor,
+        new java.lang.String[] { "Subchannel", });
+    internal_static_grpc_channelz_GetSocketRequest_descriptor =
+      getDescriptor().getMessageTypes().get(29);
+    internal_static_grpc_channelz_GetSocketRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetSocketRequest_descriptor,
+        new java.lang.String[] { "SocketId", });
+    internal_static_grpc_channelz_GetSocketResponse_descriptor =
+      getDescriptor().getMessageTypes().get(30);
+    internal_static_grpc_channelz_GetSocketResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_grpc_channelz_GetSocketResponse_descriptor,
+        new java.lang.String[] { "Socket", });
+    com.google.protobuf.AnyProto.getDescriptor();
+    com.google.protobuf.DurationProto.getDescriptor();
+    com.google.protobuf.TimestampProto.getDescriptor();
+    com.google.protobuf.WrappersProto.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelRequest.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelRequest.java
new file mode 100644
index 0000000..862177b
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelRequest.java
@@ -0,0 +1,448 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetChannelRequest}
+ */
+public  final class GetChannelRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetChannelRequest)
+    GetChannelRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetChannelRequest.newBuilder() to construct.
+  private GetChannelRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetChannelRequest() {
+    channelId_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetChannelRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            channelId_ = input.readInt64();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelRequest_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetChannelRequest.class, io.grpc.channelz.v1.GetChannelRequest.Builder.class);
+  }
+
+  public static final int CHANNEL_ID_FIELD_NUMBER = 1;
+  private long channelId_;
+  /**
+   * <code>int64 channel_id = 1;</code>
+   */
+  public long getChannelId() {
+    return channelId_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (channelId_ != 0L) {
+      output.writeInt64(1, channelId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (channelId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, channelId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetChannelRequest)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetChannelRequest other = (io.grpc.channelz.v1.GetChannelRequest) obj;
+
+    boolean result = true;
+    result = result && (getChannelId()
+        == other.getChannelId());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + CHANNEL_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getChannelId());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetChannelRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetChannelRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetChannelRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetChannelRequest)
+      io.grpc.channelz.v1.GetChannelRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetChannelRequest.class, io.grpc.channelz.v1.GetChannelRequest.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetChannelRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      channelId_ = 0L;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelRequest_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetChannelRequest getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetChannelRequest.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetChannelRequest build() {
+      io.grpc.channelz.v1.GetChannelRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetChannelRequest buildPartial() {
+      io.grpc.channelz.v1.GetChannelRequest result = new io.grpc.channelz.v1.GetChannelRequest(this);
+      result.channelId_ = channelId_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetChannelRequest) {
+        return mergeFrom((io.grpc.channelz.v1.GetChannelRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetChannelRequest other) {
+      if (other == io.grpc.channelz.v1.GetChannelRequest.getDefaultInstance()) return this;
+      if (other.getChannelId() != 0L) {
+        setChannelId(other.getChannelId());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetChannelRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetChannelRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long channelId_ ;
+    /**
+     * <code>int64 channel_id = 1;</code>
+     */
+    public long getChannelId() {
+      return channelId_;
+    }
+    /**
+     * <code>int64 channel_id = 1;</code>
+     */
+    public Builder setChannelId(long value) {
+      
+      channelId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 channel_id = 1;</code>
+     */
+    public Builder clearChannelId() {
+      
+      channelId_ = 0L;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetChannelRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetChannelRequest)
+  private static final io.grpc.channelz.v1.GetChannelRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetChannelRequest();
+  }
+
+  public static io.grpc.channelz.v1.GetChannelRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetChannelRequest>
+      PARSER = new com.google.protobuf.AbstractParser<GetChannelRequest>() {
+    public GetChannelRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetChannelRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetChannelRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetChannelRequest> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetChannelRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelRequestOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelRequestOrBuilder.java
new file mode 100644
index 0000000..6c131fe
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelRequestOrBuilder.java
@@ -0,0 +1,14 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetChannelRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetChannelRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 channel_id = 1;</code>
+   */
+  long getChannelId();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelResponse.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelResponse.java
new file mode 100644
index 0000000..99632a4
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelResponse.java
@@ -0,0 +1,570 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetChannelResponse}
+ */
+public  final class GetChannelResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetChannelResponse)
+    GetChannelResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetChannelResponse.newBuilder() to construct.
+  private GetChannelResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetChannelResponse() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetChannelResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.Channel.Builder subBuilder = null;
+            if (channel_ != null) {
+              subBuilder = channel_.toBuilder();
+            }
+            channel_ = input.readMessage(io.grpc.channelz.v1.Channel.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(channel_);
+              channel_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelResponse_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetChannelResponse.class, io.grpc.channelz.v1.GetChannelResponse.Builder.class);
+  }
+
+  public static final int CHANNEL_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.Channel channel_;
+  /**
+   * <code>.grpc.channelz.Channel channel = 1;</code>
+   */
+  public boolean hasChannel() {
+    return channel_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.Channel channel = 1;</code>
+   */
+  public io.grpc.channelz.v1.Channel getChannel() {
+    return channel_ == null ? io.grpc.channelz.v1.Channel.getDefaultInstance() : channel_;
+  }
+  /**
+   * <code>.grpc.channelz.Channel channel = 1;</code>
+   */
+  public io.grpc.channelz.v1.ChannelOrBuilder getChannelOrBuilder() {
+    return getChannel();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (channel_ != null) {
+      output.writeMessage(1, getChannel());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (channel_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getChannel());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetChannelResponse)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetChannelResponse other = (io.grpc.channelz.v1.GetChannelResponse) obj;
+
+    boolean result = true;
+    result = result && (hasChannel() == other.hasChannel());
+    if (hasChannel()) {
+      result = result && getChannel()
+          .equals(other.getChannel());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasChannel()) {
+      hash = (37 * hash) + CHANNEL_FIELD_NUMBER;
+      hash = (53 * hash) + getChannel().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetChannelResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetChannelResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetChannelResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetChannelResponse)
+      io.grpc.channelz.v1.GetChannelResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetChannelResponse.class, io.grpc.channelz.v1.GetChannelResponse.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetChannelResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (channelBuilder_ == null) {
+        channel_ = null;
+      } else {
+        channel_ = null;
+        channelBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetChannelResponse_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetChannelResponse getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetChannelResponse.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetChannelResponse build() {
+      io.grpc.channelz.v1.GetChannelResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetChannelResponse buildPartial() {
+      io.grpc.channelz.v1.GetChannelResponse result = new io.grpc.channelz.v1.GetChannelResponse(this);
+      if (channelBuilder_ == null) {
+        result.channel_ = channel_;
+      } else {
+        result.channel_ = channelBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetChannelResponse) {
+        return mergeFrom((io.grpc.channelz.v1.GetChannelResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetChannelResponse other) {
+      if (other == io.grpc.channelz.v1.GetChannelResponse.getDefaultInstance()) return this;
+      if (other.hasChannel()) {
+        mergeChannel(other.getChannel());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetChannelResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetChannelResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.grpc.channelz.v1.Channel channel_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Channel, io.grpc.channelz.v1.Channel.Builder, io.grpc.channelz.v1.ChannelOrBuilder> channelBuilder_;
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public boolean hasChannel() {
+      return channelBuilder_ != null || channel_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Channel getChannel() {
+      if (channelBuilder_ == null) {
+        return channel_ == null ? io.grpc.channelz.v1.Channel.getDefaultInstance() : channel_;
+      } else {
+        return channelBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder setChannel(io.grpc.channelz.v1.Channel value) {
+      if (channelBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        channel_ = value;
+        onChanged();
+      } else {
+        channelBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder setChannel(
+        io.grpc.channelz.v1.Channel.Builder builderForValue) {
+      if (channelBuilder_ == null) {
+        channel_ = builderForValue.build();
+        onChanged();
+      } else {
+        channelBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder mergeChannel(io.grpc.channelz.v1.Channel value) {
+      if (channelBuilder_ == null) {
+        if (channel_ != null) {
+          channel_ =
+            io.grpc.channelz.v1.Channel.newBuilder(channel_).mergeFrom(value).buildPartial();
+        } else {
+          channel_ = value;
+        }
+        onChanged();
+      } else {
+        channelBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder clearChannel() {
+      if (channelBuilder_ == null) {
+        channel_ = null;
+        onChanged();
+      } else {
+        channel_ = null;
+        channelBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Channel.Builder getChannelBuilder() {
+      
+      onChanged();
+      return getChannelFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.ChannelOrBuilder getChannelOrBuilder() {
+      if (channelBuilder_ != null) {
+        return channelBuilder_.getMessageOrBuilder();
+      } else {
+        return channel_ == null ?
+            io.grpc.channelz.v1.Channel.getDefaultInstance() : channel_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Channel channel = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Channel, io.grpc.channelz.v1.Channel.Builder, io.grpc.channelz.v1.ChannelOrBuilder> 
+        getChannelFieldBuilder() {
+      if (channelBuilder_ == null) {
+        channelBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Channel, io.grpc.channelz.v1.Channel.Builder, io.grpc.channelz.v1.ChannelOrBuilder>(
+                getChannel(),
+                getParentForChildren(),
+                isClean());
+        channel_ = null;
+      }
+      return channelBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetChannelResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetChannelResponse)
+  private static final io.grpc.channelz.v1.GetChannelResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetChannelResponse();
+  }
+
+  public static io.grpc.channelz.v1.GetChannelResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetChannelResponse>
+      PARSER = new com.google.protobuf.AbstractParser<GetChannelResponse>() {
+    public GetChannelResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetChannelResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetChannelResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetChannelResponse> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetChannelResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelResponseOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelResponseOrBuilder.java
new file mode 100644
index 0000000..5b8d7c2
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetChannelResponseOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetChannelResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetChannelResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.Channel channel = 1;</code>
+   */
+  boolean hasChannel();
+  /**
+   * <code>.grpc.channelz.Channel channel = 1;</code>
+   */
+  io.grpc.channelz.v1.Channel getChannel();
+  /**
+   * <code>.grpc.channelz.Channel channel = 1;</code>
+   */
+  io.grpc.channelz.v1.ChannelOrBuilder getChannelOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsRequest.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsRequest.java
new file mode 100644
index 0000000..9b77872
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsRequest.java
@@ -0,0 +1,527 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetServerSocketsRequest}
+ */
+public  final class GetServerSocketsRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetServerSocketsRequest)
+    GetServerSocketsRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetServerSocketsRequest.newBuilder() to construct.
+  private GetServerSocketsRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetServerSocketsRequest() {
+    serverId_ = 0L;
+    startSocketId_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetServerSocketsRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            serverId_ = input.readInt64();
+            break;
+          }
+          case 16: {
+
+            startSocketId_ = input.readInt64();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsRequest_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetServerSocketsRequest.class, io.grpc.channelz.v1.GetServerSocketsRequest.Builder.class);
+  }
+
+  public static final int SERVER_ID_FIELD_NUMBER = 1;
+  private long serverId_;
+  /**
+   * <code>int64 server_id = 1;</code>
+   */
+  public long getServerId() {
+    return serverId_;
+  }
+
+  public static final int START_SOCKET_ID_FIELD_NUMBER = 2;
+  private long startSocketId_;
+  /**
+   * <pre>
+   * start_socket_id indicates that only sockets at or above this id should be
+   * included in the results.
+   * </pre>
+   *
+   * <code>int64 start_socket_id = 2;</code>
+   */
+  public long getStartSocketId() {
+    return startSocketId_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (serverId_ != 0L) {
+      output.writeInt64(1, serverId_);
+    }
+    if (startSocketId_ != 0L) {
+      output.writeInt64(2, startSocketId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (serverId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, serverId_);
+    }
+    if (startSocketId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(2, startSocketId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetServerSocketsRequest)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetServerSocketsRequest other = (io.grpc.channelz.v1.GetServerSocketsRequest) obj;
+
+    boolean result = true;
+    result = result && (getServerId()
+        == other.getServerId());
+    result = result && (getStartSocketId()
+        == other.getStartSocketId());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + SERVER_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getServerId());
+    hash = (37 * hash) + START_SOCKET_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getStartSocketId());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetServerSocketsRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetServerSocketsRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetServerSocketsRequest)
+      io.grpc.channelz.v1.GetServerSocketsRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetServerSocketsRequest.class, io.grpc.channelz.v1.GetServerSocketsRequest.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetServerSocketsRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      serverId_ = 0L;
+
+      startSocketId_ = 0L;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsRequest_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetServerSocketsRequest getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetServerSocketsRequest.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetServerSocketsRequest build() {
+      io.grpc.channelz.v1.GetServerSocketsRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetServerSocketsRequest buildPartial() {
+      io.grpc.channelz.v1.GetServerSocketsRequest result = new io.grpc.channelz.v1.GetServerSocketsRequest(this);
+      result.serverId_ = serverId_;
+      result.startSocketId_ = startSocketId_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetServerSocketsRequest) {
+        return mergeFrom((io.grpc.channelz.v1.GetServerSocketsRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetServerSocketsRequest other) {
+      if (other == io.grpc.channelz.v1.GetServerSocketsRequest.getDefaultInstance()) return this;
+      if (other.getServerId() != 0L) {
+        setServerId(other.getServerId());
+      }
+      if (other.getStartSocketId() != 0L) {
+        setStartSocketId(other.getStartSocketId());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetServerSocketsRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetServerSocketsRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long serverId_ ;
+    /**
+     * <code>int64 server_id = 1;</code>
+     */
+    public long getServerId() {
+      return serverId_;
+    }
+    /**
+     * <code>int64 server_id = 1;</code>
+     */
+    public Builder setServerId(long value) {
+      
+      serverId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 server_id = 1;</code>
+     */
+    public Builder clearServerId() {
+      
+      serverId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long startSocketId_ ;
+    /**
+     * <pre>
+     * start_socket_id indicates that only sockets at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_socket_id = 2;</code>
+     */
+    public long getStartSocketId() {
+      return startSocketId_;
+    }
+    /**
+     * <pre>
+     * start_socket_id indicates that only sockets at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_socket_id = 2;</code>
+     */
+    public Builder setStartSocketId(long value) {
+      
+      startSocketId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * start_socket_id indicates that only sockets at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_socket_id = 2;</code>
+     */
+    public Builder clearStartSocketId() {
+      
+      startSocketId_ = 0L;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetServerSocketsRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetServerSocketsRequest)
+  private static final io.grpc.channelz.v1.GetServerSocketsRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetServerSocketsRequest();
+  }
+
+  public static io.grpc.channelz.v1.GetServerSocketsRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetServerSocketsRequest>
+      PARSER = new com.google.protobuf.AbstractParser<GetServerSocketsRequest>() {
+    public GetServerSocketsRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetServerSocketsRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetServerSocketsRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetServerSocketsRequest> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetServerSocketsRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsRequestOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsRequestOrBuilder.java
new file mode 100644
index 0000000..d9a3bb1
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsRequestOrBuilder.java
@@ -0,0 +1,24 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetServerSocketsRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetServerSocketsRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 server_id = 1;</code>
+   */
+  long getServerId();
+
+  /**
+   * <pre>
+   * start_socket_id indicates that only sockets at or above this id should be
+   * included in the results.
+   * </pre>
+   *
+   * <code>int64 start_socket_id = 2;</code>
+   */
+  long getStartSocketId();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsResponse.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsResponse.java
new file mode 100644
index 0000000..d675183
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsResponse.java
@@ -0,0 +1,935 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetServerSocketsResponse}
+ */
+public  final class GetServerSocketsResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetServerSocketsResponse)
+    GetServerSocketsResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetServerSocketsResponse.newBuilder() to construct.
+  private GetServerSocketsResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetServerSocketsResponse() {
+    socketRef_ = java.util.Collections.emptyList();
+    end_ = false;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetServerSocketsResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              socketRef_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            socketRef_.add(
+                input.readMessage(io.grpc.channelz.v1.SocketRef.parser(), extensionRegistry));
+            break;
+          }
+          case 16: {
+
+            end_ = input.readBool();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        socketRef_ = java.util.Collections.unmodifiableList(socketRef_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsResponse_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetServerSocketsResponse.class, io.grpc.channelz.v1.GetServerSocketsResponse.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int SOCKET_REF_FIELD_NUMBER = 1;
+  private java.util.List<io.grpc.channelz.v1.SocketRef> socketRef_;
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.SocketRef> getSocketRefList() {
+    return socketRef_;
+  }
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getSocketRefOrBuilderList() {
+    return socketRef_;
+  }
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  public int getSocketRefCount() {
+    return socketRef_.size();
+  }
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.SocketRef getSocketRef(int index) {
+    return socketRef_.get(index);
+  }
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.SocketRefOrBuilder getSocketRefOrBuilder(
+      int index) {
+    return socketRef_.get(index);
+  }
+
+  public static final int END_FIELD_NUMBER = 2;
+  private boolean end_;
+  /**
+   * <pre>
+   * If set, indicates that the list of sockets is the final list.  Requesting
+   * more sockets will only return more if they are created after this RPC
+   * completes.
+   * </pre>
+   *
+   * <code>bool end = 2;</code>
+   */
+  public boolean getEnd() {
+    return end_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    for (int i = 0; i < socketRef_.size(); i++) {
+      output.writeMessage(1, socketRef_.get(i));
+    }
+    if (end_ != false) {
+      output.writeBool(2, end_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    for (int i = 0; i < socketRef_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, socketRef_.get(i));
+    }
+    if (end_ != false) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeBoolSize(2, end_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetServerSocketsResponse)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetServerSocketsResponse other = (io.grpc.channelz.v1.GetServerSocketsResponse) obj;
+
+    boolean result = true;
+    result = result && getSocketRefList()
+        .equals(other.getSocketRefList());
+    result = result && (getEnd()
+        == other.getEnd());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (getSocketRefCount() > 0) {
+      hash = (37 * hash) + SOCKET_REF_FIELD_NUMBER;
+      hash = (53 * hash) + getSocketRefList().hashCode();
+    }
+    hash = (37 * hash) + END_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+        getEnd());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServerSocketsResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetServerSocketsResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetServerSocketsResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetServerSocketsResponse)
+      io.grpc.channelz.v1.GetServerSocketsResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetServerSocketsResponse.class, io.grpc.channelz.v1.GetServerSocketsResponse.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetServerSocketsResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getSocketRefFieldBuilder();
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (socketRefBuilder_ == null) {
+        socketRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        socketRefBuilder_.clear();
+      }
+      end_ = false;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServerSocketsResponse_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetServerSocketsResponse getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetServerSocketsResponse.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetServerSocketsResponse build() {
+      io.grpc.channelz.v1.GetServerSocketsResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetServerSocketsResponse buildPartial() {
+      io.grpc.channelz.v1.GetServerSocketsResponse result = new io.grpc.channelz.v1.GetServerSocketsResponse(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (socketRefBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          socketRef_ = java.util.Collections.unmodifiableList(socketRef_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.socketRef_ = socketRef_;
+      } else {
+        result.socketRef_ = socketRefBuilder_.build();
+      }
+      result.end_ = end_;
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetServerSocketsResponse) {
+        return mergeFrom((io.grpc.channelz.v1.GetServerSocketsResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetServerSocketsResponse other) {
+      if (other == io.grpc.channelz.v1.GetServerSocketsResponse.getDefaultInstance()) return this;
+      if (socketRefBuilder_ == null) {
+        if (!other.socketRef_.isEmpty()) {
+          if (socketRef_.isEmpty()) {
+            socketRef_ = other.socketRef_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureSocketRefIsMutable();
+            socketRef_.addAll(other.socketRef_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.socketRef_.isEmpty()) {
+          if (socketRefBuilder_.isEmpty()) {
+            socketRefBuilder_.dispose();
+            socketRefBuilder_ = null;
+            socketRef_ = other.socketRef_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            socketRefBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getSocketRefFieldBuilder() : null;
+          } else {
+            socketRefBuilder_.addAllMessages(other.socketRef_);
+          }
+        }
+      }
+      if (other.getEnd() != false) {
+        setEnd(other.getEnd());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetServerSocketsResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetServerSocketsResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private java.util.List<io.grpc.channelz.v1.SocketRef> socketRef_ =
+      java.util.Collections.emptyList();
+    private void ensureSocketRefIsMutable() {
+      if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        socketRef_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>(socketRef_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> socketRefBuilder_;
+
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef> getSocketRefList() {
+      if (socketRefBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(socketRef_);
+      } else {
+        return socketRefBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public int getSocketRefCount() {
+      if (socketRefBuilder_ == null) {
+        return socketRef_.size();
+      } else {
+        return socketRefBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef getSocketRef(int index) {
+      if (socketRefBuilder_ == null) {
+        return socketRef_.get(index);
+      } else {
+        return socketRefBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder setSocketRef(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (socketRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketRefIsMutable();
+        socketRef_.set(index, value);
+        onChanged();
+      } else {
+        socketRefBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder setSocketRef(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketRefBuilder_ == null) {
+        ensureSocketRefIsMutable();
+        socketRef_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        socketRefBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder addSocketRef(io.grpc.channelz.v1.SocketRef value) {
+      if (socketRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketRefIsMutable();
+        socketRef_.add(value);
+        onChanged();
+      } else {
+        socketRefBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder addSocketRef(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (socketRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketRefIsMutable();
+        socketRef_.add(index, value);
+        onChanged();
+      } else {
+        socketRefBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder addSocketRef(
+        io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketRefBuilder_ == null) {
+        ensureSocketRefIsMutable();
+        socketRef_.add(builderForValue.build());
+        onChanged();
+      } else {
+        socketRefBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder addSocketRef(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketRefBuilder_ == null) {
+        ensureSocketRefIsMutable();
+        socketRef_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        socketRefBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder addAllSocketRef(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.SocketRef> values) {
+      if (socketRefBuilder_ == null) {
+        ensureSocketRefIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, socketRef_);
+        onChanged();
+      } else {
+        socketRefBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder clearSocketRef() {
+      if (socketRefBuilder_ == null) {
+        socketRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        socketRefBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public Builder removeSocketRef(int index) {
+      if (socketRefBuilder_ == null) {
+        ensureSocketRefIsMutable();
+        socketRef_.remove(index);
+        onChanged();
+      } else {
+        socketRefBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder getSocketRefBuilder(
+        int index) {
+      return getSocketRefFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRefOrBuilder getSocketRefOrBuilder(
+        int index) {
+      if (socketRefBuilder_ == null) {
+        return socketRef_.get(index);  } else {
+        return socketRefBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+         getSocketRefOrBuilderList() {
+      if (socketRefBuilder_ != null) {
+        return socketRefBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(socketRef_);
+      }
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addSocketRefBuilder() {
+      return getSocketRefFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addSocketRefBuilder(
+        int index) {
+      return getSocketRefFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * list of socket refs that the connection detail service knows about.  Sorted in
+     * ascending socket_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef.Builder> 
+         getSocketRefBuilderList() {
+      return getSocketRefFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> 
+        getSocketRefFieldBuilder() {
+      if (socketRefBuilder_ == null) {
+        socketRefBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder>(
+                socketRef_,
+                ((bitField0_ & 0x00000001) == 0x00000001),
+                getParentForChildren(),
+                isClean());
+        socketRef_ = null;
+      }
+      return socketRefBuilder_;
+    }
+
+    private boolean end_ ;
+    /**
+     * <pre>
+     * If set, indicates that the list of sockets is the final list.  Requesting
+     * more sockets will only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public boolean getEnd() {
+      return end_;
+    }
+    /**
+     * <pre>
+     * If set, indicates that the list of sockets is the final list.  Requesting
+     * more sockets will only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public Builder setEnd(boolean value) {
+      
+      end_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * If set, indicates that the list of sockets is the final list.  Requesting
+     * more sockets will only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public Builder clearEnd() {
+      
+      end_ = false;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetServerSocketsResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetServerSocketsResponse)
+  private static final io.grpc.channelz.v1.GetServerSocketsResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetServerSocketsResponse();
+  }
+
+  public static io.grpc.channelz.v1.GetServerSocketsResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetServerSocketsResponse>
+      PARSER = new com.google.protobuf.AbstractParser<GetServerSocketsResponse>() {
+    public GetServerSocketsResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetServerSocketsResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetServerSocketsResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetServerSocketsResponse> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetServerSocketsResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsResponseOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsResponseOrBuilder.java
new file mode 100644
index 0000000..0d618f8
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServerSocketsResponseOrBuilder.java
@@ -0,0 +1,69 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetServerSocketsResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetServerSocketsResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.SocketRef> 
+      getSocketRefList();
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  io.grpc.channelz.v1.SocketRef getSocketRef(int index);
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  int getSocketRefCount();
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getSocketRefOrBuilderList();
+  /**
+   * <pre>
+   * list of socket refs that the connection detail service knows about.  Sorted in
+   * ascending socket_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket_ref = 1;</code>
+   */
+  io.grpc.channelz.v1.SocketRefOrBuilder getSocketRefOrBuilder(
+      int index);
+
+  /**
+   * <pre>
+   * If set, indicates that the list of sockets is the final list.  Requesting
+   * more sockets will only return more if they are created after this RPC
+   * completes.
+   * </pre>
+   *
+   * <code>bool end = 2;</code>
+   */
+  boolean getEnd();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServersRequest.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersRequest.java
new file mode 100644
index 0000000..e516026
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersRequest.java
@@ -0,0 +1,468 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetServersRequest}
+ */
+public  final class GetServersRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetServersRequest)
+    GetServersRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetServersRequest.newBuilder() to construct.
+  private GetServersRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetServersRequest() {
+    startServerId_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetServersRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            startServerId_ = input.readInt64();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersRequest_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetServersRequest.class, io.grpc.channelz.v1.GetServersRequest.Builder.class);
+  }
+
+  public static final int START_SERVER_ID_FIELD_NUMBER = 1;
+  private long startServerId_;
+  /**
+   * <pre>
+   * start_server_id indicates that only servers at or above this id should be
+   * included in the results.
+   * </pre>
+   *
+   * <code>int64 start_server_id = 1;</code>
+   */
+  public long getStartServerId() {
+    return startServerId_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (startServerId_ != 0L) {
+      output.writeInt64(1, startServerId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (startServerId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, startServerId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetServersRequest)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetServersRequest other = (io.grpc.channelz.v1.GetServersRequest) obj;
+
+    boolean result = true;
+    result = result && (getStartServerId()
+        == other.getStartServerId());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + START_SERVER_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getStartServerId());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServersRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetServersRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetServersRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetServersRequest)
+      io.grpc.channelz.v1.GetServersRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetServersRequest.class, io.grpc.channelz.v1.GetServersRequest.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetServersRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      startServerId_ = 0L;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersRequest_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetServersRequest getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetServersRequest.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetServersRequest build() {
+      io.grpc.channelz.v1.GetServersRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetServersRequest buildPartial() {
+      io.grpc.channelz.v1.GetServersRequest result = new io.grpc.channelz.v1.GetServersRequest(this);
+      result.startServerId_ = startServerId_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetServersRequest) {
+        return mergeFrom((io.grpc.channelz.v1.GetServersRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetServersRequest other) {
+      if (other == io.grpc.channelz.v1.GetServersRequest.getDefaultInstance()) return this;
+      if (other.getStartServerId() != 0L) {
+        setStartServerId(other.getStartServerId());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetServersRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetServersRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long startServerId_ ;
+    /**
+     * <pre>
+     * start_server_id indicates that only servers at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_server_id = 1;</code>
+     */
+    public long getStartServerId() {
+      return startServerId_;
+    }
+    /**
+     * <pre>
+     * start_server_id indicates that only servers at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_server_id = 1;</code>
+     */
+    public Builder setStartServerId(long value) {
+      
+      startServerId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * start_server_id indicates that only servers at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_server_id = 1;</code>
+     */
+    public Builder clearStartServerId() {
+      
+      startServerId_ = 0L;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetServersRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetServersRequest)
+  private static final io.grpc.channelz.v1.GetServersRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetServersRequest();
+  }
+
+  public static io.grpc.channelz.v1.GetServersRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetServersRequest>
+      PARSER = new com.google.protobuf.AbstractParser<GetServersRequest>() {
+    public GetServersRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetServersRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetServersRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetServersRequest> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetServersRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServersRequestOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersRequestOrBuilder.java
new file mode 100644
index 0000000..74e7299
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersRequestOrBuilder.java
@@ -0,0 +1,19 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetServersRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetServersRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * start_server_id indicates that only servers at or above this id should be
+   * included in the results.
+   * </pre>
+   *
+   * <code>int64 start_server_id = 1;</code>
+   */
+  long getStartServerId();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServersResponse.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersResponse.java
new file mode 100644
index 0000000..1ba2588
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersResponse.java
@@ -0,0 +1,935 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetServersResponse}
+ */
+public  final class GetServersResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetServersResponse)
+    GetServersResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetServersResponse.newBuilder() to construct.
+  private GetServersResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetServersResponse() {
+    server_ = java.util.Collections.emptyList();
+    end_ = false;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetServersResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              server_ = new java.util.ArrayList<io.grpc.channelz.v1.Server>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            server_.add(
+                input.readMessage(io.grpc.channelz.v1.Server.parser(), extensionRegistry));
+            break;
+          }
+          case 16: {
+
+            end_ = input.readBool();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        server_ = java.util.Collections.unmodifiableList(server_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersResponse_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetServersResponse.class, io.grpc.channelz.v1.GetServersResponse.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int SERVER_FIELD_NUMBER = 1;
+  private java.util.List<io.grpc.channelz.v1.Server> server_;
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.Server> getServerList() {
+    return server_;
+  }
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.ServerOrBuilder> 
+      getServerOrBuilderList() {
+    return server_;
+  }
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  public int getServerCount() {
+    return server_.size();
+  }
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  public io.grpc.channelz.v1.Server getServer(int index) {
+    return server_.get(index);
+  }
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  public io.grpc.channelz.v1.ServerOrBuilder getServerOrBuilder(
+      int index) {
+    return server_.get(index);
+  }
+
+  public static final int END_FIELD_NUMBER = 2;
+  private boolean end_;
+  /**
+   * <pre>
+   * If set, indicates that the list of servers is the final list.  Requesting
+   * more servers will only return more if they are created after this RPC
+   * completes.
+   * </pre>
+   *
+   * <code>bool end = 2;</code>
+   */
+  public boolean getEnd() {
+    return end_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    for (int i = 0; i < server_.size(); i++) {
+      output.writeMessage(1, server_.get(i));
+    }
+    if (end_ != false) {
+      output.writeBool(2, end_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    for (int i = 0; i < server_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, server_.get(i));
+    }
+    if (end_ != false) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeBoolSize(2, end_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetServersResponse)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetServersResponse other = (io.grpc.channelz.v1.GetServersResponse) obj;
+
+    boolean result = true;
+    result = result && getServerList()
+        .equals(other.getServerList());
+    result = result && (getEnd()
+        == other.getEnd());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (getServerCount() > 0) {
+      hash = (37 * hash) + SERVER_FIELD_NUMBER;
+      hash = (53 * hash) + getServerList().hashCode();
+    }
+    hash = (37 * hash) + END_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+        getEnd());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetServersResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetServersResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetServersResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetServersResponse)
+      io.grpc.channelz.v1.GetServersResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetServersResponse.class, io.grpc.channelz.v1.GetServersResponse.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetServersResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getServerFieldBuilder();
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (serverBuilder_ == null) {
+        server_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        serverBuilder_.clear();
+      }
+      end_ = false;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetServersResponse_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetServersResponse getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetServersResponse.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetServersResponse build() {
+      io.grpc.channelz.v1.GetServersResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetServersResponse buildPartial() {
+      io.grpc.channelz.v1.GetServersResponse result = new io.grpc.channelz.v1.GetServersResponse(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (serverBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          server_ = java.util.Collections.unmodifiableList(server_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.server_ = server_;
+      } else {
+        result.server_ = serverBuilder_.build();
+      }
+      result.end_ = end_;
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetServersResponse) {
+        return mergeFrom((io.grpc.channelz.v1.GetServersResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetServersResponse other) {
+      if (other == io.grpc.channelz.v1.GetServersResponse.getDefaultInstance()) return this;
+      if (serverBuilder_ == null) {
+        if (!other.server_.isEmpty()) {
+          if (server_.isEmpty()) {
+            server_ = other.server_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureServerIsMutable();
+            server_.addAll(other.server_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.server_.isEmpty()) {
+          if (serverBuilder_.isEmpty()) {
+            serverBuilder_.dispose();
+            serverBuilder_ = null;
+            server_ = other.server_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            serverBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getServerFieldBuilder() : null;
+          } else {
+            serverBuilder_.addAllMessages(other.server_);
+          }
+        }
+      }
+      if (other.getEnd() != false) {
+        setEnd(other.getEnd());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetServersResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetServersResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private java.util.List<io.grpc.channelz.v1.Server> server_ =
+      java.util.Collections.emptyList();
+    private void ensureServerIsMutable() {
+      if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        server_ = new java.util.ArrayList<io.grpc.channelz.v1.Server>(server_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.Server, io.grpc.channelz.v1.Server.Builder, io.grpc.channelz.v1.ServerOrBuilder> serverBuilder_;
+
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.Server> getServerList() {
+      if (serverBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(server_);
+      } else {
+        return serverBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public int getServerCount() {
+      if (serverBuilder_ == null) {
+        return server_.size();
+      } else {
+        return serverBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public io.grpc.channelz.v1.Server getServer(int index) {
+      if (serverBuilder_ == null) {
+        return server_.get(index);
+      } else {
+        return serverBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder setServer(
+        int index, io.grpc.channelz.v1.Server value) {
+      if (serverBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureServerIsMutable();
+        server_.set(index, value);
+        onChanged();
+      } else {
+        serverBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder setServer(
+        int index, io.grpc.channelz.v1.Server.Builder builderForValue) {
+      if (serverBuilder_ == null) {
+        ensureServerIsMutable();
+        server_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        serverBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder addServer(io.grpc.channelz.v1.Server value) {
+      if (serverBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureServerIsMutable();
+        server_.add(value);
+        onChanged();
+      } else {
+        serverBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder addServer(
+        int index, io.grpc.channelz.v1.Server value) {
+      if (serverBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureServerIsMutable();
+        server_.add(index, value);
+        onChanged();
+      } else {
+        serverBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder addServer(
+        io.grpc.channelz.v1.Server.Builder builderForValue) {
+      if (serverBuilder_ == null) {
+        ensureServerIsMutable();
+        server_.add(builderForValue.build());
+        onChanged();
+      } else {
+        serverBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder addServer(
+        int index, io.grpc.channelz.v1.Server.Builder builderForValue) {
+      if (serverBuilder_ == null) {
+        ensureServerIsMutable();
+        server_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        serverBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder addAllServer(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.Server> values) {
+      if (serverBuilder_ == null) {
+        ensureServerIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, server_);
+        onChanged();
+      } else {
+        serverBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder clearServer() {
+      if (serverBuilder_ == null) {
+        server_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        serverBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public Builder removeServer(int index) {
+      if (serverBuilder_ == null) {
+        ensureServerIsMutable();
+        server_.remove(index);
+        onChanged();
+      } else {
+        serverBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public io.grpc.channelz.v1.Server.Builder getServerBuilder(
+        int index) {
+      return getServerFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public io.grpc.channelz.v1.ServerOrBuilder getServerOrBuilder(
+        int index) {
+      if (serverBuilder_ == null) {
+        return server_.get(index);  } else {
+        return serverBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.ServerOrBuilder> 
+         getServerOrBuilderList() {
+      if (serverBuilder_ != null) {
+        return serverBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(server_);
+      }
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public io.grpc.channelz.v1.Server.Builder addServerBuilder() {
+      return getServerFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.Server.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public io.grpc.channelz.v1.Server.Builder addServerBuilder(
+        int index) {
+      return getServerFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.Server.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * list of servers that the connection detail service knows about.  Sorted in
+     * ascending server_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Server server = 1;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.Server.Builder> 
+         getServerBuilderList() {
+      return getServerFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.Server, io.grpc.channelz.v1.Server.Builder, io.grpc.channelz.v1.ServerOrBuilder> 
+        getServerFieldBuilder() {
+      if (serverBuilder_ == null) {
+        serverBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.Server, io.grpc.channelz.v1.Server.Builder, io.grpc.channelz.v1.ServerOrBuilder>(
+                server_,
+                ((bitField0_ & 0x00000001) == 0x00000001),
+                getParentForChildren(),
+                isClean());
+        server_ = null;
+      }
+      return serverBuilder_;
+    }
+
+    private boolean end_ ;
+    /**
+     * <pre>
+     * If set, indicates that the list of servers is the final list.  Requesting
+     * more servers will only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public boolean getEnd() {
+      return end_;
+    }
+    /**
+     * <pre>
+     * If set, indicates that the list of servers is the final list.  Requesting
+     * more servers will only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public Builder setEnd(boolean value) {
+      
+      end_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * If set, indicates that the list of servers is the final list.  Requesting
+     * more servers will only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public Builder clearEnd() {
+      
+      end_ = false;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetServersResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetServersResponse)
+  private static final io.grpc.channelz.v1.GetServersResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetServersResponse();
+  }
+
+  public static io.grpc.channelz.v1.GetServersResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetServersResponse>
+      PARSER = new com.google.protobuf.AbstractParser<GetServersResponse>() {
+    public GetServersResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetServersResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetServersResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetServersResponse> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetServersResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetServersResponseOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersResponseOrBuilder.java
new file mode 100644
index 0000000..d9db0d0
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetServersResponseOrBuilder.java
@@ -0,0 +1,69 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetServersResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetServersResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.Server> 
+      getServerList();
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  io.grpc.channelz.v1.Server getServer(int index);
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  int getServerCount();
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.ServerOrBuilder> 
+      getServerOrBuilderList();
+  /**
+   * <pre>
+   * list of servers that the connection detail service knows about.  Sorted in
+   * ascending server_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Server server = 1;</code>
+   */
+  io.grpc.channelz.v1.ServerOrBuilder getServerOrBuilder(
+      int index);
+
+  /**
+   * <pre>
+   * If set, indicates that the list of servers is the final list.  Requesting
+   * more servers will only return more if they are created after this RPC
+   * completes.
+   * </pre>
+   *
+   * <code>bool end = 2;</code>
+   */
+  boolean getEnd();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketRequest.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketRequest.java
new file mode 100644
index 0000000..956523b
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketRequest.java
@@ -0,0 +1,448 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetSocketRequest}
+ */
+public  final class GetSocketRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetSocketRequest)
+    GetSocketRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetSocketRequest.newBuilder() to construct.
+  private GetSocketRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetSocketRequest() {
+    socketId_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetSocketRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            socketId_ = input.readInt64();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketRequest_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetSocketRequest.class, io.grpc.channelz.v1.GetSocketRequest.Builder.class);
+  }
+
+  public static final int SOCKET_ID_FIELD_NUMBER = 1;
+  private long socketId_;
+  /**
+   * <code>int64 socket_id = 1;</code>
+   */
+  public long getSocketId() {
+    return socketId_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (socketId_ != 0L) {
+      output.writeInt64(1, socketId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (socketId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, socketId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetSocketRequest)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetSocketRequest other = (io.grpc.channelz.v1.GetSocketRequest) obj;
+
+    boolean result = true;
+    result = result && (getSocketId()
+        == other.getSocketId());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + SOCKET_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getSocketId());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSocketRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetSocketRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetSocketRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetSocketRequest)
+      io.grpc.channelz.v1.GetSocketRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetSocketRequest.class, io.grpc.channelz.v1.GetSocketRequest.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetSocketRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      socketId_ = 0L;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketRequest_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetSocketRequest getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetSocketRequest.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetSocketRequest build() {
+      io.grpc.channelz.v1.GetSocketRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetSocketRequest buildPartial() {
+      io.grpc.channelz.v1.GetSocketRequest result = new io.grpc.channelz.v1.GetSocketRequest(this);
+      result.socketId_ = socketId_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetSocketRequest) {
+        return mergeFrom((io.grpc.channelz.v1.GetSocketRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetSocketRequest other) {
+      if (other == io.grpc.channelz.v1.GetSocketRequest.getDefaultInstance()) return this;
+      if (other.getSocketId() != 0L) {
+        setSocketId(other.getSocketId());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetSocketRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetSocketRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long socketId_ ;
+    /**
+     * <code>int64 socket_id = 1;</code>
+     */
+    public long getSocketId() {
+      return socketId_;
+    }
+    /**
+     * <code>int64 socket_id = 1;</code>
+     */
+    public Builder setSocketId(long value) {
+      
+      socketId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 socket_id = 1;</code>
+     */
+    public Builder clearSocketId() {
+      
+      socketId_ = 0L;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetSocketRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetSocketRequest)
+  private static final io.grpc.channelz.v1.GetSocketRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetSocketRequest();
+  }
+
+  public static io.grpc.channelz.v1.GetSocketRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetSocketRequest>
+      PARSER = new com.google.protobuf.AbstractParser<GetSocketRequest>() {
+    public GetSocketRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetSocketRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetSocketRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetSocketRequest> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetSocketRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketRequestOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketRequestOrBuilder.java
new file mode 100644
index 0000000..6c09e8f
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketRequestOrBuilder.java
@@ -0,0 +1,14 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetSocketRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetSocketRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 socket_id = 1;</code>
+   */
+  long getSocketId();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketResponse.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketResponse.java
new file mode 100644
index 0000000..7e98024
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketResponse.java
@@ -0,0 +1,570 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetSocketResponse}
+ */
+public  final class GetSocketResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetSocketResponse)
+    GetSocketResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetSocketResponse.newBuilder() to construct.
+  private GetSocketResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetSocketResponse() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetSocketResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.Socket.Builder subBuilder = null;
+            if (socket_ != null) {
+              subBuilder = socket_.toBuilder();
+            }
+            socket_ = input.readMessage(io.grpc.channelz.v1.Socket.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(socket_);
+              socket_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketResponse_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetSocketResponse.class, io.grpc.channelz.v1.GetSocketResponse.Builder.class);
+  }
+
+  public static final int SOCKET_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.Socket socket_;
+  /**
+   * <code>.grpc.channelz.Socket socket = 1;</code>
+   */
+  public boolean hasSocket() {
+    return socket_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.Socket socket = 1;</code>
+   */
+  public io.grpc.channelz.v1.Socket getSocket() {
+    return socket_ == null ? io.grpc.channelz.v1.Socket.getDefaultInstance() : socket_;
+  }
+  /**
+   * <code>.grpc.channelz.Socket socket = 1;</code>
+   */
+  public io.grpc.channelz.v1.SocketOrBuilder getSocketOrBuilder() {
+    return getSocket();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (socket_ != null) {
+      output.writeMessage(1, getSocket());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (socket_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getSocket());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetSocketResponse)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetSocketResponse other = (io.grpc.channelz.v1.GetSocketResponse) obj;
+
+    boolean result = true;
+    result = result && (hasSocket() == other.hasSocket());
+    if (hasSocket()) {
+      result = result && getSocket()
+          .equals(other.getSocket());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasSocket()) {
+      hash = (37 * hash) + SOCKET_FIELD_NUMBER;
+      hash = (53 * hash) + getSocket().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSocketResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetSocketResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetSocketResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetSocketResponse)
+      io.grpc.channelz.v1.GetSocketResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetSocketResponse.class, io.grpc.channelz.v1.GetSocketResponse.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetSocketResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (socketBuilder_ == null) {
+        socket_ = null;
+      } else {
+        socket_ = null;
+        socketBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSocketResponse_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetSocketResponse getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetSocketResponse.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetSocketResponse build() {
+      io.grpc.channelz.v1.GetSocketResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetSocketResponse buildPartial() {
+      io.grpc.channelz.v1.GetSocketResponse result = new io.grpc.channelz.v1.GetSocketResponse(this);
+      if (socketBuilder_ == null) {
+        result.socket_ = socket_;
+      } else {
+        result.socket_ = socketBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetSocketResponse) {
+        return mergeFrom((io.grpc.channelz.v1.GetSocketResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetSocketResponse other) {
+      if (other == io.grpc.channelz.v1.GetSocketResponse.getDefaultInstance()) return this;
+      if (other.hasSocket()) {
+        mergeSocket(other.getSocket());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetSocketResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetSocketResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.grpc.channelz.v1.Socket socket_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Socket, io.grpc.channelz.v1.Socket.Builder, io.grpc.channelz.v1.SocketOrBuilder> socketBuilder_;
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public boolean hasSocket() {
+      return socketBuilder_ != null || socket_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public io.grpc.channelz.v1.Socket getSocket() {
+      if (socketBuilder_ == null) {
+        return socket_ == null ? io.grpc.channelz.v1.Socket.getDefaultInstance() : socket_;
+      } else {
+        return socketBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public Builder setSocket(io.grpc.channelz.v1.Socket value) {
+      if (socketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        socket_ = value;
+        onChanged();
+      } else {
+        socketBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public Builder setSocket(
+        io.grpc.channelz.v1.Socket.Builder builderForValue) {
+      if (socketBuilder_ == null) {
+        socket_ = builderForValue.build();
+        onChanged();
+      } else {
+        socketBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public Builder mergeSocket(io.grpc.channelz.v1.Socket value) {
+      if (socketBuilder_ == null) {
+        if (socket_ != null) {
+          socket_ =
+            io.grpc.channelz.v1.Socket.newBuilder(socket_).mergeFrom(value).buildPartial();
+        } else {
+          socket_ = value;
+        }
+        onChanged();
+      } else {
+        socketBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public Builder clearSocket() {
+      if (socketBuilder_ == null) {
+        socket_ = null;
+        onChanged();
+      } else {
+        socket_ = null;
+        socketBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public io.grpc.channelz.v1.Socket.Builder getSocketBuilder() {
+      
+      onChanged();
+      return getSocketFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketOrBuilder getSocketOrBuilder() {
+      if (socketBuilder_ != null) {
+        return socketBuilder_.getMessageOrBuilder();
+      } else {
+        return socket_ == null ?
+            io.grpc.channelz.v1.Socket.getDefaultInstance() : socket_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Socket socket = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Socket, io.grpc.channelz.v1.Socket.Builder, io.grpc.channelz.v1.SocketOrBuilder> 
+        getSocketFieldBuilder() {
+      if (socketBuilder_ == null) {
+        socketBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Socket, io.grpc.channelz.v1.Socket.Builder, io.grpc.channelz.v1.SocketOrBuilder>(
+                getSocket(),
+                getParentForChildren(),
+                isClean());
+        socket_ = null;
+      }
+      return socketBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetSocketResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetSocketResponse)
+  private static final io.grpc.channelz.v1.GetSocketResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetSocketResponse();
+  }
+
+  public static io.grpc.channelz.v1.GetSocketResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetSocketResponse>
+      PARSER = new com.google.protobuf.AbstractParser<GetSocketResponse>() {
+    public GetSocketResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetSocketResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetSocketResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetSocketResponse> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetSocketResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketResponseOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketResponseOrBuilder.java
new file mode 100644
index 0000000..3767b76
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSocketResponseOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetSocketResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetSocketResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.Socket socket = 1;</code>
+   */
+  boolean hasSocket();
+  /**
+   * <code>.grpc.channelz.Socket socket = 1;</code>
+   */
+  io.grpc.channelz.v1.Socket getSocket();
+  /**
+   * <code>.grpc.channelz.Socket socket = 1;</code>
+   */
+  io.grpc.channelz.v1.SocketOrBuilder getSocketOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelRequest.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelRequest.java
new file mode 100644
index 0000000..130371b
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelRequest.java
@@ -0,0 +1,448 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetSubchannelRequest}
+ */
+public  final class GetSubchannelRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetSubchannelRequest)
+    GetSubchannelRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetSubchannelRequest.newBuilder() to construct.
+  private GetSubchannelRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetSubchannelRequest() {
+    subchannelId_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetSubchannelRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            subchannelId_ = input.readInt64();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelRequest_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetSubchannelRequest.class, io.grpc.channelz.v1.GetSubchannelRequest.Builder.class);
+  }
+
+  public static final int SUBCHANNEL_ID_FIELD_NUMBER = 1;
+  private long subchannelId_;
+  /**
+   * <code>int64 subchannel_id = 1;</code>
+   */
+  public long getSubchannelId() {
+    return subchannelId_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (subchannelId_ != 0L) {
+      output.writeInt64(1, subchannelId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (subchannelId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, subchannelId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetSubchannelRequest)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetSubchannelRequest other = (io.grpc.channelz.v1.GetSubchannelRequest) obj;
+
+    boolean result = true;
+    result = result && (getSubchannelId()
+        == other.getSubchannelId());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + SUBCHANNEL_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getSubchannelId());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetSubchannelRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetSubchannelRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetSubchannelRequest)
+      io.grpc.channelz.v1.GetSubchannelRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetSubchannelRequest.class, io.grpc.channelz.v1.GetSubchannelRequest.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetSubchannelRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      subchannelId_ = 0L;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelRequest_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetSubchannelRequest getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetSubchannelRequest.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetSubchannelRequest build() {
+      io.grpc.channelz.v1.GetSubchannelRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetSubchannelRequest buildPartial() {
+      io.grpc.channelz.v1.GetSubchannelRequest result = new io.grpc.channelz.v1.GetSubchannelRequest(this);
+      result.subchannelId_ = subchannelId_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetSubchannelRequest) {
+        return mergeFrom((io.grpc.channelz.v1.GetSubchannelRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetSubchannelRequest other) {
+      if (other == io.grpc.channelz.v1.GetSubchannelRequest.getDefaultInstance()) return this;
+      if (other.getSubchannelId() != 0L) {
+        setSubchannelId(other.getSubchannelId());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetSubchannelRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetSubchannelRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long subchannelId_ ;
+    /**
+     * <code>int64 subchannel_id = 1;</code>
+     */
+    public long getSubchannelId() {
+      return subchannelId_;
+    }
+    /**
+     * <code>int64 subchannel_id = 1;</code>
+     */
+    public Builder setSubchannelId(long value) {
+      
+      subchannelId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 subchannel_id = 1;</code>
+     */
+    public Builder clearSubchannelId() {
+      
+      subchannelId_ = 0L;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetSubchannelRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetSubchannelRequest)
+  private static final io.grpc.channelz.v1.GetSubchannelRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetSubchannelRequest();
+  }
+
+  public static io.grpc.channelz.v1.GetSubchannelRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetSubchannelRequest>
+      PARSER = new com.google.protobuf.AbstractParser<GetSubchannelRequest>() {
+    public GetSubchannelRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetSubchannelRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetSubchannelRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetSubchannelRequest> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetSubchannelRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelRequestOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelRequestOrBuilder.java
new file mode 100644
index 0000000..1562028
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelRequestOrBuilder.java
@@ -0,0 +1,14 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetSubchannelRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetSubchannelRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 subchannel_id = 1;</code>
+   */
+  long getSubchannelId();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelResponse.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelResponse.java
new file mode 100644
index 0000000..e4a3ea0
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelResponse.java
@@ -0,0 +1,570 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetSubchannelResponse}
+ */
+public  final class GetSubchannelResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetSubchannelResponse)
+    GetSubchannelResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetSubchannelResponse.newBuilder() to construct.
+  private GetSubchannelResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetSubchannelResponse() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetSubchannelResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.Subchannel.Builder subBuilder = null;
+            if (subchannel_ != null) {
+              subBuilder = subchannel_.toBuilder();
+            }
+            subchannel_ = input.readMessage(io.grpc.channelz.v1.Subchannel.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(subchannel_);
+              subchannel_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelResponse_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetSubchannelResponse.class, io.grpc.channelz.v1.GetSubchannelResponse.Builder.class);
+  }
+
+  public static final int SUBCHANNEL_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.Subchannel subchannel_;
+  /**
+   * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+   */
+  public boolean hasSubchannel() {
+    return subchannel_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+   */
+  public io.grpc.channelz.v1.Subchannel getSubchannel() {
+    return subchannel_ == null ? io.grpc.channelz.v1.Subchannel.getDefaultInstance() : subchannel_;
+  }
+  /**
+   * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+   */
+  public io.grpc.channelz.v1.SubchannelOrBuilder getSubchannelOrBuilder() {
+    return getSubchannel();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (subchannel_ != null) {
+      output.writeMessage(1, getSubchannel());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (subchannel_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getSubchannel());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetSubchannelResponse)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetSubchannelResponse other = (io.grpc.channelz.v1.GetSubchannelResponse) obj;
+
+    boolean result = true;
+    result = result && (hasSubchannel() == other.hasSubchannel());
+    if (hasSubchannel()) {
+      result = result && getSubchannel()
+          .equals(other.getSubchannel());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasSubchannel()) {
+      hash = (37 * hash) + SUBCHANNEL_FIELD_NUMBER;
+      hash = (53 * hash) + getSubchannel().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetSubchannelResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetSubchannelResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetSubchannelResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetSubchannelResponse)
+      io.grpc.channelz.v1.GetSubchannelResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetSubchannelResponse.class, io.grpc.channelz.v1.GetSubchannelResponse.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetSubchannelResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (subchannelBuilder_ == null) {
+        subchannel_ = null;
+      } else {
+        subchannel_ = null;
+        subchannelBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetSubchannelResponse_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetSubchannelResponse getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetSubchannelResponse.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetSubchannelResponse build() {
+      io.grpc.channelz.v1.GetSubchannelResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetSubchannelResponse buildPartial() {
+      io.grpc.channelz.v1.GetSubchannelResponse result = new io.grpc.channelz.v1.GetSubchannelResponse(this);
+      if (subchannelBuilder_ == null) {
+        result.subchannel_ = subchannel_;
+      } else {
+        result.subchannel_ = subchannelBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetSubchannelResponse) {
+        return mergeFrom((io.grpc.channelz.v1.GetSubchannelResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetSubchannelResponse other) {
+      if (other == io.grpc.channelz.v1.GetSubchannelResponse.getDefaultInstance()) return this;
+      if (other.hasSubchannel()) {
+        mergeSubchannel(other.getSubchannel());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetSubchannelResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetSubchannelResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.grpc.channelz.v1.Subchannel subchannel_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Subchannel, io.grpc.channelz.v1.Subchannel.Builder, io.grpc.channelz.v1.SubchannelOrBuilder> subchannelBuilder_;
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public boolean hasSubchannel() {
+      return subchannelBuilder_ != null || subchannel_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Subchannel getSubchannel() {
+      if (subchannelBuilder_ == null) {
+        return subchannel_ == null ? io.grpc.channelz.v1.Subchannel.getDefaultInstance() : subchannel_;
+      } else {
+        return subchannelBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public Builder setSubchannel(io.grpc.channelz.v1.Subchannel value) {
+      if (subchannelBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        subchannel_ = value;
+        onChanged();
+      } else {
+        subchannelBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public Builder setSubchannel(
+        io.grpc.channelz.v1.Subchannel.Builder builderForValue) {
+      if (subchannelBuilder_ == null) {
+        subchannel_ = builderForValue.build();
+        onChanged();
+      } else {
+        subchannelBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public Builder mergeSubchannel(io.grpc.channelz.v1.Subchannel value) {
+      if (subchannelBuilder_ == null) {
+        if (subchannel_ != null) {
+          subchannel_ =
+            io.grpc.channelz.v1.Subchannel.newBuilder(subchannel_).mergeFrom(value).buildPartial();
+        } else {
+          subchannel_ = value;
+        }
+        onChanged();
+      } else {
+        subchannelBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public Builder clearSubchannel() {
+      if (subchannelBuilder_ == null) {
+        subchannel_ = null;
+        onChanged();
+      } else {
+        subchannel_ = null;
+        subchannelBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Subchannel.Builder getSubchannelBuilder() {
+      
+      onChanged();
+      return getSubchannelFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelOrBuilder getSubchannelOrBuilder() {
+      if (subchannelBuilder_ != null) {
+        return subchannelBuilder_.getMessageOrBuilder();
+      } else {
+        return subchannel_ == null ?
+            io.grpc.channelz.v1.Subchannel.getDefaultInstance() : subchannel_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Subchannel, io.grpc.channelz.v1.Subchannel.Builder, io.grpc.channelz.v1.SubchannelOrBuilder> 
+        getSubchannelFieldBuilder() {
+      if (subchannelBuilder_ == null) {
+        subchannelBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Subchannel, io.grpc.channelz.v1.Subchannel.Builder, io.grpc.channelz.v1.SubchannelOrBuilder>(
+                getSubchannel(),
+                getParentForChildren(),
+                isClean());
+        subchannel_ = null;
+      }
+      return subchannelBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetSubchannelResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetSubchannelResponse)
+  private static final io.grpc.channelz.v1.GetSubchannelResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetSubchannelResponse();
+  }
+
+  public static io.grpc.channelz.v1.GetSubchannelResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetSubchannelResponse>
+      PARSER = new com.google.protobuf.AbstractParser<GetSubchannelResponse>() {
+    public GetSubchannelResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetSubchannelResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetSubchannelResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetSubchannelResponse> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetSubchannelResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelResponseOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelResponseOrBuilder.java
new file mode 100644
index 0000000..601544e
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetSubchannelResponseOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetSubchannelResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetSubchannelResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+   */
+  boolean hasSubchannel();
+  /**
+   * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+   */
+  io.grpc.channelz.v1.Subchannel getSubchannel();
+  /**
+   * <code>.grpc.channelz.Subchannel subchannel = 1;</code>
+   */
+  io.grpc.channelz.v1.SubchannelOrBuilder getSubchannelOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsRequest.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsRequest.java
new file mode 100644
index 0000000..db0cf1f
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsRequest.java
@@ -0,0 +1,468 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetTopChannelsRequest}
+ */
+public  final class GetTopChannelsRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetTopChannelsRequest)
+    GetTopChannelsRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetTopChannelsRequest.newBuilder() to construct.
+  private GetTopChannelsRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetTopChannelsRequest() {
+    startChannelId_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetTopChannelsRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            startChannelId_ = input.readInt64();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsRequest_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetTopChannelsRequest.class, io.grpc.channelz.v1.GetTopChannelsRequest.Builder.class);
+  }
+
+  public static final int START_CHANNEL_ID_FIELD_NUMBER = 1;
+  private long startChannelId_;
+  /**
+   * <pre>
+   * start_channel_id indicates that only channels at or above this id should be
+   * included in the results.
+   * </pre>
+   *
+   * <code>int64 start_channel_id = 1;</code>
+   */
+  public long getStartChannelId() {
+    return startChannelId_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (startChannelId_ != 0L) {
+      output.writeInt64(1, startChannelId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (startChannelId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, startChannelId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetTopChannelsRequest)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetTopChannelsRequest other = (io.grpc.channelz.v1.GetTopChannelsRequest) obj;
+
+    boolean result = true;
+    result = result && (getStartChannelId()
+        == other.getStartChannelId());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + START_CHANNEL_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getStartChannelId());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetTopChannelsRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetTopChannelsRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetTopChannelsRequest)
+      io.grpc.channelz.v1.GetTopChannelsRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsRequest_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetTopChannelsRequest.class, io.grpc.channelz.v1.GetTopChannelsRequest.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetTopChannelsRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      startChannelId_ = 0L;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsRequest_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetTopChannelsRequest getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetTopChannelsRequest.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetTopChannelsRequest build() {
+      io.grpc.channelz.v1.GetTopChannelsRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetTopChannelsRequest buildPartial() {
+      io.grpc.channelz.v1.GetTopChannelsRequest result = new io.grpc.channelz.v1.GetTopChannelsRequest(this);
+      result.startChannelId_ = startChannelId_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetTopChannelsRequest) {
+        return mergeFrom((io.grpc.channelz.v1.GetTopChannelsRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetTopChannelsRequest other) {
+      if (other == io.grpc.channelz.v1.GetTopChannelsRequest.getDefaultInstance()) return this;
+      if (other.getStartChannelId() != 0L) {
+        setStartChannelId(other.getStartChannelId());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetTopChannelsRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetTopChannelsRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long startChannelId_ ;
+    /**
+     * <pre>
+     * start_channel_id indicates that only channels at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_channel_id = 1;</code>
+     */
+    public long getStartChannelId() {
+      return startChannelId_;
+    }
+    /**
+     * <pre>
+     * start_channel_id indicates that only channels at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_channel_id = 1;</code>
+     */
+    public Builder setStartChannelId(long value) {
+      
+      startChannelId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * start_channel_id indicates that only channels at or above this id should be
+     * included in the results.
+     * </pre>
+     *
+     * <code>int64 start_channel_id = 1;</code>
+     */
+    public Builder clearStartChannelId() {
+      
+      startChannelId_ = 0L;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetTopChannelsRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetTopChannelsRequest)
+  private static final io.grpc.channelz.v1.GetTopChannelsRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetTopChannelsRequest();
+  }
+
+  public static io.grpc.channelz.v1.GetTopChannelsRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetTopChannelsRequest>
+      PARSER = new com.google.protobuf.AbstractParser<GetTopChannelsRequest>() {
+    public GetTopChannelsRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetTopChannelsRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetTopChannelsRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetTopChannelsRequest> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetTopChannelsRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsRequestOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsRequestOrBuilder.java
new file mode 100644
index 0000000..fef096b
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsRequestOrBuilder.java
@@ -0,0 +1,19 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetTopChannelsRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetTopChannelsRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * start_channel_id indicates that only channels at or above this id should be
+   * included in the results.
+   * </pre>
+   *
+   * <code>int64 start_channel_id = 1;</code>
+   */
+  long getStartChannelId();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsResponse.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsResponse.java
new file mode 100644
index 0000000..7e05fe9
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsResponse.java
@@ -0,0 +1,935 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.GetTopChannelsResponse}
+ */
+public  final class GetTopChannelsResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.GetTopChannelsResponse)
+    GetTopChannelsResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GetTopChannelsResponse.newBuilder() to construct.
+  private GetTopChannelsResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GetTopChannelsResponse() {
+    channel_ = java.util.Collections.emptyList();
+    end_ = false;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GetTopChannelsResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+              channel_ = new java.util.ArrayList<io.grpc.channelz.v1.Channel>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            channel_.add(
+                input.readMessage(io.grpc.channelz.v1.Channel.parser(), extensionRegistry));
+            break;
+          }
+          case 16: {
+
+            end_ = input.readBool();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
+        channel_ = java.util.Collections.unmodifiableList(channel_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsResponse_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.GetTopChannelsResponse.class, io.grpc.channelz.v1.GetTopChannelsResponse.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int CHANNEL_FIELD_NUMBER = 1;
+  private java.util.List<io.grpc.channelz.v1.Channel> channel_;
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.Channel> getChannelList() {
+    return channel_;
+  }
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.ChannelOrBuilder> 
+      getChannelOrBuilderList() {
+    return channel_;
+  }
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  public int getChannelCount() {
+    return channel_.size();
+  }
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  public io.grpc.channelz.v1.Channel getChannel(int index) {
+    return channel_.get(index);
+  }
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  public io.grpc.channelz.v1.ChannelOrBuilder getChannelOrBuilder(
+      int index) {
+    return channel_.get(index);
+  }
+
+  public static final int END_FIELD_NUMBER = 2;
+  private boolean end_;
+  /**
+   * <pre>
+   * If set, indicates that the list of channels is the final list.  Requesting
+   * more channels can only return more if they are created after this RPC
+   * completes.
+   * </pre>
+   *
+   * <code>bool end = 2;</code>
+   */
+  public boolean getEnd() {
+    return end_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    for (int i = 0; i < channel_.size(); i++) {
+      output.writeMessage(1, channel_.get(i));
+    }
+    if (end_ != false) {
+      output.writeBool(2, end_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    for (int i = 0; i < channel_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, channel_.get(i));
+    }
+    if (end_ != false) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeBoolSize(2, end_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.GetTopChannelsResponse)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.GetTopChannelsResponse other = (io.grpc.channelz.v1.GetTopChannelsResponse) obj;
+
+    boolean result = true;
+    result = result && getChannelList()
+        .equals(other.getChannelList());
+    result = result && (getEnd()
+        == other.getEnd());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (getChannelCount() > 0) {
+      hash = (37 * hash) + CHANNEL_FIELD_NUMBER;
+      hash = (53 * hash) + getChannelList().hashCode();
+    }
+    hash = (37 * hash) + END_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+        getEnd());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.GetTopChannelsResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.GetTopChannelsResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.GetTopChannelsResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.GetTopChannelsResponse)
+      io.grpc.channelz.v1.GetTopChannelsResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.GetTopChannelsResponse.class, io.grpc.channelz.v1.GetTopChannelsResponse.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.GetTopChannelsResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getChannelFieldBuilder();
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (channelBuilder_ == null) {
+        channel_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        channelBuilder_.clear();
+      }
+      end_ = false;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_GetTopChannelsResponse_descriptor;
+    }
+
+    public io.grpc.channelz.v1.GetTopChannelsResponse getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.GetTopChannelsResponse.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.GetTopChannelsResponse build() {
+      io.grpc.channelz.v1.GetTopChannelsResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.GetTopChannelsResponse buildPartial() {
+      io.grpc.channelz.v1.GetTopChannelsResponse result = new io.grpc.channelz.v1.GetTopChannelsResponse(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (channelBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) == 0x00000001)) {
+          channel_ = java.util.Collections.unmodifiableList(channel_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.channel_ = channel_;
+      } else {
+        result.channel_ = channelBuilder_.build();
+      }
+      result.end_ = end_;
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.GetTopChannelsResponse) {
+        return mergeFrom((io.grpc.channelz.v1.GetTopChannelsResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.GetTopChannelsResponse other) {
+      if (other == io.grpc.channelz.v1.GetTopChannelsResponse.getDefaultInstance()) return this;
+      if (channelBuilder_ == null) {
+        if (!other.channel_.isEmpty()) {
+          if (channel_.isEmpty()) {
+            channel_ = other.channel_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureChannelIsMutable();
+            channel_.addAll(other.channel_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.channel_.isEmpty()) {
+          if (channelBuilder_.isEmpty()) {
+            channelBuilder_.dispose();
+            channelBuilder_ = null;
+            channel_ = other.channel_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            channelBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getChannelFieldBuilder() : null;
+          } else {
+            channelBuilder_.addAllMessages(other.channel_);
+          }
+        }
+      }
+      if (other.getEnd() != false) {
+        setEnd(other.getEnd());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.GetTopChannelsResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.GetTopChannelsResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private java.util.List<io.grpc.channelz.v1.Channel> channel_ =
+      java.util.Collections.emptyList();
+    private void ensureChannelIsMutable() {
+      if (!((bitField0_ & 0x00000001) == 0x00000001)) {
+        channel_ = new java.util.ArrayList<io.grpc.channelz.v1.Channel>(channel_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.Channel, io.grpc.channelz.v1.Channel.Builder, io.grpc.channelz.v1.ChannelOrBuilder> channelBuilder_;
+
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.Channel> getChannelList() {
+      if (channelBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(channel_);
+      } else {
+        return channelBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public int getChannelCount() {
+      if (channelBuilder_ == null) {
+        return channel_.size();
+      } else {
+        return channelBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Channel getChannel(int index) {
+      if (channelBuilder_ == null) {
+        return channel_.get(index);
+      } else {
+        return channelBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder setChannel(
+        int index, io.grpc.channelz.v1.Channel value) {
+      if (channelBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelIsMutable();
+        channel_.set(index, value);
+        onChanged();
+      } else {
+        channelBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder setChannel(
+        int index, io.grpc.channelz.v1.Channel.Builder builderForValue) {
+      if (channelBuilder_ == null) {
+        ensureChannelIsMutable();
+        channel_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        channelBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder addChannel(io.grpc.channelz.v1.Channel value) {
+      if (channelBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelIsMutable();
+        channel_.add(value);
+        onChanged();
+      } else {
+        channelBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder addChannel(
+        int index, io.grpc.channelz.v1.Channel value) {
+      if (channelBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelIsMutable();
+        channel_.add(index, value);
+        onChanged();
+      } else {
+        channelBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder addChannel(
+        io.grpc.channelz.v1.Channel.Builder builderForValue) {
+      if (channelBuilder_ == null) {
+        ensureChannelIsMutable();
+        channel_.add(builderForValue.build());
+        onChanged();
+      } else {
+        channelBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder addChannel(
+        int index, io.grpc.channelz.v1.Channel.Builder builderForValue) {
+      if (channelBuilder_ == null) {
+        ensureChannelIsMutable();
+        channel_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        channelBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder addAllChannel(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.Channel> values) {
+      if (channelBuilder_ == null) {
+        ensureChannelIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, channel_);
+        onChanged();
+      } else {
+        channelBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder clearChannel() {
+      if (channelBuilder_ == null) {
+        channel_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        channelBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public Builder removeChannel(int index) {
+      if (channelBuilder_ == null) {
+        ensureChannelIsMutable();
+        channel_.remove(index);
+        onChanged();
+      } else {
+        channelBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Channel.Builder getChannelBuilder(
+        int index) {
+      return getChannelFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.ChannelOrBuilder getChannelOrBuilder(
+        int index) {
+      if (channelBuilder_ == null) {
+        return channel_.get(index);  } else {
+        return channelBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.ChannelOrBuilder> 
+         getChannelOrBuilderList() {
+      if (channelBuilder_ != null) {
+        return channelBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(channel_);
+      }
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Channel.Builder addChannelBuilder() {
+      return getChannelFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.Channel.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public io.grpc.channelz.v1.Channel.Builder addChannelBuilder(
+        int index) {
+      return getChannelFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.Channel.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * list of channels that the connection detail service knows about.  Sorted in
+     * ascending channel_id order.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.Channel.Builder> 
+         getChannelBuilderList() {
+      return getChannelFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.Channel, io.grpc.channelz.v1.Channel.Builder, io.grpc.channelz.v1.ChannelOrBuilder> 
+        getChannelFieldBuilder() {
+      if (channelBuilder_ == null) {
+        channelBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.Channel, io.grpc.channelz.v1.Channel.Builder, io.grpc.channelz.v1.ChannelOrBuilder>(
+                channel_,
+                ((bitField0_ & 0x00000001) == 0x00000001),
+                getParentForChildren(),
+                isClean());
+        channel_ = null;
+      }
+      return channelBuilder_;
+    }
+
+    private boolean end_ ;
+    /**
+     * <pre>
+     * If set, indicates that the list of channels is the final list.  Requesting
+     * more channels can only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public boolean getEnd() {
+      return end_;
+    }
+    /**
+     * <pre>
+     * If set, indicates that the list of channels is the final list.  Requesting
+     * more channels can only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public Builder setEnd(boolean value) {
+      
+      end_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * If set, indicates that the list of channels is the final list.  Requesting
+     * more channels can only return more if they are created after this RPC
+     * completes.
+     * </pre>
+     *
+     * <code>bool end = 2;</code>
+     */
+    public Builder clearEnd() {
+      
+      end_ = false;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.GetTopChannelsResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.GetTopChannelsResponse)
+  private static final io.grpc.channelz.v1.GetTopChannelsResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.GetTopChannelsResponse();
+  }
+
+  public static io.grpc.channelz.v1.GetTopChannelsResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GetTopChannelsResponse>
+      PARSER = new com.google.protobuf.AbstractParser<GetTopChannelsResponse>() {
+    public GetTopChannelsResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GetTopChannelsResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GetTopChannelsResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GetTopChannelsResponse> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.GetTopChannelsResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsResponseOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsResponseOrBuilder.java
new file mode 100644
index 0000000..f56d9eb
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/GetTopChannelsResponseOrBuilder.java
@@ -0,0 +1,69 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface GetTopChannelsResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.GetTopChannelsResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.Channel> 
+      getChannelList();
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  io.grpc.channelz.v1.Channel getChannel(int index);
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  int getChannelCount();
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.ChannelOrBuilder> 
+      getChannelOrBuilderList();
+  /**
+   * <pre>
+   * list of channels that the connection detail service knows about.  Sorted in
+   * ascending channel_id order.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.Channel channel = 1;</code>
+   */
+  io.grpc.channelz.v1.ChannelOrBuilder getChannelOrBuilder(
+      int index);
+
+  /**
+   * <pre>
+   * If set, indicates that the list of channels is the final list.  Requesting
+   * more channels can only return more if they are created after this RPC
+   * completes.
+   * </pre>
+   *
+   * <code>bool end = 2;</code>
+   */
+  boolean getEnd();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/Security.java b/services/src/generated/main/java/io/grpc/channelz/v1/Security.java
new file mode 100644
index 0000000..63084c4
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/Security.java
@@ -0,0 +1,2586 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.Security}
+ */
+public  final class Security extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.Security)
+    SecurityOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use Security.newBuilder() to construct.
+  private Security(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private Security() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private Security(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.Security.Tls.Builder subBuilder = null;
+            if (modelCase_ == 1) {
+              subBuilder = ((io.grpc.channelz.v1.Security.Tls) model_).toBuilder();
+            }
+            model_ =
+                input.readMessage(io.grpc.channelz.v1.Security.Tls.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom((io.grpc.channelz.v1.Security.Tls) model_);
+              model_ = subBuilder.buildPartial();
+            }
+            modelCase_ = 1;
+            break;
+          }
+          case 18: {
+            io.grpc.channelz.v1.Security.OtherSecurity.Builder subBuilder = null;
+            if (modelCase_ == 2) {
+              subBuilder = ((io.grpc.channelz.v1.Security.OtherSecurity) model_).toBuilder();
+            }
+            model_ =
+                input.readMessage(io.grpc.channelz.v1.Security.OtherSecurity.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom((io.grpc.channelz.v1.Security.OtherSecurity) model_);
+              model_ = subBuilder.buildPartial();
+            }
+            modelCase_ = 2;
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.Security.class, io.grpc.channelz.v1.Security.Builder.class);
+  }
+
+  public interface TlsOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:grpc.channelz.Security.Tls)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <pre>
+     * The key exchange used.  e.g. X25519
+     * </pre>
+     *
+     * <code>string key_exchange = 1;</code>
+     */
+    java.lang.String getKeyExchange();
+    /**
+     * <pre>
+     * The key exchange used.  e.g. X25519
+     * </pre>
+     *
+     * <code>string key_exchange = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getKeyExchangeBytes();
+
+    /**
+     * <pre>
+     * The cipher used. e.g. AES_128_GCM.
+     * </pre>
+     *
+     * <code>string cipher = 2;</code>
+     */
+    java.lang.String getCipher();
+    /**
+     * <pre>
+     * The cipher used. e.g. AES_128_GCM.
+     * </pre>
+     *
+     * <code>string cipher = 2;</code>
+     */
+    com.google.protobuf.ByteString
+        getCipherBytes();
+
+    /**
+     * <pre>
+     * the certificate used by this endpoint.
+     * </pre>
+     *
+     * <code>bytes local_certificate = 3;</code>
+     */
+    com.google.protobuf.ByteString getLocalCertificate();
+
+    /**
+     * <pre>
+     * the certificate used by the remote endpoint.
+     * </pre>
+     *
+     * <code>bytes remote_certificate = 4;</code>
+     */
+    com.google.protobuf.ByteString getRemoteCertificate();
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.Security.Tls}
+   */
+  public  static final class Tls extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:grpc.channelz.Security.Tls)
+      TlsOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use Tls.newBuilder() to construct.
+    private Tls(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private Tls() {
+      keyExchange_ = "";
+      cipher_ = "";
+      localCertificate_ = com.google.protobuf.ByteString.EMPTY;
+      remoteCertificate_ = com.google.protobuf.ByteString.EMPTY;
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Tls(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownFieldProto3(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              keyExchange_ = s;
+              break;
+            }
+            case 18: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              cipher_ = s;
+              break;
+            }
+            case 26: {
+
+              localCertificate_ = input.readBytes();
+              break;
+            }
+            case 34: {
+
+              remoteCertificate_ = input.readBytes();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_Tls_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_Tls_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Security.Tls.class, io.grpc.channelz.v1.Security.Tls.Builder.class);
+    }
+
+    public static final int KEY_EXCHANGE_FIELD_NUMBER = 1;
+    private volatile java.lang.Object keyExchange_;
+    /**
+     * <pre>
+     * The key exchange used.  e.g. X25519
+     * </pre>
+     *
+     * <code>string key_exchange = 1;</code>
+     */
+    public java.lang.String getKeyExchange() {
+      java.lang.Object ref = keyExchange_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        keyExchange_ = s;
+        return s;
+      }
+    }
+    /**
+     * <pre>
+     * The key exchange used.  e.g. X25519
+     * </pre>
+     *
+     * <code>string key_exchange = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getKeyExchangeBytes() {
+      java.lang.Object ref = keyExchange_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        keyExchange_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int CIPHER_FIELD_NUMBER = 2;
+    private volatile java.lang.Object cipher_;
+    /**
+     * <pre>
+     * The cipher used. e.g. AES_128_GCM.
+     * </pre>
+     *
+     * <code>string cipher = 2;</code>
+     */
+    public java.lang.String getCipher() {
+      java.lang.Object ref = cipher_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        cipher_ = s;
+        return s;
+      }
+    }
+    /**
+     * <pre>
+     * The cipher used. e.g. AES_128_GCM.
+     * </pre>
+     *
+     * <code>string cipher = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getCipherBytes() {
+      java.lang.Object ref = cipher_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        cipher_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int LOCAL_CERTIFICATE_FIELD_NUMBER = 3;
+    private com.google.protobuf.ByteString localCertificate_;
+    /**
+     * <pre>
+     * the certificate used by this endpoint.
+     * </pre>
+     *
+     * <code>bytes local_certificate = 3;</code>
+     */
+    public com.google.protobuf.ByteString getLocalCertificate() {
+      return localCertificate_;
+    }
+
+    public static final int REMOTE_CERTIFICATE_FIELD_NUMBER = 4;
+    private com.google.protobuf.ByteString remoteCertificate_;
+    /**
+     * <pre>
+     * the certificate used by the remote endpoint.
+     * </pre>
+     *
+     * <code>bytes remote_certificate = 4;</code>
+     */
+    public com.google.protobuf.ByteString getRemoteCertificate() {
+      return remoteCertificate_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!getKeyExchangeBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, keyExchange_);
+      }
+      if (!getCipherBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, cipher_);
+      }
+      if (!localCertificate_.isEmpty()) {
+        output.writeBytes(3, localCertificate_);
+      }
+      if (!remoteCertificate_.isEmpty()) {
+        output.writeBytes(4, remoteCertificate_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getKeyExchangeBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, keyExchange_);
+      }
+      if (!getCipherBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, cipher_);
+      }
+      if (!localCertificate_.isEmpty()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(3, localCertificate_);
+      }
+      if (!remoteCertificate_.isEmpty()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(4, remoteCertificate_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.grpc.channelz.v1.Security.Tls)) {
+        return super.equals(obj);
+      }
+      io.grpc.channelz.v1.Security.Tls other = (io.grpc.channelz.v1.Security.Tls) obj;
+
+      boolean result = true;
+      result = result && getKeyExchange()
+          .equals(other.getKeyExchange());
+      result = result && getCipher()
+          .equals(other.getCipher());
+      result = result && getLocalCertificate()
+          .equals(other.getLocalCertificate());
+      result = result && getRemoteCertificate()
+          .equals(other.getRemoteCertificate());
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + KEY_EXCHANGE_FIELD_NUMBER;
+      hash = (53 * hash) + getKeyExchange().hashCode();
+      hash = (37 * hash) + CIPHER_FIELD_NUMBER;
+      hash = (53 * hash) + getCipher().hashCode();
+      hash = (37 * hash) + LOCAL_CERTIFICATE_FIELD_NUMBER;
+      hash = (53 * hash) + getLocalCertificate().hashCode();
+      hash = (37 * hash) + REMOTE_CERTIFICATE_FIELD_NUMBER;
+      hash = (53 * hash) + getRemoteCertificate().hashCode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Security.Tls parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(io.grpc.channelz.v1.Security.Tls prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code grpc.channelz.Security.Tls}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:grpc.channelz.Security.Tls)
+        io.grpc.channelz.v1.Security.TlsOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_Tls_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_Tls_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                io.grpc.channelz.v1.Security.Tls.class, io.grpc.channelz.v1.Security.Tls.Builder.class);
+      }
+
+      // Construct using io.grpc.channelz.v1.Security.Tls.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        keyExchange_ = "";
+
+        cipher_ = "";
+
+        localCertificate_ = com.google.protobuf.ByteString.EMPTY;
+
+        remoteCertificate_ = com.google.protobuf.ByteString.EMPTY;
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_Tls_descriptor;
+      }
+
+      public io.grpc.channelz.v1.Security.Tls getDefaultInstanceForType() {
+        return io.grpc.channelz.v1.Security.Tls.getDefaultInstance();
+      }
+
+      public io.grpc.channelz.v1.Security.Tls build() {
+        io.grpc.channelz.v1.Security.Tls result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public io.grpc.channelz.v1.Security.Tls buildPartial() {
+        io.grpc.channelz.v1.Security.Tls result = new io.grpc.channelz.v1.Security.Tls(this);
+        result.keyExchange_ = keyExchange_;
+        result.cipher_ = cipher_;
+        result.localCertificate_ = localCertificate_;
+        result.remoteCertificate_ = remoteCertificate_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof io.grpc.channelz.v1.Security.Tls) {
+          return mergeFrom((io.grpc.channelz.v1.Security.Tls)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(io.grpc.channelz.v1.Security.Tls other) {
+        if (other == io.grpc.channelz.v1.Security.Tls.getDefaultInstance()) return this;
+        if (!other.getKeyExchange().isEmpty()) {
+          keyExchange_ = other.keyExchange_;
+          onChanged();
+        }
+        if (!other.getCipher().isEmpty()) {
+          cipher_ = other.cipher_;
+          onChanged();
+        }
+        if (other.getLocalCertificate() != com.google.protobuf.ByteString.EMPTY) {
+          setLocalCertificate(other.getLocalCertificate());
+        }
+        if (other.getRemoteCertificate() != com.google.protobuf.ByteString.EMPTY) {
+          setRemoteCertificate(other.getRemoteCertificate());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        io.grpc.channelz.v1.Security.Tls parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (io.grpc.channelz.v1.Security.Tls) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object keyExchange_ = "";
+      /**
+       * <pre>
+       * The key exchange used.  e.g. X25519
+       * </pre>
+       *
+       * <code>string key_exchange = 1;</code>
+       */
+      public java.lang.String getKeyExchange() {
+        java.lang.Object ref = keyExchange_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          keyExchange_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The key exchange used.  e.g. X25519
+       * </pre>
+       *
+       * <code>string key_exchange = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getKeyExchangeBytes() {
+        java.lang.Object ref = keyExchange_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          keyExchange_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The key exchange used.  e.g. X25519
+       * </pre>
+       *
+       * <code>string key_exchange = 1;</code>
+       */
+      public Builder setKeyExchange(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        keyExchange_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The key exchange used.  e.g. X25519
+       * </pre>
+       *
+       * <code>string key_exchange = 1;</code>
+       */
+      public Builder clearKeyExchange() {
+        
+        keyExchange_ = getDefaultInstance().getKeyExchange();
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The key exchange used.  e.g. X25519
+       * </pre>
+       *
+       * <code>string key_exchange = 1;</code>
+       */
+      public Builder setKeyExchangeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        keyExchange_ = value;
+        onChanged();
+        return this;
+      }
+
+      private java.lang.Object cipher_ = "";
+      /**
+       * <pre>
+       * The cipher used. e.g. AES_128_GCM.
+       * </pre>
+       *
+       * <code>string cipher = 2;</code>
+       */
+      public java.lang.String getCipher() {
+        java.lang.Object ref = cipher_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          cipher_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The cipher used. e.g. AES_128_GCM.
+       * </pre>
+       *
+       * <code>string cipher = 2;</code>
+       */
+      public com.google.protobuf.ByteString
+          getCipherBytes() {
+        java.lang.Object ref = cipher_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          cipher_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The cipher used. e.g. AES_128_GCM.
+       * </pre>
+       *
+       * <code>string cipher = 2;</code>
+       */
+      public Builder setCipher(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        cipher_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The cipher used. e.g. AES_128_GCM.
+       * </pre>
+       *
+       * <code>string cipher = 2;</code>
+       */
+      public Builder clearCipher() {
+        
+        cipher_ = getDefaultInstance().getCipher();
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The cipher used. e.g. AES_128_GCM.
+       * </pre>
+       *
+       * <code>string cipher = 2;</code>
+       */
+      public Builder setCipherBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        cipher_ = value;
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.ByteString localCertificate_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <pre>
+       * the certificate used by this endpoint.
+       * </pre>
+       *
+       * <code>bytes local_certificate = 3;</code>
+       */
+      public com.google.protobuf.ByteString getLocalCertificate() {
+        return localCertificate_;
+      }
+      /**
+       * <pre>
+       * the certificate used by this endpoint.
+       * </pre>
+       *
+       * <code>bytes local_certificate = 3;</code>
+       */
+      public Builder setLocalCertificate(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        localCertificate_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * the certificate used by this endpoint.
+       * </pre>
+       *
+       * <code>bytes local_certificate = 3;</code>
+       */
+      public Builder clearLocalCertificate() {
+        
+        localCertificate_ = getDefaultInstance().getLocalCertificate();
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.ByteString remoteCertificate_ = com.google.protobuf.ByteString.EMPTY;
+      /**
+       * <pre>
+       * the certificate used by the remote endpoint.
+       * </pre>
+       *
+       * <code>bytes remote_certificate = 4;</code>
+       */
+      public com.google.protobuf.ByteString getRemoteCertificate() {
+        return remoteCertificate_;
+      }
+      /**
+       * <pre>
+       * the certificate used by the remote endpoint.
+       * </pre>
+       *
+       * <code>bytes remote_certificate = 4;</code>
+       */
+      public Builder setRemoteCertificate(com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        remoteCertificate_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * the certificate used by the remote endpoint.
+       * </pre>
+       *
+       * <code>bytes remote_certificate = 4;</code>
+       */
+      public Builder clearRemoteCertificate() {
+        
+        remoteCertificate_ = getDefaultInstance().getRemoteCertificate();
+        onChanged();
+        return this;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFieldsProto3(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:grpc.channelz.Security.Tls)
+    }
+
+    // @@protoc_insertion_point(class_scope:grpc.channelz.Security.Tls)
+    private static final io.grpc.channelz.v1.Security.Tls DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new io.grpc.channelz.v1.Security.Tls();
+    }
+
+    public static io.grpc.channelz.v1.Security.Tls getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Tls>
+        PARSER = new com.google.protobuf.AbstractParser<Tls>() {
+      public Tls parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Tls(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Tls> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Tls> getParserForType() {
+      return PARSER;
+    }
+
+    public io.grpc.channelz.v1.Security.Tls getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface OtherSecurityOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:grpc.channelz.Security.OtherSecurity)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    java.lang.String getName();
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getNameBytes();
+
+    /**
+     * <pre>
+     * The actual security details message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    boolean hasValue();
+    /**
+     * <pre>
+     * The actual security details message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    com.google.protobuf.Any getValue();
+    /**
+     * <pre>
+     * The actual security details message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    com.google.protobuf.AnyOrBuilder getValueOrBuilder();
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.Security.OtherSecurity}
+   */
+  public  static final class OtherSecurity extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:grpc.channelz.Security.OtherSecurity)
+      OtherSecurityOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use OtherSecurity.newBuilder() to construct.
+    private OtherSecurity(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private OtherSecurity() {
+      name_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private OtherSecurity(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownFieldProto3(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              name_ = s;
+              break;
+            }
+            case 18: {
+              com.google.protobuf.Any.Builder subBuilder = null;
+              if (value_ != null) {
+                subBuilder = value_.toBuilder();
+              }
+              value_ = input.readMessage(com.google.protobuf.Any.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(value_);
+                value_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_OtherSecurity_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_OtherSecurity_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Security.OtherSecurity.class, io.grpc.channelz.v1.Security.OtherSecurity.Builder.class);
+    }
+
+    public static final int NAME_FIELD_NUMBER = 1;
+    private volatile java.lang.Object name_;
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      }
+    }
+    /**
+     * <pre>
+     * The human readable version of the value.
+     * </pre>
+     *
+     * <code>string name = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int VALUE_FIELD_NUMBER = 2;
+    private com.google.protobuf.Any value_;
+    /**
+     * <pre>
+     * The actual security details message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    public boolean hasValue() {
+      return value_ != null;
+    }
+    /**
+     * <pre>
+     * The actual security details message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    public com.google.protobuf.Any getValue() {
+      return value_ == null ? com.google.protobuf.Any.getDefaultInstance() : value_;
+    }
+    /**
+     * <pre>
+     * The actual security details message.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any value = 2;</code>
+     */
+    public com.google.protobuf.AnyOrBuilder getValueOrBuilder() {
+      return getValue();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!getNameBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
+      }
+      if (value_ != null) {
+        output.writeMessage(2, getValue());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getNameBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
+      }
+      if (value_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getValue());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof io.grpc.channelz.v1.Security.OtherSecurity)) {
+        return super.equals(obj);
+      }
+      io.grpc.channelz.v1.Security.OtherSecurity other = (io.grpc.channelz.v1.Security.OtherSecurity) obj;
+
+      boolean result = true;
+      result = result && getName()
+          .equals(other.getName());
+      result = result && (hasValue() == other.hasValue());
+      if (hasValue()) {
+        result = result && getValue()
+            .equals(other.getValue());
+      }
+      result = result && unknownFields.equals(other.unknownFields);
+      return result;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + NAME_FIELD_NUMBER;
+      hash = (53 * hash) + getName().hashCode();
+      if (hasValue()) {
+        hash = (37 * hash) + VALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getValue().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static io.grpc.channelz.v1.Security.OtherSecurity parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(io.grpc.channelz.v1.Security.OtherSecurity prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code grpc.channelz.Security.OtherSecurity}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:grpc.channelz.Security.OtherSecurity)
+        io.grpc.channelz.v1.Security.OtherSecurityOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_OtherSecurity_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_OtherSecurity_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                io.grpc.channelz.v1.Security.OtherSecurity.class, io.grpc.channelz.v1.Security.OtherSecurity.Builder.class);
+      }
+
+      // Construct using io.grpc.channelz.v1.Security.OtherSecurity.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      public Builder clear() {
+        super.clear();
+        name_ = "";
+
+        if (valueBuilder_ == null) {
+          value_ = null;
+        } else {
+          value_ = null;
+          valueBuilder_ = null;
+        }
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_OtherSecurity_descriptor;
+      }
+
+      public io.grpc.channelz.v1.Security.OtherSecurity getDefaultInstanceForType() {
+        return io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance();
+      }
+
+      public io.grpc.channelz.v1.Security.OtherSecurity build() {
+        io.grpc.channelz.v1.Security.OtherSecurity result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public io.grpc.channelz.v1.Security.OtherSecurity buildPartial() {
+        io.grpc.channelz.v1.Security.OtherSecurity result = new io.grpc.channelz.v1.Security.OtherSecurity(this);
+        result.name_ = name_;
+        if (valueBuilder_ == null) {
+          result.value_ = value_;
+        } else {
+          result.value_ = valueBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      public Builder clone() {
+        return (Builder) super.clone();
+      }
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.setField(field, value);
+      }
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return (Builder) super.clearField(field);
+      }
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return (Builder) super.clearOneof(oneof);
+      }
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return (Builder) super.setRepeatedField(field, index, value);
+      }
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return (Builder) super.addRepeatedField(field, value);
+      }
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof io.grpc.channelz.v1.Security.OtherSecurity) {
+          return mergeFrom((io.grpc.channelz.v1.Security.OtherSecurity)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(io.grpc.channelz.v1.Security.OtherSecurity other) {
+        if (other == io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance()) return this;
+        if (!other.getName().isEmpty()) {
+          name_ = other.name_;
+          onChanged();
+        }
+        if (other.hasValue()) {
+          mergeValue(other.getValue());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        io.grpc.channelz.v1.Security.OtherSecurity parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (io.grpc.channelz.v1.Security.OtherSecurity) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object name_ = "";
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public java.lang.String getName() {
+        java.lang.Object ref = name_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          name_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getNameBytes() {
+        java.lang.Object ref = name_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          name_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public Builder setName(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        name_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public Builder clearName() {
+        
+        name_ = getDefaultInstance().getName();
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * The human readable version of the value.
+       * </pre>
+       *
+       * <code>string name = 1;</code>
+       */
+      public Builder setNameBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        name_ = value;
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.Any value_ = null;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> valueBuilder_;
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public boolean hasValue() {
+        return valueBuilder_ != null || value_ != null;
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public com.google.protobuf.Any getValue() {
+        if (valueBuilder_ == null) {
+          return value_ == null ? com.google.protobuf.Any.getDefaultInstance() : value_;
+        } else {
+          return valueBuilder_.getMessage();
+        }
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder setValue(com.google.protobuf.Any value) {
+        if (valueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          value_ = value;
+          onChanged();
+        } else {
+          valueBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder setValue(
+          com.google.protobuf.Any.Builder builderForValue) {
+        if (valueBuilder_ == null) {
+          value_ = builderForValue.build();
+          onChanged();
+        } else {
+          valueBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder mergeValue(com.google.protobuf.Any value) {
+        if (valueBuilder_ == null) {
+          if (value_ != null) {
+            value_ =
+              com.google.protobuf.Any.newBuilder(value_).mergeFrom(value).buildPartial();
+          } else {
+            value_ = value;
+          }
+          onChanged();
+        } else {
+          valueBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public Builder clearValue() {
+        if (valueBuilder_ == null) {
+          value_ = null;
+          onChanged();
+        } else {
+          value_ = null;
+          valueBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public com.google.protobuf.Any.Builder getValueBuilder() {
+        
+        onChanged();
+        return getValueFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      public com.google.protobuf.AnyOrBuilder getValueOrBuilder() {
+        if (valueBuilder_ != null) {
+          return valueBuilder_.getMessageOrBuilder();
+        } else {
+          return value_ == null ?
+              com.google.protobuf.Any.getDefaultInstance() : value_;
+        }
+      }
+      /**
+       * <pre>
+       * The actual security details message.
+       * </pre>
+       *
+       * <code>.google.protobuf.Any value = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> 
+          getValueFieldBuilder() {
+        if (valueBuilder_ == null) {
+          valueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder>(
+                  getValue(),
+                  getParentForChildren(),
+                  isClean());
+          value_ = null;
+        }
+        return valueBuilder_;
+      }
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFieldsProto3(unknownFields);
+      }
+
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:grpc.channelz.Security.OtherSecurity)
+    }
+
+    // @@protoc_insertion_point(class_scope:grpc.channelz.Security.OtherSecurity)
+    private static final io.grpc.channelz.v1.Security.OtherSecurity DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new io.grpc.channelz.v1.Security.OtherSecurity();
+    }
+
+    public static io.grpc.channelz.v1.Security.OtherSecurity getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<OtherSecurity>
+        PARSER = new com.google.protobuf.AbstractParser<OtherSecurity>() {
+      public OtherSecurity parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new OtherSecurity(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<OtherSecurity> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<OtherSecurity> getParserForType() {
+      return PARSER;
+    }
+
+    public io.grpc.channelz.v1.Security.OtherSecurity getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private int modelCase_ = 0;
+  private java.lang.Object model_;
+  public enum ModelCase
+      implements com.google.protobuf.Internal.EnumLite {
+    TLS(1),
+    OTHER(2),
+    MODEL_NOT_SET(0);
+    private final int value;
+    private ModelCase(int value) {
+      this.value = value;
+    }
+    /**
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static ModelCase valueOf(int value) {
+      return forNumber(value);
+    }
+
+    public static ModelCase forNumber(int value) {
+      switch (value) {
+        case 1: return TLS;
+        case 2: return OTHER;
+        case 0: return MODEL_NOT_SET;
+        default: return null;
+      }
+    }
+    public int getNumber() {
+      return this.value;
+    }
+  };
+
+  public ModelCase
+  getModelCase() {
+    return ModelCase.forNumber(
+        modelCase_);
+  }
+
+  public static final int TLS_FIELD_NUMBER = 1;
+  /**
+   * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+   */
+  public boolean hasTls() {
+    return modelCase_ == 1;
+  }
+  /**
+   * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+   */
+  public io.grpc.channelz.v1.Security.Tls getTls() {
+    if (modelCase_ == 1) {
+       return (io.grpc.channelz.v1.Security.Tls) model_;
+    }
+    return io.grpc.channelz.v1.Security.Tls.getDefaultInstance();
+  }
+  /**
+   * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+   */
+  public io.grpc.channelz.v1.Security.TlsOrBuilder getTlsOrBuilder() {
+    if (modelCase_ == 1) {
+       return (io.grpc.channelz.v1.Security.Tls) model_;
+    }
+    return io.grpc.channelz.v1.Security.Tls.getDefaultInstance();
+  }
+
+  public static final int OTHER_FIELD_NUMBER = 2;
+  /**
+   * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+   */
+  public boolean hasOther() {
+    return modelCase_ == 2;
+  }
+  /**
+   * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+   */
+  public io.grpc.channelz.v1.Security.OtherSecurity getOther() {
+    if (modelCase_ == 2) {
+       return (io.grpc.channelz.v1.Security.OtherSecurity) model_;
+    }
+    return io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance();
+  }
+  /**
+   * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+   */
+  public io.grpc.channelz.v1.Security.OtherSecurityOrBuilder getOtherOrBuilder() {
+    if (modelCase_ == 2) {
+       return (io.grpc.channelz.v1.Security.OtherSecurity) model_;
+    }
+    return io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (modelCase_ == 1) {
+      output.writeMessage(1, (io.grpc.channelz.v1.Security.Tls) model_);
+    }
+    if (modelCase_ == 2) {
+      output.writeMessage(2, (io.grpc.channelz.v1.Security.OtherSecurity) model_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (modelCase_ == 1) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, (io.grpc.channelz.v1.Security.Tls) model_);
+    }
+    if (modelCase_ == 2) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, (io.grpc.channelz.v1.Security.OtherSecurity) model_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.Security)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.Security other = (io.grpc.channelz.v1.Security) obj;
+
+    boolean result = true;
+    result = result && getModelCase().equals(
+        other.getModelCase());
+    if (!result) return false;
+    switch (modelCase_) {
+      case 1:
+        result = result && getTls()
+            .equals(other.getTls());
+        break;
+      case 2:
+        result = result && getOther()
+            .equals(other.getOther());
+        break;
+      case 0:
+      default:
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    switch (modelCase_) {
+      case 1:
+        hash = (37 * hash) + TLS_FIELD_NUMBER;
+        hash = (53 * hash) + getTls().hashCode();
+        break;
+      case 2:
+        hash = (37 * hash) + OTHER_FIELD_NUMBER;
+        hash = (53 * hash) + getOther().hashCode();
+        break;
+      case 0:
+      default:
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.Security parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Security parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Security parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Security parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.Security prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.Security}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.Security)
+      io.grpc.channelz.v1.SecurityOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Security.class, io.grpc.channelz.v1.Security.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.Security.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      modelCase_ = 0;
+      model_ = null;
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Security_descriptor;
+    }
+
+    public io.grpc.channelz.v1.Security getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.Security.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.Security build() {
+      io.grpc.channelz.v1.Security result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.Security buildPartial() {
+      io.grpc.channelz.v1.Security result = new io.grpc.channelz.v1.Security(this);
+      if (modelCase_ == 1) {
+        if (tlsBuilder_ == null) {
+          result.model_ = model_;
+        } else {
+          result.model_ = tlsBuilder_.build();
+        }
+      }
+      if (modelCase_ == 2) {
+        if (otherBuilder_ == null) {
+          result.model_ = model_;
+        } else {
+          result.model_ = otherBuilder_.build();
+        }
+      }
+      result.modelCase_ = modelCase_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.Security) {
+        return mergeFrom((io.grpc.channelz.v1.Security)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.Security other) {
+      if (other == io.grpc.channelz.v1.Security.getDefaultInstance()) return this;
+      switch (other.getModelCase()) {
+        case TLS: {
+          mergeTls(other.getTls());
+          break;
+        }
+        case OTHER: {
+          mergeOther(other.getOther());
+          break;
+        }
+        case MODEL_NOT_SET: {
+          break;
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.Security parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.Security) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int modelCase_ = 0;
+    private java.lang.Object model_;
+    public ModelCase
+        getModelCase() {
+      return ModelCase.forNumber(
+          modelCase_);
+    }
+
+    public Builder clearModel() {
+      modelCase_ = 0;
+      model_ = null;
+      onChanged();
+      return this;
+    }
+
+
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Security.Tls, io.grpc.channelz.v1.Security.Tls.Builder, io.grpc.channelz.v1.Security.TlsOrBuilder> tlsBuilder_;
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public boolean hasTls() {
+      return modelCase_ == 1;
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public io.grpc.channelz.v1.Security.Tls getTls() {
+      if (tlsBuilder_ == null) {
+        if (modelCase_ == 1) {
+          return (io.grpc.channelz.v1.Security.Tls) model_;
+        }
+        return io.grpc.channelz.v1.Security.Tls.getDefaultInstance();
+      } else {
+        if (modelCase_ == 1) {
+          return tlsBuilder_.getMessage();
+        }
+        return io.grpc.channelz.v1.Security.Tls.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public Builder setTls(io.grpc.channelz.v1.Security.Tls value) {
+      if (tlsBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        model_ = value;
+        onChanged();
+      } else {
+        tlsBuilder_.setMessage(value);
+      }
+      modelCase_ = 1;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public Builder setTls(
+        io.grpc.channelz.v1.Security.Tls.Builder builderForValue) {
+      if (tlsBuilder_ == null) {
+        model_ = builderForValue.build();
+        onChanged();
+      } else {
+        tlsBuilder_.setMessage(builderForValue.build());
+      }
+      modelCase_ = 1;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public Builder mergeTls(io.grpc.channelz.v1.Security.Tls value) {
+      if (tlsBuilder_ == null) {
+        if (modelCase_ == 1 &&
+            model_ != io.grpc.channelz.v1.Security.Tls.getDefaultInstance()) {
+          model_ = io.grpc.channelz.v1.Security.Tls.newBuilder((io.grpc.channelz.v1.Security.Tls) model_)
+              .mergeFrom(value).buildPartial();
+        } else {
+          model_ = value;
+        }
+        onChanged();
+      } else {
+        if (modelCase_ == 1) {
+          tlsBuilder_.mergeFrom(value);
+        }
+        tlsBuilder_.setMessage(value);
+      }
+      modelCase_ = 1;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public Builder clearTls() {
+      if (tlsBuilder_ == null) {
+        if (modelCase_ == 1) {
+          modelCase_ = 0;
+          model_ = null;
+          onChanged();
+        }
+      } else {
+        if (modelCase_ == 1) {
+          modelCase_ = 0;
+          model_ = null;
+        }
+        tlsBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public io.grpc.channelz.v1.Security.Tls.Builder getTlsBuilder() {
+      return getTlsFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    public io.grpc.channelz.v1.Security.TlsOrBuilder getTlsOrBuilder() {
+      if ((modelCase_ == 1) && (tlsBuilder_ != null)) {
+        return tlsBuilder_.getMessageOrBuilder();
+      } else {
+        if (modelCase_ == 1) {
+          return (io.grpc.channelz.v1.Security.Tls) model_;
+        }
+        return io.grpc.channelz.v1.Security.Tls.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Security.Tls, io.grpc.channelz.v1.Security.Tls.Builder, io.grpc.channelz.v1.Security.TlsOrBuilder> 
+        getTlsFieldBuilder() {
+      if (tlsBuilder_ == null) {
+        if (!(modelCase_ == 1)) {
+          model_ = io.grpc.channelz.v1.Security.Tls.getDefaultInstance();
+        }
+        tlsBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Security.Tls, io.grpc.channelz.v1.Security.Tls.Builder, io.grpc.channelz.v1.Security.TlsOrBuilder>(
+                (io.grpc.channelz.v1.Security.Tls) model_,
+                getParentForChildren(),
+                isClean());
+        model_ = null;
+      }
+      modelCase_ = 1;
+      onChanged();;
+      return tlsBuilder_;
+    }
+
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Security.OtherSecurity, io.grpc.channelz.v1.Security.OtherSecurity.Builder, io.grpc.channelz.v1.Security.OtherSecurityOrBuilder> otherBuilder_;
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public boolean hasOther() {
+      return modelCase_ == 2;
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public io.grpc.channelz.v1.Security.OtherSecurity getOther() {
+      if (otherBuilder_ == null) {
+        if (modelCase_ == 2) {
+          return (io.grpc.channelz.v1.Security.OtherSecurity) model_;
+        }
+        return io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance();
+      } else {
+        if (modelCase_ == 2) {
+          return otherBuilder_.getMessage();
+        }
+        return io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public Builder setOther(io.grpc.channelz.v1.Security.OtherSecurity value) {
+      if (otherBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        model_ = value;
+        onChanged();
+      } else {
+        otherBuilder_.setMessage(value);
+      }
+      modelCase_ = 2;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public Builder setOther(
+        io.grpc.channelz.v1.Security.OtherSecurity.Builder builderForValue) {
+      if (otherBuilder_ == null) {
+        model_ = builderForValue.build();
+        onChanged();
+      } else {
+        otherBuilder_.setMessage(builderForValue.build());
+      }
+      modelCase_ = 2;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public Builder mergeOther(io.grpc.channelz.v1.Security.OtherSecurity value) {
+      if (otherBuilder_ == null) {
+        if (modelCase_ == 2 &&
+            model_ != io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance()) {
+          model_ = io.grpc.channelz.v1.Security.OtherSecurity.newBuilder((io.grpc.channelz.v1.Security.OtherSecurity) model_)
+              .mergeFrom(value).buildPartial();
+        } else {
+          model_ = value;
+        }
+        onChanged();
+      } else {
+        if (modelCase_ == 2) {
+          otherBuilder_.mergeFrom(value);
+        }
+        otherBuilder_.setMessage(value);
+      }
+      modelCase_ = 2;
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public Builder clearOther() {
+      if (otherBuilder_ == null) {
+        if (modelCase_ == 2) {
+          modelCase_ = 0;
+          model_ = null;
+          onChanged();
+        }
+      } else {
+        if (modelCase_ == 2) {
+          modelCase_ = 0;
+          model_ = null;
+        }
+        otherBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public io.grpc.channelz.v1.Security.OtherSecurity.Builder getOtherBuilder() {
+      return getOtherFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    public io.grpc.channelz.v1.Security.OtherSecurityOrBuilder getOtherOrBuilder() {
+      if ((modelCase_ == 2) && (otherBuilder_ != null)) {
+        return otherBuilder_.getMessageOrBuilder();
+      } else {
+        if (modelCase_ == 2) {
+          return (io.grpc.channelz.v1.Security.OtherSecurity) model_;
+        }
+        return io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Security.OtherSecurity, io.grpc.channelz.v1.Security.OtherSecurity.Builder, io.grpc.channelz.v1.Security.OtherSecurityOrBuilder> 
+        getOtherFieldBuilder() {
+      if (otherBuilder_ == null) {
+        if (!(modelCase_ == 2)) {
+          model_ = io.grpc.channelz.v1.Security.OtherSecurity.getDefaultInstance();
+        }
+        otherBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Security.OtherSecurity, io.grpc.channelz.v1.Security.OtherSecurity.Builder, io.grpc.channelz.v1.Security.OtherSecurityOrBuilder>(
+                (io.grpc.channelz.v1.Security.OtherSecurity) model_,
+                getParentForChildren(),
+                isClean());
+        model_ = null;
+      }
+      modelCase_ = 2;
+      onChanged();;
+      return otherBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.Security)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.Security)
+  private static final io.grpc.channelz.v1.Security DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.Security();
+  }
+
+  public static io.grpc.channelz.v1.Security getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<Security>
+      PARSER = new com.google.protobuf.AbstractParser<Security>() {
+    public Security parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new Security(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<Security> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<Security> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.Security getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SecurityOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SecurityOrBuilder.java
new file mode 100644
index 0000000..ed342b9
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SecurityOrBuilder.java
@@ -0,0 +1,37 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SecurityOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.Security)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+   */
+  boolean hasTls();
+  /**
+   * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+   */
+  io.grpc.channelz.v1.Security.Tls getTls();
+  /**
+   * <code>.grpc.channelz.Security.Tls tls = 1;</code>
+   */
+  io.grpc.channelz.v1.Security.TlsOrBuilder getTlsOrBuilder();
+
+  /**
+   * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+   */
+  boolean hasOther();
+  /**
+   * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+   */
+  io.grpc.channelz.v1.Security.OtherSecurity getOther();
+  /**
+   * <code>.grpc.channelz.Security.OtherSecurity other = 2;</code>
+   */
+  io.grpc.channelz.v1.Security.OtherSecurityOrBuilder getOtherOrBuilder();
+
+  public io.grpc.channelz.v1.Security.ModelCase getModelCase();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/Server.java b/services/src/generated/main/java/io/grpc/channelz/v1/Server.java
new file mode 100644
index 0000000..4c50050
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/Server.java
@@ -0,0 +1,1214 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.Server}
+ */
+public  final class Server extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.Server)
+    ServerOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use Server.newBuilder() to construct.
+  private Server(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private Server() {
+    listenSocket_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private Server(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.ServerRef.Builder subBuilder = null;
+            if (ref_ != null) {
+              subBuilder = ref_.toBuilder();
+            }
+            ref_ = input.readMessage(io.grpc.channelz.v1.ServerRef.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(ref_);
+              ref_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            io.grpc.channelz.v1.ServerData.Builder subBuilder = null;
+            if (data_ != null) {
+              subBuilder = data_.toBuilder();
+            }
+            data_ = input.readMessage(io.grpc.channelz.v1.ServerData.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(data_);
+              data_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 26: {
+            if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+              listenSocket_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>();
+              mutable_bitField0_ |= 0x00000004;
+            }
+            listenSocket_.add(
+                input.readMessage(io.grpc.channelz.v1.SocketRef.parser(), extensionRegistry));
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+        listenSocket_ = java.util.Collections.unmodifiableList(listenSocket_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Server_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Server_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.Server.class, io.grpc.channelz.v1.Server.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int REF_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.ServerRef ref_;
+  /**
+   * <code>.grpc.channelz.ServerRef ref = 1;</code>
+   */
+  public boolean hasRef() {
+    return ref_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.ServerRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.ServerRef getRef() {
+    return ref_ == null ? io.grpc.channelz.v1.ServerRef.getDefaultInstance() : ref_;
+  }
+  /**
+   * <code>.grpc.channelz.ServerRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.ServerRefOrBuilder getRefOrBuilder() {
+    return getRef();
+  }
+
+  public static final int DATA_FIELD_NUMBER = 2;
+  private io.grpc.channelz.v1.ServerData data_;
+  /**
+   * <code>.grpc.channelz.ServerData data = 2;</code>
+   */
+  public boolean hasData() {
+    return data_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.ServerData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.ServerData getData() {
+    return data_ == null ? io.grpc.channelz.v1.ServerData.getDefaultInstance() : data_;
+  }
+  /**
+   * <code>.grpc.channelz.ServerData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.ServerDataOrBuilder getDataOrBuilder() {
+    return getData();
+  }
+
+  public static final int LISTEN_SOCKET_FIELD_NUMBER = 3;
+  private java.util.List<io.grpc.channelz.v1.SocketRef> listenSocket_;
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.SocketRef> getListenSocketList() {
+    return listenSocket_;
+  }
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getListenSocketOrBuilderList() {
+    return listenSocket_;
+  }
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  public int getListenSocketCount() {
+    return listenSocket_.size();
+  }
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  public io.grpc.channelz.v1.SocketRef getListenSocket(int index) {
+    return listenSocket_.get(index);
+  }
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  public io.grpc.channelz.v1.SocketRefOrBuilder getListenSocketOrBuilder(
+      int index) {
+    return listenSocket_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (ref_ != null) {
+      output.writeMessage(1, getRef());
+    }
+    if (data_ != null) {
+      output.writeMessage(2, getData());
+    }
+    for (int i = 0; i < listenSocket_.size(); i++) {
+      output.writeMessage(3, listenSocket_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (ref_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getRef());
+    }
+    if (data_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, getData());
+    }
+    for (int i = 0; i < listenSocket_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, listenSocket_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.Server)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.Server other = (io.grpc.channelz.v1.Server) obj;
+
+    boolean result = true;
+    result = result && (hasRef() == other.hasRef());
+    if (hasRef()) {
+      result = result && getRef()
+          .equals(other.getRef());
+    }
+    result = result && (hasData() == other.hasData());
+    if (hasData()) {
+      result = result && getData()
+          .equals(other.getData());
+    }
+    result = result && getListenSocketList()
+        .equals(other.getListenSocketList());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasRef()) {
+      hash = (37 * hash) + REF_FIELD_NUMBER;
+      hash = (53 * hash) + getRef().hashCode();
+    }
+    if (hasData()) {
+      hash = (37 * hash) + DATA_FIELD_NUMBER;
+      hash = (53 * hash) + getData().hashCode();
+    }
+    if (getListenSocketCount() > 0) {
+      hash = (37 * hash) + LISTEN_SOCKET_FIELD_NUMBER;
+      hash = (53 * hash) + getListenSocketList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.Server parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Server parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Server parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Server parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.Server prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.Server}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.Server)
+      io.grpc.channelz.v1.ServerOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Server_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Server_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Server.class, io.grpc.channelz.v1.Server.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.Server.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getListenSocketFieldBuilder();
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (refBuilder_ == null) {
+        ref_ = null;
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+      if (dataBuilder_ == null) {
+        data_ = null;
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+      if (listenSocketBuilder_ == null) {
+        listenSocket_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+      } else {
+        listenSocketBuilder_.clear();
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Server_descriptor;
+    }
+
+    public io.grpc.channelz.v1.Server getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.Server.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.Server build() {
+      io.grpc.channelz.v1.Server result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.Server buildPartial() {
+      io.grpc.channelz.v1.Server result = new io.grpc.channelz.v1.Server(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (refBuilder_ == null) {
+        result.ref_ = ref_;
+      } else {
+        result.ref_ = refBuilder_.build();
+      }
+      if (dataBuilder_ == null) {
+        result.data_ = data_;
+      } else {
+        result.data_ = dataBuilder_.build();
+      }
+      if (listenSocketBuilder_ == null) {
+        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          listenSocket_ = java.util.Collections.unmodifiableList(listenSocket_);
+          bitField0_ = (bitField0_ & ~0x00000004);
+        }
+        result.listenSocket_ = listenSocket_;
+      } else {
+        result.listenSocket_ = listenSocketBuilder_.build();
+      }
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.Server) {
+        return mergeFrom((io.grpc.channelz.v1.Server)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.Server other) {
+      if (other == io.grpc.channelz.v1.Server.getDefaultInstance()) return this;
+      if (other.hasRef()) {
+        mergeRef(other.getRef());
+      }
+      if (other.hasData()) {
+        mergeData(other.getData());
+      }
+      if (listenSocketBuilder_ == null) {
+        if (!other.listenSocket_.isEmpty()) {
+          if (listenSocket_.isEmpty()) {
+            listenSocket_ = other.listenSocket_;
+            bitField0_ = (bitField0_ & ~0x00000004);
+          } else {
+            ensureListenSocketIsMutable();
+            listenSocket_.addAll(other.listenSocket_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.listenSocket_.isEmpty()) {
+          if (listenSocketBuilder_.isEmpty()) {
+            listenSocketBuilder_.dispose();
+            listenSocketBuilder_ = null;
+            listenSocket_ = other.listenSocket_;
+            bitField0_ = (bitField0_ & ~0x00000004);
+            listenSocketBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getListenSocketFieldBuilder() : null;
+          } else {
+            listenSocketBuilder_.addAllMessages(other.listenSocket_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.Server parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.Server) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private io.grpc.channelz.v1.ServerRef ref_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ServerRef, io.grpc.channelz.v1.ServerRef.Builder, io.grpc.channelz.v1.ServerRefOrBuilder> refBuilder_;
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public boolean hasRef() {
+      return refBuilder_ != null || ref_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.ServerRef getRef() {
+      if (refBuilder_ == null) {
+        return ref_ == null ? io.grpc.channelz.v1.ServerRef.getDefaultInstance() : ref_;
+      } else {
+        return refBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public Builder setRef(io.grpc.channelz.v1.ServerRef value) {
+      if (refBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ref_ = value;
+        onChanged();
+      } else {
+        refBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public Builder setRef(
+        io.grpc.channelz.v1.ServerRef.Builder builderForValue) {
+      if (refBuilder_ == null) {
+        ref_ = builderForValue.build();
+        onChanged();
+      } else {
+        refBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public Builder mergeRef(io.grpc.channelz.v1.ServerRef value) {
+      if (refBuilder_ == null) {
+        if (ref_ != null) {
+          ref_ =
+            io.grpc.channelz.v1.ServerRef.newBuilder(ref_).mergeFrom(value).buildPartial();
+        } else {
+          ref_ = value;
+        }
+        onChanged();
+      } else {
+        refBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public Builder clearRef() {
+      if (refBuilder_ == null) {
+        ref_ = null;
+        onChanged();
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.ServerRef.Builder getRefBuilder() {
+      
+      onChanged();
+      return getRefFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.ServerRefOrBuilder getRefOrBuilder() {
+      if (refBuilder_ != null) {
+        return refBuilder_.getMessageOrBuilder();
+      } else {
+        return ref_ == null ?
+            io.grpc.channelz.v1.ServerRef.getDefaultInstance() : ref_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ServerRef ref = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ServerRef, io.grpc.channelz.v1.ServerRef.Builder, io.grpc.channelz.v1.ServerRefOrBuilder> 
+        getRefFieldBuilder() {
+      if (refBuilder_ == null) {
+        refBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.ServerRef, io.grpc.channelz.v1.ServerRef.Builder, io.grpc.channelz.v1.ServerRefOrBuilder>(
+                getRef(),
+                getParentForChildren(),
+                isClean());
+        ref_ = null;
+      }
+      return refBuilder_;
+    }
+
+    private io.grpc.channelz.v1.ServerData data_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ServerData, io.grpc.channelz.v1.ServerData.Builder, io.grpc.channelz.v1.ServerDataOrBuilder> dataBuilder_;
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public boolean hasData() {
+      return dataBuilder_ != null || data_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ServerData getData() {
+      if (dataBuilder_ == null) {
+        return data_ == null ? io.grpc.channelz.v1.ServerData.getDefaultInstance() : data_;
+      } else {
+        return dataBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public Builder setData(io.grpc.channelz.v1.ServerData value) {
+      if (dataBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        data_ = value;
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public Builder setData(
+        io.grpc.channelz.v1.ServerData.Builder builderForValue) {
+      if (dataBuilder_ == null) {
+        data_ = builderForValue.build();
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public Builder mergeData(io.grpc.channelz.v1.ServerData value) {
+      if (dataBuilder_ == null) {
+        if (data_ != null) {
+          data_ =
+            io.grpc.channelz.v1.ServerData.newBuilder(data_).mergeFrom(value).buildPartial();
+        } else {
+          data_ = value;
+        }
+        onChanged();
+      } else {
+        dataBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public Builder clearData() {
+      if (dataBuilder_ == null) {
+        data_ = null;
+        onChanged();
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ServerData.Builder getDataBuilder() {
+      
+      onChanged();
+      return getDataFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ServerDataOrBuilder getDataOrBuilder() {
+      if (dataBuilder_ != null) {
+        return dataBuilder_.getMessageOrBuilder();
+      } else {
+        return data_ == null ?
+            io.grpc.channelz.v1.ServerData.getDefaultInstance() : data_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ServerData data = 2;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ServerData, io.grpc.channelz.v1.ServerData.Builder, io.grpc.channelz.v1.ServerDataOrBuilder> 
+        getDataFieldBuilder() {
+      if (dataBuilder_ == null) {
+        dataBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.ServerData, io.grpc.channelz.v1.ServerData.Builder, io.grpc.channelz.v1.ServerDataOrBuilder>(
+                getData(),
+                getParentForChildren(),
+                isClean());
+        data_ = null;
+      }
+      return dataBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.SocketRef> listenSocket_ =
+      java.util.Collections.emptyList();
+    private void ensureListenSocketIsMutable() {
+      if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+        listenSocket_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>(listenSocket_);
+        bitField0_ |= 0x00000004;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> listenSocketBuilder_;
+
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef> getListenSocketList() {
+      if (listenSocketBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(listenSocket_);
+      } else {
+        return listenSocketBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public int getListenSocketCount() {
+      if (listenSocketBuilder_ == null) {
+        return listenSocket_.size();
+      } else {
+        return listenSocketBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef getListenSocket(int index) {
+      if (listenSocketBuilder_ == null) {
+        return listenSocket_.get(index);
+      } else {
+        return listenSocketBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder setListenSocket(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (listenSocketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureListenSocketIsMutable();
+        listenSocket_.set(index, value);
+        onChanged();
+      } else {
+        listenSocketBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder setListenSocket(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (listenSocketBuilder_ == null) {
+        ensureListenSocketIsMutable();
+        listenSocket_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        listenSocketBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder addListenSocket(io.grpc.channelz.v1.SocketRef value) {
+      if (listenSocketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureListenSocketIsMutable();
+        listenSocket_.add(value);
+        onChanged();
+      } else {
+        listenSocketBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder addListenSocket(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (listenSocketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureListenSocketIsMutable();
+        listenSocket_.add(index, value);
+        onChanged();
+      } else {
+        listenSocketBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder addListenSocket(
+        io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (listenSocketBuilder_ == null) {
+        ensureListenSocketIsMutable();
+        listenSocket_.add(builderForValue.build());
+        onChanged();
+      } else {
+        listenSocketBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder addListenSocket(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (listenSocketBuilder_ == null) {
+        ensureListenSocketIsMutable();
+        listenSocket_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        listenSocketBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder addAllListenSocket(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.SocketRef> values) {
+      if (listenSocketBuilder_ == null) {
+        ensureListenSocketIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, listenSocket_);
+        onChanged();
+      } else {
+        listenSocketBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder clearListenSocket() {
+      if (listenSocketBuilder_ == null) {
+        listenSocket_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+        onChanged();
+      } else {
+        listenSocketBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public Builder removeListenSocket(int index) {
+      if (listenSocketBuilder_ == null) {
+        ensureListenSocketIsMutable();
+        listenSocket_.remove(index);
+        onChanged();
+      } else {
+        listenSocketBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder getListenSocketBuilder(
+        int index) {
+      return getListenSocketFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public io.grpc.channelz.v1.SocketRefOrBuilder getListenSocketOrBuilder(
+        int index) {
+      if (listenSocketBuilder_ == null) {
+        return listenSocket_.get(index);  } else {
+        return listenSocketBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+         getListenSocketOrBuilderList() {
+      if (listenSocketBuilder_ != null) {
+        return listenSocketBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(listenSocket_);
+      }
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addListenSocketBuilder() {
+      return getListenSocketFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addListenSocketBuilder(
+        int index) {
+      return getListenSocketFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * The sockets that the server is listening on.  There are no ordering
+     * guarantees.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef.Builder> 
+         getListenSocketBuilderList() {
+      return getListenSocketFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> 
+        getListenSocketFieldBuilder() {
+      if (listenSocketBuilder_ == null) {
+        listenSocketBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder>(
+                listenSocket_,
+                ((bitField0_ & 0x00000004) == 0x00000004),
+                getParentForChildren(),
+                isClean());
+        listenSocket_ = null;
+      }
+      return listenSocketBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.Server)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.Server)
+  private static final io.grpc.channelz.v1.Server DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.Server();
+  }
+
+  public static io.grpc.channelz.v1.Server getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<Server>
+      PARSER = new com.google.protobuf.AbstractParser<Server>() {
+    public Server parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new Server(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<Server> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<Server> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.Server getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ServerChannelTrace.java b/services/src/generated/main/java/io/grpc/channelz/v1/ServerChannelTrace.java
new file mode 100644
index 0000000..602ca87
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ServerChannelTrace.java
@@ -0,0 +1,396 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * <pre>
+ * TODO: fill this in.
+ * </pre>
+ *
+ * Protobuf type {@code grpc.channelz.ServerChannelTrace}
+ */
+public  final class ServerChannelTrace extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.ServerChannelTrace)
+    ServerChannelTraceOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ServerChannelTrace.newBuilder() to construct.
+  private ServerChannelTrace(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ServerChannelTrace() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ServerChannelTrace(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerChannelTrace_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerChannelTrace_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.ServerChannelTrace.class, io.grpc.channelz.v1.ServerChannelTrace.Builder.class);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.ServerChannelTrace)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.ServerChannelTrace other = (io.grpc.channelz.v1.ServerChannelTrace) obj;
+
+    boolean result = true;
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerChannelTrace parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.ServerChannelTrace prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * TODO: fill this in.
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.ServerChannelTrace}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.ServerChannelTrace)
+      io.grpc.channelz.v1.ServerChannelTraceOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerChannelTrace_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerChannelTrace_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.ServerChannelTrace.class, io.grpc.channelz.v1.ServerChannelTrace.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.ServerChannelTrace.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerChannelTrace_descriptor;
+    }
+
+    public io.grpc.channelz.v1.ServerChannelTrace getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.ServerChannelTrace.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.ServerChannelTrace build() {
+      io.grpc.channelz.v1.ServerChannelTrace result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.ServerChannelTrace buildPartial() {
+      io.grpc.channelz.v1.ServerChannelTrace result = new io.grpc.channelz.v1.ServerChannelTrace(this);
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.ServerChannelTrace) {
+        return mergeFrom((io.grpc.channelz.v1.ServerChannelTrace)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.ServerChannelTrace other) {
+      if (other == io.grpc.channelz.v1.ServerChannelTrace.getDefaultInstance()) return this;
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.ServerChannelTrace parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.ServerChannelTrace) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.ServerChannelTrace)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.ServerChannelTrace)
+  private static final io.grpc.channelz.v1.ServerChannelTrace DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.ServerChannelTrace();
+  }
+
+  public static io.grpc.channelz.v1.ServerChannelTrace getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ServerChannelTrace>
+      PARSER = new com.google.protobuf.AbstractParser<ServerChannelTrace>() {
+    public ServerChannelTrace parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ServerChannelTrace(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ServerChannelTrace> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ServerChannelTrace> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.ServerChannelTrace getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ServerChannelTraceOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ServerChannelTraceOrBuilder.java
new file mode 100644
index 0000000..3cb9656
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ServerChannelTraceOrBuilder.java
@@ -0,0 +1,9 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ServerChannelTraceOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.ServerChannelTrace)
+    com.google.protobuf.MessageOrBuilder {
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ServerData.java b/services/src/generated/main/java/io/grpc/channelz/v1/ServerData.java
new file mode 100644
index 0000000..eb320df
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ServerData.java
@@ -0,0 +1,1024 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.ServerData}
+ */
+public  final class ServerData extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.ServerData)
+    ServerDataOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ServerData.newBuilder() to construct.
+  private ServerData(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ServerData() {
+    callsStarted_ = 0L;
+    callsSucceeded_ = 0L;
+    callsFailed_ = 0L;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ServerData(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.ServerChannelTrace.Builder subBuilder = null;
+            if (trace_ != null) {
+              subBuilder = trace_.toBuilder();
+            }
+            trace_ = input.readMessage(io.grpc.channelz.v1.ServerChannelTrace.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(trace_);
+              trace_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+
+            callsStarted_ = input.readInt64();
+            break;
+          }
+          case 24: {
+
+            callsSucceeded_ = input.readInt64();
+            break;
+          }
+          case 32: {
+
+            callsFailed_ = input.readInt64();
+            break;
+          }
+          case 42: {
+            com.google.protobuf.Timestamp.Builder subBuilder = null;
+            if (lastCallStartedTimestamp_ != null) {
+              subBuilder = lastCallStartedTimestamp_.toBuilder();
+            }
+            lastCallStartedTimestamp_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(lastCallStartedTimestamp_);
+              lastCallStartedTimestamp_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerData_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerData_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.ServerData.class, io.grpc.channelz.v1.ServerData.Builder.class);
+  }
+
+  public static final int TRACE_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.ServerChannelTrace trace_;
+  /**
+   * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+   */
+  public boolean hasTrace() {
+    return trace_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+   */
+  public io.grpc.channelz.v1.ServerChannelTrace getTrace() {
+    return trace_ == null ? io.grpc.channelz.v1.ServerChannelTrace.getDefaultInstance() : trace_;
+  }
+  /**
+   * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+   */
+  public io.grpc.channelz.v1.ServerChannelTraceOrBuilder getTraceOrBuilder() {
+    return getTrace();
+  }
+
+  public static final int CALLS_STARTED_FIELD_NUMBER = 2;
+  private long callsStarted_;
+  /**
+   * <pre>
+   * The number of incoming calls started on the server
+   * </pre>
+   *
+   * <code>int64 calls_started = 2;</code>
+   */
+  public long getCallsStarted() {
+    return callsStarted_;
+  }
+
+  public static final int CALLS_SUCCEEDED_FIELD_NUMBER = 3;
+  private long callsSucceeded_;
+  /**
+   * <pre>
+   * The number of incoming calls that have completed with an OK status
+   * </pre>
+   *
+   * <code>int64 calls_succeeded = 3;</code>
+   */
+  public long getCallsSucceeded() {
+    return callsSucceeded_;
+  }
+
+  public static final int CALLS_FAILED_FIELD_NUMBER = 4;
+  private long callsFailed_;
+  /**
+   * <pre>
+   * The number of incoming calls that have a completed with a non-OK status
+   * </pre>
+   *
+   * <code>int64 calls_failed = 4;</code>
+   */
+  public long getCallsFailed() {
+    return callsFailed_;
+  }
+
+  public static final int LAST_CALL_STARTED_TIMESTAMP_FIELD_NUMBER = 5;
+  private com.google.protobuf.Timestamp lastCallStartedTimestamp_;
+  /**
+   * <pre>
+   * The last time a call was started on the server.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+   */
+  public boolean hasLastCallStartedTimestamp() {
+    return lastCallStartedTimestamp_ != null;
+  }
+  /**
+   * <pre>
+   * The last time a call was started on the server.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+   */
+  public com.google.protobuf.Timestamp getLastCallStartedTimestamp() {
+    return lastCallStartedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastCallStartedTimestamp_;
+  }
+  /**
+   * <pre>
+   * The last time a call was started on the server.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+   */
+  public com.google.protobuf.TimestampOrBuilder getLastCallStartedTimestampOrBuilder() {
+    return getLastCallStartedTimestamp();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (trace_ != null) {
+      output.writeMessage(1, getTrace());
+    }
+    if (callsStarted_ != 0L) {
+      output.writeInt64(2, callsStarted_);
+    }
+    if (callsSucceeded_ != 0L) {
+      output.writeInt64(3, callsSucceeded_);
+    }
+    if (callsFailed_ != 0L) {
+      output.writeInt64(4, callsFailed_);
+    }
+    if (lastCallStartedTimestamp_ != null) {
+      output.writeMessage(5, getLastCallStartedTimestamp());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (trace_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getTrace());
+    }
+    if (callsStarted_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(2, callsStarted_);
+    }
+    if (callsSucceeded_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(3, callsSucceeded_);
+    }
+    if (callsFailed_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(4, callsFailed_);
+    }
+    if (lastCallStartedTimestamp_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(5, getLastCallStartedTimestamp());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.ServerData)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.ServerData other = (io.grpc.channelz.v1.ServerData) obj;
+
+    boolean result = true;
+    result = result && (hasTrace() == other.hasTrace());
+    if (hasTrace()) {
+      result = result && getTrace()
+          .equals(other.getTrace());
+    }
+    result = result && (getCallsStarted()
+        == other.getCallsStarted());
+    result = result && (getCallsSucceeded()
+        == other.getCallsSucceeded());
+    result = result && (getCallsFailed()
+        == other.getCallsFailed());
+    result = result && (hasLastCallStartedTimestamp() == other.hasLastCallStartedTimestamp());
+    if (hasLastCallStartedTimestamp()) {
+      result = result && getLastCallStartedTimestamp()
+          .equals(other.getLastCallStartedTimestamp());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasTrace()) {
+      hash = (37 * hash) + TRACE_FIELD_NUMBER;
+      hash = (53 * hash) + getTrace().hashCode();
+    }
+    hash = (37 * hash) + CALLS_STARTED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getCallsStarted());
+    hash = (37 * hash) + CALLS_SUCCEEDED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getCallsSucceeded());
+    hash = (37 * hash) + CALLS_FAILED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getCallsFailed());
+    if (hasLastCallStartedTimestamp()) {
+      hash = (37 * hash) + LAST_CALL_STARTED_TIMESTAMP_FIELD_NUMBER;
+      hash = (53 * hash) + getLastCallStartedTimestamp().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerData parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerData parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerData parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.ServerData prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.ServerData}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.ServerData)
+      io.grpc.channelz.v1.ServerDataOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerData_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerData_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.ServerData.class, io.grpc.channelz.v1.ServerData.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.ServerData.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (traceBuilder_ == null) {
+        trace_ = null;
+      } else {
+        trace_ = null;
+        traceBuilder_ = null;
+      }
+      callsStarted_ = 0L;
+
+      callsSucceeded_ = 0L;
+
+      callsFailed_ = 0L;
+
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestamp_ = null;
+      } else {
+        lastCallStartedTimestamp_ = null;
+        lastCallStartedTimestampBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerData_descriptor;
+    }
+
+    public io.grpc.channelz.v1.ServerData getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.ServerData.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.ServerData build() {
+      io.grpc.channelz.v1.ServerData result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.ServerData buildPartial() {
+      io.grpc.channelz.v1.ServerData result = new io.grpc.channelz.v1.ServerData(this);
+      if (traceBuilder_ == null) {
+        result.trace_ = trace_;
+      } else {
+        result.trace_ = traceBuilder_.build();
+      }
+      result.callsStarted_ = callsStarted_;
+      result.callsSucceeded_ = callsSucceeded_;
+      result.callsFailed_ = callsFailed_;
+      if (lastCallStartedTimestampBuilder_ == null) {
+        result.lastCallStartedTimestamp_ = lastCallStartedTimestamp_;
+      } else {
+        result.lastCallStartedTimestamp_ = lastCallStartedTimestampBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.ServerData) {
+        return mergeFrom((io.grpc.channelz.v1.ServerData)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.ServerData other) {
+      if (other == io.grpc.channelz.v1.ServerData.getDefaultInstance()) return this;
+      if (other.hasTrace()) {
+        mergeTrace(other.getTrace());
+      }
+      if (other.getCallsStarted() != 0L) {
+        setCallsStarted(other.getCallsStarted());
+      }
+      if (other.getCallsSucceeded() != 0L) {
+        setCallsSucceeded(other.getCallsSucceeded());
+      }
+      if (other.getCallsFailed() != 0L) {
+        setCallsFailed(other.getCallsFailed());
+      }
+      if (other.hasLastCallStartedTimestamp()) {
+        mergeLastCallStartedTimestamp(other.getLastCallStartedTimestamp());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.ServerData parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.ServerData) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.grpc.channelz.v1.ServerChannelTrace trace_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ServerChannelTrace, io.grpc.channelz.v1.ServerChannelTrace.Builder, io.grpc.channelz.v1.ServerChannelTraceOrBuilder> traceBuilder_;
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public boolean hasTrace() {
+      return traceBuilder_ != null || trace_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public io.grpc.channelz.v1.ServerChannelTrace getTrace() {
+      if (traceBuilder_ == null) {
+        return trace_ == null ? io.grpc.channelz.v1.ServerChannelTrace.getDefaultInstance() : trace_;
+      } else {
+        return traceBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public Builder setTrace(io.grpc.channelz.v1.ServerChannelTrace value) {
+      if (traceBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        trace_ = value;
+        onChanged();
+      } else {
+        traceBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public Builder setTrace(
+        io.grpc.channelz.v1.ServerChannelTrace.Builder builderForValue) {
+      if (traceBuilder_ == null) {
+        trace_ = builderForValue.build();
+        onChanged();
+      } else {
+        traceBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public Builder mergeTrace(io.grpc.channelz.v1.ServerChannelTrace value) {
+      if (traceBuilder_ == null) {
+        if (trace_ != null) {
+          trace_ =
+            io.grpc.channelz.v1.ServerChannelTrace.newBuilder(trace_).mergeFrom(value).buildPartial();
+        } else {
+          trace_ = value;
+        }
+        onChanged();
+      } else {
+        traceBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public Builder clearTrace() {
+      if (traceBuilder_ == null) {
+        trace_ = null;
+        onChanged();
+      } else {
+        trace_ = null;
+        traceBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public io.grpc.channelz.v1.ServerChannelTrace.Builder getTraceBuilder() {
+      
+      onChanged();
+      return getTraceFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    public io.grpc.channelz.v1.ServerChannelTraceOrBuilder getTraceOrBuilder() {
+      if (traceBuilder_ != null) {
+        return traceBuilder_.getMessageOrBuilder();
+      } else {
+        return trace_ == null ?
+            io.grpc.channelz.v1.ServerChannelTrace.getDefaultInstance() : trace_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ServerChannelTrace, io.grpc.channelz.v1.ServerChannelTrace.Builder, io.grpc.channelz.v1.ServerChannelTraceOrBuilder> 
+        getTraceFieldBuilder() {
+      if (traceBuilder_ == null) {
+        traceBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.ServerChannelTrace, io.grpc.channelz.v1.ServerChannelTrace.Builder, io.grpc.channelz.v1.ServerChannelTraceOrBuilder>(
+                getTrace(),
+                getParentForChildren(),
+                isClean());
+        trace_ = null;
+      }
+      return traceBuilder_;
+    }
+
+    private long callsStarted_ ;
+    /**
+     * <pre>
+     * The number of incoming calls started on the server
+     * </pre>
+     *
+     * <code>int64 calls_started = 2;</code>
+     */
+    public long getCallsStarted() {
+      return callsStarted_;
+    }
+    /**
+     * <pre>
+     * The number of incoming calls started on the server
+     * </pre>
+     *
+     * <code>int64 calls_started = 2;</code>
+     */
+    public Builder setCallsStarted(long value) {
+      
+      callsStarted_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of incoming calls started on the server
+     * </pre>
+     *
+     * <code>int64 calls_started = 2;</code>
+     */
+    public Builder clearCallsStarted() {
+      
+      callsStarted_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long callsSucceeded_ ;
+    /**
+     * <pre>
+     * The number of incoming calls that have completed with an OK status
+     * </pre>
+     *
+     * <code>int64 calls_succeeded = 3;</code>
+     */
+    public long getCallsSucceeded() {
+      return callsSucceeded_;
+    }
+    /**
+     * <pre>
+     * The number of incoming calls that have completed with an OK status
+     * </pre>
+     *
+     * <code>int64 calls_succeeded = 3;</code>
+     */
+    public Builder setCallsSucceeded(long value) {
+      
+      callsSucceeded_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of incoming calls that have completed with an OK status
+     * </pre>
+     *
+     * <code>int64 calls_succeeded = 3;</code>
+     */
+    public Builder clearCallsSucceeded() {
+      
+      callsSucceeded_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long callsFailed_ ;
+    /**
+     * <pre>
+     * The number of incoming calls that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 calls_failed = 4;</code>
+     */
+    public long getCallsFailed() {
+      return callsFailed_;
+    }
+    /**
+     * <pre>
+     * The number of incoming calls that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 calls_failed = 4;</code>
+     */
+    public Builder setCallsFailed(long value) {
+      
+      callsFailed_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of incoming calls that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 calls_failed = 4;</code>
+     */
+    public Builder clearCallsFailed() {
+      
+      callsFailed_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.Timestamp lastCallStartedTimestamp_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lastCallStartedTimestampBuilder_;
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public boolean hasLastCallStartedTimestamp() {
+      return lastCallStartedTimestampBuilder_ != null || lastCallStartedTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public com.google.protobuf.Timestamp getLastCallStartedTimestamp() {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        return lastCallStartedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastCallStartedTimestamp_;
+      } else {
+        return lastCallStartedTimestampBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public Builder setLastCallStartedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        lastCallStartedTimestamp_ = value;
+        onChanged();
+      } else {
+        lastCallStartedTimestampBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public Builder setLastCallStartedTimestamp(
+        com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestamp_ = builderForValue.build();
+        onChanged();
+      } else {
+        lastCallStartedTimestampBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public Builder mergeLastCallStartedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        if (lastCallStartedTimestamp_ != null) {
+          lastCallStartedTimestamp_ =
+            com.google.protobuf.Timestamp.newBuilder(lastCallStartedTimestamp_).mergeFrom(value).buildPartial();
+        } else {
+          lastCallStartedTimestamp_ = value;
+        }
+        onChanged();
+      } else {
+        lastCallStartedTimestampBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public Builder clearLastCallStartedTimestamp() {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestamp_ = null;
+        onChanged();
+      } else {
+        lastCallStartedTimestamp_ = null;
+        lastCallStartedTimestampBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public com.google.protobuf.Timestamp.Builder getLastCallStartedTimestampBuilder() {
+      
+      onChanged();
+      return getLastCallStartedTimestampFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getLastCallStartedTimestampOrBuilder() {
+      if (lastCallStartedTimestampBuilder_ != null) {
+        return lastCallStartedTimestampBuilder_.getMessageOrBuilder();
+      } else {
+        return lastCallStartedTimestamp_ == null ?
+            com.google.protobuf.Timestamp.getDefaultInstance() : lastCallStartedTimestamp_;
+      }
+    }
+    /**
+     * <pre>
+     * The last time a call was started on the server.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
+        getLastCallStartedTimestampFieldBuilder() {
+      if (lastCallStartedTimestampBuilder_ == null) {
+        lastCallStartedTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
+                getLastCallStartedTimestamp(),
+                getParentForChildren(),
+                isClean());
+        lastCallStartedTimestamp_ = null;
+      }
+      return lastCallStartedTimestampBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.ServerData)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.ServerData)
+  private static final io.grpc.channelz.v1.ServerData DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.ServerData();
+  }
+
+  public static io.grpc.channelz.v1.ServerData getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ServerData>
+      PARSER = new com.google.protobuf.AbstractParser<ServerData>() {
+    public ServerData parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ServerData(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ServerData> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ServerData> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.ServerData getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ServerDataOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ServerDataOrBuilder.java
new file mode 100644
index 0000000..2996f4a
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ServerDataOrBuilder.java
@@ -0,0 +1,74 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ServerDataOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.ServerData)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+   */
+  boolean hasTrace();
+  /**
+   * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+   */
+  io.grpc.channelz.v1.ServerChannelTrace getTrace();
+  /**
+   * <code>.grpc.channelz.ServerChannelTrace trace = 1;</code>
+   */
+  io.grpc.channelz.v1.ServerChannelTraceOrBuilder getTraceOrBuilder();
+
+  /**
+   * <pre>
+   * The number of incoming calls started on the server
+   * </pre>
+   *
+   * <code>int64 calls_started = 2;</code>
+   */
+  long getCallsStarted();
+
+  /**
+   * <pre>
+   * The number of incoming calls that have completed with an OK status
+   * </pre>
+   *
+   * <code>int64 calls_succeeded = 3;</code>
+   */
+  long getCallsSucceeded();
+
+  /**
+   * <pre>
+   * The number of incoming calls that have a completed with a non-OK status
+   * </pre>
+   *
+   * <code>int64 calls_failed = 4;</code>
+   */
+  long getCallsFailed();
+
+  /**
+   * <pre>
+   * The last time a call was started on the server.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+   */
+  boolean hasLastCallStartedTimestamp();
+  /**
+   * <pre>
+   * The last time a call was started on the server.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+   */
+  com.google.protobuf.Timestamp getLastCallStartedTimestamp();
+  /**
+   * <pre>
+   * The last time a call was started on the server.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_call_started_timestamp = 5;</code>
+   */
+  com.google.protobuf.TimestampOrBuilder getLastCallStartedTimestampOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ServerOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ServerOrBuilder.java
new file mode 100644
index 0000000..bcf0a11
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ServerOrBuilder.java
@@ -0,0 +1,84 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ServerOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.Server)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.ServerRef ref = 1;</code>
+   */
+  boolean hasRef();
+  /**
+   * <code>.grpc.channelz.ServerRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.ServerRef getRef();
+  /**
+   * <code>.grpc.channelz.ServerRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.ServerRefOrBuilder getRefOrBuilder();
+
+  /**
+   * <code>.grpc.channelz.ServerData data = 2;</code>
+   */
+  boolean hasData();
+  /**
+   * <code>.grpc.channelz.ServerData data = 2;</code>
+   */
+  io.grpc.channelz.v1.ServerData getData();
+  /**
+   * <code>.grpc.channelz.ServerData data = 2;</code>
+   */
+  io.grpc.channelz.v1.ServerDataOrBuilder getDataOrBuilder();
+
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.SocketRef> 
+      getListenSocketList();
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  io.grpc.channelz.v1.SocketRef getListenSocket(int index);
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  int getListenSocketCount();
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getListenSocketOrBuilderList();
+  /**
+   * <pre>
+   * The sockets that the server is listening on.  There are no ordering
+   * guarantees.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef listen_socket = 3;</code>
+   */
+  io.grpc.channelz.v1.SocketRefOrBuilder getListenSocketOrBuilder(
+      int index);
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ServerRef.java b/services/src/generated/main/java/io/grpc/channelz/v1/ServerRef.java
new file mode 100644
index 0000000..47ffb25
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ServerRef.java
@@ -0,0 +1,619 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.ServerRef}
+ */
+public  final class ServerRef extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.ServerRef)
+    ServerRefOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use ServerRef.newBuilder() to construct.
+  private ServerRef(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private ServerRef() {
+    serverId_ = 0L;
+    name_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private ServerRef(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 40: {
+
+            serverId_ = input.readInt64();
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerRef_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerRef_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.ServerRef.class, io.grpc.channelz.v1.ServerRef.Builder.class);
+  }
+
+  public static final int SERVER_ID_FIELD_NUMBER = 5;
+  private long serverId_;
+  /**
+   * <pre>
+   * A globally unique identifier for this server.   Must be a positive number.
+   * </pre>
+   *
+   * <code>int64 server_id = 5;</code>
+   */
+  public long getServerId() {
+    return serverId_;
+  }
+
+  public static final int NAME_FIELD_NUMBER = 6;
+  private volatile java.lang.Object name_;
+  /**
+   * <pre>
+   * An optional name associated with the server.
+   * </pre>
+   *
+   * <code>string name = 6;</code>
+   */
+  public java.lang.String getName() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * An optional name associated with the server.
+   * </pre>
+   *
+   * <code>string name = 6;</code>
+   */
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (serverId_ != 0L) {
+      output.writeInt64(5, serverId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, name_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (serverId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(5, serverId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, name_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.ServerRef)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.ServerRef other = (io.grpc.channelz.v1.ServerRef) obj;
+
+    boolean result = true;
+    result = result && (getServerId()
+        == other.getServerId());
+    result = result && getName()
+        .equals(other.getName());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + SERVER_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getServerId());
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.ServerRef parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.ServerRef prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.ServerRef}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.ServerRef)
+      io.grpc.channelz.v1.ServerRefOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerRef_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerRef_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.ServerRef.class, io.grpc.channelz.v1.ServerRef.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.ServerRef.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      serverId_ = 0L;
+
+      name_ = "";
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_ServerRef_descriptor;
+    }
+
+    public io.grpc.channelz.v1.ServerRef getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.ServerRef.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.ServerRef build() {
+      io.grpc.channelz.v1.ServerRef result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.ServerRef buildPartial() {
+      io.grpc.channelz.v1.ServerRef result = new io.grpc.channelz.v1.ServerRef(this);
+      result.serverId_ = serverId_;
+      result.name_ = name_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.ServerRef) {
+        return mergeFrom((io.grpc.channelz.v1.ServerRef)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.ServerRef other) {
+      if (other == io.grpc.channelz.v1.ServerRef.getDefaultInstance()) return this;
+      if (other.getServerId() != 0L) {
+        setServerId(other.getServerId());
+      }
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.ServerRef parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.ServerRef) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long serverId_ ;
+    /**
+     * <pre>
+     * A globally unique identifier for this server.   Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 server_id = 5;</code>
+     */
+    public long getServerId() {
+      return serverId_;
+    }
+    /**
+     * <pre>
+     * A globally unique identifier for this server.   Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 server_id = 5;</code>
+     */
+    public Builder setServerId(long value) {
+      
+      serverId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * A globally unique identifier for this server.   Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 server_id = 5;</code>
+     */
+    public Builder clearServerId() {
+      
+      serverId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object name_ = "";
+    /**
+     * <pre>
+     * An optional name associated with the server.
+     * </pre>
+     *
+     * <code>string name = 6;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the server.
+     * </pre>
+     *
+     * <code>string name = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the server.
+     * </pre>
+     *
+     * <code>string name = 6;</code>
+     */
+    public Builder setName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the server.
+     * </pre>
+     *
+     * <code>string name = 6;</code>
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the server.
+     * </pre>
+     *
+     * <code>string name = 6;</code>
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.ServerRef)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.ServerRef)
+  private static final io.grpc.channelz.v1.ServerRef DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.ServerRef();
+  }
+
+  public static io.grpc.channelz.v1.ServerRef getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<ServerRef>
+      PARSER = new com.google.protobuf.AbstractParser<ServerRef>() {
+    public ServerRef parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new ServerRef(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<ServerRef> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<ServerRef> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.ServerRef getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/ServerRefOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/ServerRefOrBuilder.java
new file mode 100644
index 0000000..5200616
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/ServerRefOrBuilder.java
@@ -0,0 +1,36 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface ServerRefOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.ServerRef)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * A globally unique identifier for this server.   Must be a positive number.
+   * </pre>
+   *
+   * <code>int64 server_id = 5;</code>
+   */
+  long getServerId();
+
+  /**
+   * <pre>
+   * An optional name associated with the server.
+   * </pre>
+   *
+   * <code>string name = 6;</code>
+   */
+  java.lang.String getName();
+  /**
+   * <pre>
+   * An optional name associated with the server.
+   * </pre>
+   *
+   * <code>string name = 6;</code>
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/Socket.java b/services/src/generated/main/java/io/grpc/channelz/v1/Socket.java
new file mode 100644
index 0000000..b013ec0
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/Socket.java
@@ -0,0 +1,1560 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * <pre>
+ * Information about an actual connection.  Pronounced "sock-ay".
+ * </pre>
+ *
+ * Protobuf type {@code grpc.channelz.Socket}
+ */
+public  final class Socket extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.Socket)
+    SocketOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use Socket.newBuilder() to construct.
+  private Socket(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private Socket() {
+    remoteName_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private Socket(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.SocketRef.Builder subBuilder = null;
+            if (ref_ != null) {
+              subBuilder = ref_.toBuilder();
+            }
+            ref_ = input.readMessage(io.grpc.channelz.v1.SocketRef.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(ref_);
+              ref_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            io.grpc.channelz.v1.SocketData.Builder subBuilder = null;
+            if (data_ != null) {
+              subBuilder = data_.toBuilder();
+            }
+            data_ = input.readMessage(io.grpc.channelz.v1.SocketData.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(data_);
+              data_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 26: {
+            io.grpc.channelz.v1.Address.Builder subBuilder = null;
+            if (local_ != null) {
+              subBuilder = local_.toBuilder();
+            }
+            local_ = input.readMessage(io.grpc.channelz.v1.Address.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(local_);
+              local_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 34: {
+            io.grpc.channelz.v1.Address.Builder subBuilder = null;
+            if (remote_ != null) {
+              subBuilder = remote_.toBuilder();
+            }
+            remote_ = input.readMessage(io.grpc.channelz.v1.Address.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(remote_);
+              remote_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 42: {
+            io.grpc.channelz.v1.Security.Builder subBuilder = null;
+            if (security_ != null) {
+              subBuilder = security_.toBuilder();
+            }
+            security_ = input.readMessage(io.grpc.channelz.v1.Security.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(security_);
+              security_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            remoteName_ = s;
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Socket_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Socket_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.Socket.class, io.grpc.channelz.v1.Socket.Builder.class);
+  }
+
+  public static final int REF_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.SocketRef ref_;
+  /**
+   * <code>.grpc.channelz.SocketRef ref = 1;</code>
+   */
+  public boolean hasRef() {
+    return ref_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.SocketRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.SocketRef getRef() {
+    return ref_ == null ? io.grpc.channelz.v1.SocketRef.getDefaultInstance() : ref_;
+  }
+  /**
+   * <code>.grpc.channelz.SocketRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.SocketRefOrBuilder getRefOrBuilder() {
+    return getRef();
+  }
+
+  public static final int DATA_FIELD_NUMBER = 2;
+  private io.grpc.channelz.v1.SocketData data_;
+  /**
+   * <code>.grpc.channelz.SocketData data = 2;</code>
+   */
+  public boolean hasData() {
+    return data_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.SocketData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.SocketData getData() {
+    return data_ == null ? io.grpc.channelz.v1.SocketData.getDefaultInstance() : data_;
+  }
+  /**
+   * <code>.grpc.channelz.SocketData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.SocketDataOrBuilder getDataOrBuilder() {
+    return getData();
+  }
+
+  public static final int LOCAL_FIELD_NUMBER = 3;
+  private io.grpc.channelz.v1.Address local_;
+  /**
+   * <pre>
+   * The locally bound address.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address local = 3;</code>
+   */
+  public boolean hasLocal() {
+    return local_ != null;
+  }
+  /**
+   * <pre>
+   * The locally bound address.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address local = 3;</code>
+   */
+  public io.grpc.channelz.v1.Address getLocal() {
+    return local_ == null ? io.grpc.channelz.v1.Address.getDefaultInstance() : local_;
+  }
+  /**
+   * <pre>
+   * The locally bound address.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address local = 3;</code>
+   */
+  public io.grpc.channelz.v1.AddressOrBuilder getLocalOrBuilder() {
+    return getLocal();
+  }
+
+  public static final int REMOTE_FIELD_NUMBER = 4;
+  private io.grpc.channelz.v1.Address remote_;
+  /**
+   * <pre>
+   * The remote bound address.  May be absent.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address remote = 4;</code>
+   */
+  public boolean hasRemote() {
+    return remote_ != null;
+  }
+  /**
+   * <pre>
+   * The remote bound address.  May be absent.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address remote = 4;</code>
+   */
+  public io.grpc.channelz.v1.Address getRemote() {
+    return remote_ == null ? io.grpc.channelz.v1.Address.getDefaultInstance() : remote_;
+  }
+  /**
+   * <pre>
+   * The remote bound address.  May be absent.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address remote = 4;</code>
+   */
+  public io.grpc.channelz.v1.AddressOrBuilder getRemoteOrBuilder() {
+    return getRemote();
+  }
+
+  public static final int SECURITY_FIELD_NUMBER = 5;
+  private io.grpc.channelz.v1.Security security_;
+  /**
+   * <code>.grpc.channelz.Security security = 5;</code>
+   */
+  public boolean hasSecurity() {
+    return security_ != null;
+  }
+  /**
+   * <code>.grpc.channelz.Security security = 5;</code>
+   */
+  public io.grpc.channelz.v1.Security getSecurity() {
+    return security_ == null ? io.grpc.channelz.v1.Security.getDefaultInstance() : security_;
+  }
+  /**
+   * <code>.grpc.channelz.Security security = 5;</code>
+   */
+  public io.grpc.channelz.v1.SecurityOrBuilder getSecurityOrBuilder() {
+    return getSecurity();
+  }
+
+  public static final int REMOTE_NAME_FIELD_NUMBER = 6;
+  private volatile java.lang.Object remoteName_;
+  /**
+   * <pre>
+   * Optional, represents the name of the remote endpoint, if different than
+   * the original target name.
+   * </pre>
+   *
+   * <code>string remote_name = 6;</code>
+   */
+  public java.lang.String getRemoteName() {
+    java.lang.Object ref = remoteName_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      remoteName_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * Optional, represents the name of the remote endpoint, if different than
+   * the original target name.
+   * </pre>
+   *
+   * <code>string remote_name = 6;</code>
+   */
+  public com.google.protobuf.ByteString
+      getRemoteNameBytes() {
+    java.lang.Object ref = remoteName_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      remoteName_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (ref_ != null) {
+      output.writeMessage(1, getRef());
+    }
+    if (data_ != null) {
+      output.writeMessage(2, getData());
+    }
+    if (local_ != null) {
+      output.writeMessage(3, getLocal());
+    }
+    if (remote_ != null) {
+      output.writeMessage(4, getRemote());
+    }
+    if (security_ != null) {
+      output.writeMessage(5, getSecurity());
+    }
+    if (!getRemoteNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, remoteName_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (ref_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getRef());
+    }
+    if (data_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, getData());
+    }
+    if (local_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, getLocal());
+    }
+    if (remote_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(4, getRemote());
+    }
+    if (security_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(5, getSecurity());
+    }
+    if (!getRemoteNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, remoteName_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.Socket)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.Socket other = (io.grpc.channelz.v1.Socket) obj;
+
+    boolean result = true;
+    result = result && (hasRef() == other.hasRef());
+    if (hasRef()) {
+      result = result && getRef()
+          .equals(other.getRef());
+    }
+    result = result && (hasData() == other.hasData());
+    if (hasData()) {
+      result = result && getData()
+          .equals(other.getData());
+    }
+    result = result && (hasLocal() == other.hasLocal());
+    if (hasLocal()) {
+      result = result && getLocal()
+          .equals(other.getLocal());
+    }
+    result = result && (hasRemote() == other.hasRemote());
+    if (hasRemote()) {
+      result = result && getRemote()
+          .equals(other.getRemote());
+    }
+    result = result && (hasSecurity() == other.hasSecurity());
+    if (hasSecurity()) {
+      result = result && getSecurity()
+          .equals(other.getSecurity());
+    }
+    result = result && getRemoteName()
+        .equals(other.getRemoteName());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasRef()) {
+      hash = (37 * hash) + REF_FIELD_NUMBER;
+      hash = (53 * hash) + getRef().hashCode();
+    }
+    if (hasData()) {
+      hash = (37 * hash) + DATA_FIELD_NUMBER;
+      hash = (53 * hash) + getData().hashCode();
+    }
+    if (hasLocal()) {
+      hash = (37 * hash) + LOCAL_FIELD_NUMBER;
+      hash = (53 * hash) + getLocal().hashCode();
+    }
+    if (hasRemote()) {
+      hash = (37 * hash) + REMOTE_FIELD_NUMBER;
+      hash = (53 * hash) + getRemote().hashCode();
+    }
+    if (hasSecurity()) {
+      hash = (37 * hash) + SECURITY_FIELD_NUMBER;
+      hash = (53 * hash) + getSecurity().hashCode();
+    }
+    hash = (37 * hash) + REMOTE_NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getRemoteName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Socket parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Socket parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Socket parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.Socket prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * Information about an actual connection.  Pronounced "sock-ay".
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.Socket}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.Socket)
+      io.grpc.channelz.v1.SocketOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Socket_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Socket_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Socket.class, io.grpc.channelz.v1.Socket.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.Socket.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (refBuilder_ == null) {
+        ref_ = null;
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+      if (dataBuilder_ == null) {
+        data_ = null;
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+      if (localBuilder_ == null) {
+        local_ = null;
+      } else {
+        local_ = null;
+        localBuilder_ = null;
+      }
+      if (remoteBuilder_ == null) {
+        remote_ = null;
+      } else {
+        remote_ = null;
+        remoteBuilder_ = null;
+      }
+      if (securityBuilder_ == null) {
+        security_ = null;
+      } else {
+        security_ = null;
+        securityBuilder_ = null;
+      }
+      remoteName_ = "";
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Socket_descriptor;
+    }
+
+    public io.grpc.channelz.v1.Socket getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.Socket.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.Socket build() {
+      io.grpc.channelz.v1.Socket result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.Socket buildPartial() {
+      io.grpc.channelz.v1.Socket result = new io.grpc.channelz.v1.Socket(this);
+      if (refBuilder_ == null) {
+        result.ref_ = ref_;
+      } else {
+        result.ref_ = refBuilder_.build();
+      }
+      if (dataBuilder_ == null) {
+        result.data_ = data_;
+      } else {
+        result.data_ = dataBuilder_.build();
+      }
+      if (localBuilder_ == null) {
+        result.local_ = local_;
+      } else {
+        result.local_ = localBuilder_.build();
+      }
+      if (remoteBuilder_ == null) {
+        result.remote_ = remote_;
+      } else {
+        result.remote_ = remoteBuilder_.build();
+      }
+      if (securityBuilder_ == null) {
+        result.security_ = security_;
+      } else {
+        result.security_ = securityBuilder_.build();
+      }
+      result.remoteName_ = remoteName_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.Socket) {
+        return mergeFrom((io.grpc.channelz.v1.Socket)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.Socket other) {
+      if (other == io.grpc.channelz.v1.Socket.getDefaultInstance()) return this;
+      if (other.hasRef()) {
+        mergeRef(other.getRef());
+      }
+      if (other.hasData()) {
+        mergeData(other.getData());
+      }
+      if (other.hasLocal()) {
+        mergeLocal(other.getLocal());
+      }
+      if (other.hasRemote()) {
+        mergeRemote(other.getRemote());
+      }
+      if (other.hasSecurity()) {
+        mergeSecurity(other.getSecurity());
+      }
+      if (!other.getRemoteName().isEmpty()) {
+        remoteName_ = other.remoteName_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.Socket parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.Socket) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.grpc.channelz.v1.SocketRef ref_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> refBuilder_;
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public boolean hasRef() {
+      return refBuilder_ != null || ref_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef getRef() {
+      if (refBuilder_ == null) {
+        return ref_ == null ? io.grpc.channelz.v1.SocketRef.getDefaultInstance() : ref_;
+      } else {
+        return refBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public Builder setRef(io.grpc.channelz.v1.SocketRef value) {
+      if (refBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ref_ = value;
+        onChanged();
+      } else {
+        refBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public Builder setRef(
+        io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (refBuilder_ == null) {
+        ref_ = builderForValue.build();
+        onChanged();
+      } else {
+        refBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public Builder mergeRef(io.grpc.channelz.v1.SocketRef value) {
+      if (refBuilder_ == null) {
+        if (ref_ != null) {
+          ref_ =
+            io.grpc.channelz.v1.SocketRef.newBuilder(ref_).mergeFrom(value).buildPartial();
+        } else {
+          ref_ = value;
+        }
+        onChanged();
+      } else {
+        refBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public Builder clearRef() {
+      if (refBuilder_ == null) {
+        ref_ = null;
+        onChanged();
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder getRefBuilder() {
+      
+      onChanged();
+      return getRefFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SocketRefOrBuilder getRefOrBuilder() {
+      if (refBuilder_ != null) {
+        return refBuilder_.getMessageOrBuilder();
+      } else {
+        return ref_ == null ?
+            io.grpc.channelz.v1.SocketRef.getDefaultInstance() : ref_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.SocketRef ref = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> 
+        getRefFieldBuilder() {
+      if (refBuilder_ == null) {
+        refBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder>(
+                getRef(),
+                getParentForChildren(),
+                isClean());
+        ref_ = null;
+      }
+      return refBuilder_;
+    }
+
+    private io.grpc.channelz.v1.SocketData data_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.SocketData, io.grpc.channelz.v1.SocketData.Builder, io.grpc.channelz.v1.SocketDataOrBuilder> dataBuilder_;
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public boolean hasData() {
+      return dataBuilder_ != null || data_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.SocketData getData() {
+      if (dataBuilder_ == null) {
+        return data_ == null ? io.grpc.channelz.v1.SocketData.getDefaultInstance() : data_;
+      } else {
+        return dataBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public Builder setData(io.grpc.channelz.v1.SocketData value) {
+      if (dataBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        data_ = value;
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public Builder setData(
+        io.grpc.channelz.v1.SocketData.Builder builderForValue) {
+      if (dataBuilder_ == null) {
+        data_ = builderForValue.build();
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public Builder mergeData(io.grpc.channelz.v1.SocketData value) {
+      if (dataBuilder_ == null) {
+        if (data_ != null) {
+          data_ =
+            io.grpc.channelz.v1.SocketData.newBuilder(data_).mergeFrom(value).buildPartial();
+        } else {
+          data_ = value;
+        }
+        onChanged();
+      } else {
+        dataBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public Builder clearData() {
+      if (dataBuilder_ == null) {
+        data_ = null;
+        onChanged();
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.SocketData.Builder getDataBuilder() {
+      
+      onChanged();
+      return getDataFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.SocketDataOrBuilder getDataOrBuilder() {
+      if (dataBuilder_ != null) {
+        return dataBuilder_.getMessageOrBuilder();
+      } else {
+        return data_ == null ?
+            io.grpc.channelz.v1.SocketData.getDefaultInstance() : data_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.SocketData data = 2;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.SocketData, io.grpc.channelz.v1.SocketData.Builder, io.grpc.channelz.v1.SocketDataOrBuilder> 
+        getDataFieldBuilder() {
+      if (dataBuilder_ == null) {
+        dataBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.SocketData, io.grpc.channelz.v1.SocketData.Builder, io.grpc.channelz.v1.SocketDataOrBuilder>(
+                getData(),
+                getParentForChildren(),
+                isClean());
+        data_ = null;
+      }
+      return dataBuilder_;
+    }
+
+    private io.grpc.channelz.v1.Address local_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address, io.grpc.channelz.v1.Address.Builder, io.grpc.channelz.v1.AddressOrBuilder> localBuilder_;
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public boolean hasLocal() {
+      return localBuilder_ != null || local_ != null;
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public io.grpc.channelz.v1.Address getLocal() {
+      if (localBuilder_ == null) {
+        return local_ == null ? io.grpc.channelz.v1.Address.getDefaultInstance() : local_;
+      } else {
+        return localBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public Builder setLocal(io.grpc.channelz.v1.Address value) {
+      if (localBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        local_ = value;
+        onChanged();
+      } else {
+        localBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public Builder setLocal(
+        io.grpc.channelz.v1.Address.Builder builderForValue) {
+      if (localBuilder_ == null) {
+        local_ = builderForValue.build();
+        onChanged();
+      } else {
+        localBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public Builder mergeLocal(io.grpc.channelz.v1.Address value) {
+      if (localBuilder_ == null) {
+        if (local_ != null) {
+          local_ =
+            io.grpc.channelz.v1.Address.newBuilder(local_).mergeFrom(value).buildPartial();
+        } else {
+          local_ = value;
+        }
+        onChanged();
+      } else {
+        localBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public Builder clearLocal() {
+      if (localBuilder_ == null) {
+        local_ = null;
+        onChanged();
+      } else {
+        local_ = null;
+        localBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public io.grpc.channelz.v1.Address.Builder getLocalBuilder() {
+      
+      onChanged();
+      return getLocalFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    public io.grpc.channelz.v1.AddressOrBuilder getLocalOrBuilder() {
+      if (localBuilder_ != null) {
+        return localBuilder_.getMessageOrBuilder();
+      } else {
+        return local_ == null ?
+            io.grpc.channelz.v1.Address.getDefaultInstance() : local_;
+      }
+    }
+    /**
+     * <pre>
+     * The locally bound address.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address local = 3;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address, io.grpc.channelz.v1.Address.Builder, io.grpc.channelz.v1.AddressOrBuilder> 
+        getLocalFieldBuilder() {
+      if (localBuilder_ == null) {
+        localBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Address, io.grpc.channelz.v1.Address.Builder, io.grpc.channelz.v1.AddressOrBuilder>(
+                getLocal(),
+                getParentForChildren(),
+                isClean());
+        local_ = null;
+      }
+      return localBuilder_;
+    }
+
+    private io.grpc.channelz.v1.Address remote_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address, io.grpc.channelz.v1.Address.Builder, io.grpc.channelz.v1.AddressOrBuilder> remoteBuilder_;
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public boolean hasRemote() {
+      return remoteBuilder_ != null || remote_ != null;
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public io.grpc.channelz.v1.Address getRemote() {
+      if (remoteBuilder_ == null) {
+        return remote_ == null ? io.grpc.channelz.v1.Address.getDefaultInstance() : remote_;
+      } else {
+        return remoteBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public Builder setRemote(io.grpc.channelz.v1.Address value) {
+      if (remoteBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        remote_ = value;
+        onChanged();
+      } else {
+        remoteBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public Builder setRemote(
+        io.grpc.channelz.v1.Address.Builder builderForValue) {
+      if (remoteBuilder_ == null) {
+        remote_ = builderForValue.build();
+        onChanged();
+      } else {
+        remoteBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public Builder mergeRemote(io.grpc.channelz.v1.Address value) {
+      if (remoteBuilder_ == null) {
+        if (remote_ != null) {
+          remote_ =
+            io.grpc.channelz.v1.Address.newBuilder(remote_).mergeFrom(value).buildPartial();
+        } else {
+          remote_ = value;
+        }
+        onChanged();
+      } else {
+        remoteBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public Builder clearRemote() {
+      if (remoteBuilder_ == null) {
+        remote_ = null;
+        onChanged();
+      } else {
+        remote_ = null;
+        remoteBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public io.grpc.channelz.v1.Address.Builder getRemoteBuilder() {
+      
+      onChanged();
+      return getRemoteFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    public io.grpc.channelz.v1.AddressOrBuilder getRemoteOrBuilder() {
+      if (remoteBuilder_ != null) {
+        return remoteBuilder_.getMessageOrBuilder();
+      } else {
+        return remote_ == null ?
+            io.grpc.channelz.v1.Address.getDefaultInstance() : remote_;
+      }
+    }
+    /**
+     * <pre>
+     * The remote bound address.  May be absent.
+     * </pre>
+     *
+     * <code>.grpc.channelz.Address remote = 4;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Address, io.grpc.channelz.v1.Address.Builder, io.grpc.channelz.v1.AddressOrBuilder> 
+        getRemoteFieldBuilder() {
+      if (remoteBuilder_ == null) {
+        remoteBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Address, io.grpc.channelz.v1.Address.Builder, io.grpc.channelz.v1.AddressOrBuilder>(
+                getRemote(),
+                getParentForChildren(),
+                isClean());
+        remote_ = null;
+      }
+      return remoteBuilder_;
+    }
+
+    private io.grpc.channelz.v1.Security security_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Security, io.grpc.channelz.v1.Security.Builder, io.grpc.channelz.v1.SecurityOrBuilder> securityBuilder_;
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public boolean hasSecurity() {
+      return securityBuilder_ != null || security_ != null;
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public io.grpc.channelz.v1.Security getSecurity() {
+      if (securityBuilder_ == null) {
+        return security_ == null ? io.grpc.channelz.v1.Security.getDefaultInstance() : security_;
+      } else {
+        return securityBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public Builder setSecurity(io.grpc.channelz.v1.Security value) {
+      if (securityBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        security_ = value;
+        onChanged();
+      } else {
+        securityBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public Builder setSecurity(
+        io.grpc.channelz.v1.Security.Builder builderForValue) {
+      if (securityBuilder_ == null) {
+        security_ = builderForValue.build();
+        onChanged();
+      } else {
+        securityBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public Builder mergeSecurity(io.grpc.channelz.v1.Security value) {
+      if (securityBuilder_ == null) {
+        if (security_ != null) {
+          security_ =
+            io.grpc.channelz.v1.Security.newBuilder(security_).mergeFrom(value).buildPartial();
+        } else {
+          security_ = value;
+        }
+        onChanged();
+      } else {
+        securityBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public Builder clearSecurity() {
+      if (securityBuilder_ == null) {
+        security_ = null;
+        onChanged();
+      } else {
+        security_ = null;
+        securityBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public io.grpc.channelz.v1.Security.Builder getSecurityBuilder() {
+      
+      onChanged();
+      return getSecurityFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    public io.grpc.channelz.v1.SecurityOrBuilder getSecurityOrBuilder() {
+      if (securityBuilder_ != null) {
+        return securityBuilder_.getMessageOrBuilder();
+      } else {
+        return security_ == null ?
+            io.grpc.channelz.v1.Security.getDefaultInstance() : security_;
+      }
+    }
+    /**
+     * <code>.grpc.channelz.Security security = 5;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.Security, io.grpc.channelz.v1.Security.Builder, io.grpc.channelz.v1.SecurityOrBuilder> 
+        getSecurityFieldBuilder() {
+      if (securityBuilder_ == null) {
+        securityBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.Security, io.grpc.channelz.v1.Security.Builder, io.grpc.channelz.v1.SecurityOrBuilder>(
+                getSecurity(),
+                getParentForChildren(),
+                isClean());
+        security_ = null;
+      }
+      return securityBuilder_;
+    }
+
+    private java.lang.Object remoteName_ = "";
+    /**
+     * <pre>
+     * Optional, represents the name of the remote endpoint, if different than
+     * the original target name.
+     * </pre>
+     *
+     * <code>string remote_name = 6;</code>
+     */
+    public java.lang.String getRemoteName() {
+      java.lang.Object ref = remoteName_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        remoteName_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * Optional, represents the name of the remote endpoint, if different than
+     * the original target name.
+     * </pre>
+     *
+     * <code>string remote_name = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getRemoteNameBytes() {
+      java.lang.Object ref = remoteName_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        remoteName_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * Optional, represents the name of the remote endpoint, if different than
+     * the original target name.
+     * </pre>
+     *
+     * <code>string remote_name = 6;</code>
+     */
+    public Builder setRemoteName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      remoteName_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * Optional, represents the name of the remote endpoint, if different than
+     * the original target name.
+     * </pre>
+     *
+     * <code>string remote_name = 6;</code>
+     */
+    public Builder clearRemoteName() {
+      
+      remoteName_ = getDefaultInstance().getRemoteName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * Optional, represents the name of the remote endpoint, if different than
+     * the original target name.
+     * </pre>
+     *
+     * <code>string remote_name = 6;</code>
+     */
+    public Builder setRemoteNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      remoteName_ = value;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.Socket)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.Socket)
+  private static final io.grpc.channelz.v1.Socket DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.Socket();
+  }
+
+  public static io.grpc.channelz.v1.Socket getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<Socket>
+      PARSER = new com.google.protobuf.AbstractParser<Socket>() {
+    public Socket parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new Socket(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<Socket> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<Socket> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.Socket getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketData.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketData.java
new file mode 100644
index 0000000..18bbbfa
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketData.java
@@ -0,0 +1,2625 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.SocketData}
+ */
+public  final class SocketData extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.SocketData)
+    SocketDataOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use SocketData.newBuilder() to construct.
+  private SocketData(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private SocketData() {
+    streamsStarted_ = 0L;
+    streamsSucceeded_ = 0L;
+    streamsFailed_ = 0L;
+    messagesSent_ = 0L;
+    messagesReceived_ = 0L;
+    keepAlivesSent_ = 0L;
+    option_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private SocketData(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            streamsStarted_ = input.readInt64();
+            break;
+          }
+          case 16: {
+
+            streamsSucceeded_ = input.readInt64();
+            break;
+          }
+          case 24: {
+
+            streamsFailed_ = input.readInt64();
+            break;
+          }
+          case 32: {
+
+            messagesSent_ = input.readInt64();
+            break;
+          }
+          case 40: {
+
+            messagesReceived_ = input.readInt64();
+            break;
+          }
+          case 48: {
+
+            keepAlivesSent_ = input.readInt64();
+            break;
+          }
+          case 58: {
+            com.google.protobuf.Timestamp.Builder subBuilder = null;
+            if (lastLocalStreamCreatedTimestamp_ != null) {
+              subBuilder = lastLocalStreamCreatedTimestamp_.toBuilder();
+            }
+            lastLocalStreamCreatedTimestamp_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(lastLocalStreamCreatedTimestamp_);
+              lastLocalStreamCreatedTimestamp_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 66: {
+            com.google.protobuf.Timestamp.Builder subBuilder = null;
+            if (lastRemoteStreamCreatedTimestamp_ != null) {
+              subBuilder = lastRemoteStreamCreatedTimestamp_.toBuilder();
+            }
+            lastRemoteStreamCreatedTimestamp_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(lastRemoteStreamCreatedTimestamp_);
+              lastRemoteStreamCreatedTimestamp_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 74: {
+            com.google.protobuf.Timestamp.Builder subBuilder = null;
+            if (lastMessageSentTimestamp_ != null) {
+              subBuilder = lastMessageSentTimestamp_.toBuilder();
+            }
+            lastMessageSentTimestamp_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(lastMessageSentTimestamp_);
+              lastMessageSentTimestamp_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 82: {
+            com.google.protobuf.Timestamp.Builder subBuilder = null;
+            if (lastMessageReceivedTimestamp_ != null) {
+              subBuilder = lastMessageReceivedTimestamp_.toBuilder();
+            }
+            lastMessageReceivedTimestamp_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(lastMessageReceivedTimestamp_);
+              lastMessageReceivedTimestamp_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 90: {
+            com.google.protobuf.Int64Value.Builder subBuilder = null;
+            if (localFlowControlWindow_ != null) {
+              subBuilder = localFlowControlWindow_.toBuilder();
+            }
+            localFlowControlWindow_ = input.readMessage(com.google.protobuf.Int64Value.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(localFlowControlWindow_);
+              localFlowControlWindow_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 98: {
+            com.google.protobuf.Int64Value.Builder subBuilder = null;
+            if (remoteFlowControlWindow_ != null) {
+              subBuilder = remoteFlowControlWindow_.toBuilder();
+            }
+            remoteFlowControlWindow_ = input.readMessage(com.google.protobuf.Int64Value.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(remoteFlowControlWindow_);
+              remoteFlowControlWindow_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 106: {
+            if (!((mutable_bitField0_ & 0x00001000) == 0x00001000)) {
+              option_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketOption>();
+              mutable_bitField0_ |= 0x00001000;
+            }
+            option_.add(
+                input.readMessage(io.grpc.channelz.v1.SocketOption.parser(), extensionRegistry));
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00001000) == 0x00001000)) {
+        option_ = java.util.Collections.unmodifiableList(option_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketData_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketData_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.SocketData.class, io.grpc.channelz.v1.SocketData.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int STREAMS_STARTED_FIELD_NUMBER = 1;
+  private long streamsStarted_;
+  /**
+   * <pre>
+   * The number of streams that have been started.
+   * </pre>
+   *
+   * <code>int64 streams_started = 1;</code>
+   */
+  public long getStreamsStarted() {
+    return streamsStarted_;
+  }
+
+  public static final int STREAMS_SUCCEEDED_FIELD_NUMBER = 2;
+  private long streamsSucceeded_;
+  /**
+   * <pre>
+   * The number of streams that have ended successfully with the EoS bit set for
+   *  both end points
+   * </pre>
+   *
+   * <code>int64 streams_succeeded = 2;</code>
+   */
+  public long getStreamsSucceeded() {
+    return streamsSucceeded_;
+  }
+
+  public static final int STREAMS_FAILED_FIELD_NUMBER = 3;
+  private long streamsFailed_;
+  /**
+   * <pre>
+   * The number of incoming streams that have a completed with a non-OK status
+   * </pre>
+   *
+   * <code>int64 streams_failed = 3;</code>
+   */
+  public long getStreamsFailed() {
+    return streamsFailed_;
+  }
+
+  public static final int MESSAGES_SENT_FIELD_NUMBER = 4;
+  private long messagesSent_;
+  /**
+   * <pre>
+   * The number of messages successfully sent on this socket.
+   * </pre>
+   *
+   * <code>int64 messages_sent = 4;</code>
+   */
+  public long getMessagesSent() {
+    return messagesSent_;
+  }
+
+  public static final int MESSAGES_RECEIVED_FIELD_NUMBER = 5;
+  private long messagesReceived_;
+  /**
+   * <code>int64 messages_received = 5;</code>
+   */
+  public long getMessagesReceived() {
+    return messagesReceived_;
+  }
+
+  public static final int KEEP_ALIVES_SENT_FIELD_NUMBER = 6;
+  private long keepAlivesSent_;
+  /**
+   * <pre>
+   * The number of keep alives sent.  This is typically implemented with HTTP/2
+   * ping messages.
+   * </pre>
+   *
+   * <code>int64 keep_alives_sent = 6;</code>
+   */
+  public long getKeepAlivesSent() {
+    return keepAlivesSent_;
+  }
+
+  public static final int LAST_LOCAL_STREAM_CREATED_TIMESTAMP_FIELD_NUMBER = 7;
+  private com.google.protobuf.Timestamp lastLocalStreamCreatedTimestamp_;
+  /**
+   * <pre>
+   * The last time a stream was created by this endpoint.  Usually unset for
+   * servers.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+   */
+  public boolean hasLastLocalStreamCreatedTimestamp() {
+    return lastLocalStreamCreatedTimestamp_ != null;
+  }
+  /**
+   * <pre>
+   * The last time a stream was created by this endpoint.  Usually unset for
+   * servers.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+   */
+  public com.google.protobuf.Timestamp getLastLocalStreamCreatedTimestamp() {
+    return lastLocalStreamCreatedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastLocalStreamCreatedTimestamp_;
+  }
+  /**
+   * <pre>
+   * The last time a stream was created by this endpoint.  Usually unset for
+   * servers.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+   */
+  public com.google.protobuf.TimestampOrBuilder getLastLocalStreamCreatedTimestampOrBuilder() {
+    return getLastLocalStreamCreatedTimestamp();
+  }
+
+  public static final int LAST_REMOTE_STREAM_CREATED_TIMESTAMP_FIELD_NUMBER = 8;
+  private com.google.protobuf.Timestamp lastRemoteStreamCreatedTimestamp_;
+  /**
+   * <pre>
+   * The last time a stream was created by the remote endpoint.  Usually unset
+   * for clients.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+   */
+  public boolean hasLastRemoteStreamCreatedTimestamp() {
+    return lastRemoteStreamCreatedTimestamp_ != null;
+  }
+  /**
+   * <pre>
+   * The last time a stream was created by the remote endpoint.  Usually unset
+   * for clients.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+   */
+  public com.google.protobuf.Timestamp getLastRemoteStreamCreatedTimestamp() {
+    return lastRemoteStreamCreatedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastRemoteStreamCreatedTimestamp_;
+  }
+  /**
+   * <pre>
+   * The last time a stream was created by the remote endpoint.  Usually unset
+   * for clients.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+   */
+  public com.google.protobuf.TimestampOrBuilder getLastRemoteStreamCreatedTimestampOrBuilder() {
+    return getLastRemoteStreamCreatedTimestamp();
+  }
+
+  public static final int LAST_MESSAGE_SENT_TIMESTAMP_FIELD_NUMBER = 9;
+  private com.google.protobuf.Timestamp lastMessageSentTimestamp_;
+  /**
+   * <pre>
+   * The last time a message was sent by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+   */
+  public boolean hasLastMessageSentTimestamp() {
+    return lastMessageSentTimestamp_ != null;
+  }
+  /**
+   * <pre>
+   * The last time a message was sent by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+   */
+  public com.google.protobuf.Timestamp getLastMessageSentTimestamp() {
+    return lastMessageSentTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastMessageSentTimestamp_;
+  }
+  /**
+   * <pre>
+   * The last time a message was sent by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+   */
+  public com.google.protobuf.TimestampOrBuilder getLastMessageSentTimestampOrBuilder() {
+    return getLastMessageSentTimestamp();
+  }
+
+  public static final int LAST_MESSAGE_RECEIVED_TIMESTAMP_FIELD_NUMBER = 10;
+  private com.google.protobuf.Timestamp lastMessageReceivedTimestamp_;
+  /**
+   * <pre>
+   * The last time a message was received by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+   */
+  public boolean hasLastMessageReceivedTimestamp() {
+    return lastMessageReceivedTimestamp_ != null;
+  }
+  /**
+   * <pre>
+   * The last time a message was received by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+   */
+  public com.google.protobuf.Timestamp getLastMessageReceivedTimestamp() {
+    return lastMessageReceivedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastMessageReceivedTimestamp_;
+  }
+  /**
+   * <pre>
+   * The last time a message was received by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+   */
+  public com.google.protobuf.TimestampOrBuilder getLastMessageReceivedTimestampOrBuilder() {
+    return getLastMessageReceivedTimestamp();
+  }
+
+  public static final int LOCAL_FLOW_CONTROL_WINDOW_FIELD_NUMBER = 11;
+  private com.google.protobuf.Int64Value localFlowControlWindow_;
+  /**
+   * <pre>
+   * The amount of window, granted to the local endpoint by the remote endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+   */
+  public boolean hasLocalFlowControlWindow() {
+    return localFlowControlWindow_ != null;
+  }
+  /**
+   * <pre>
+   * The amount of window, granted to the local endpoint by the remote endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+   */
+  public com.google.protobuf.Int64Value getLocalFlowControlWindow() {
+    return localFlowControlWindow_ == null ? com.google.protobuf.Int64Value.getDefaultInstance() : localFlowControlWindow_;
+  }
+  /**
+   * <pre>
+   * The amount of window, granted to the local endpoint by the remote endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+   */
+  public com.google.protobuf.Int64ValueOrBuilder getLocalFlowControlWindowOrBuilder() {
+    return getLocalFlowControlWindow();
+  }
+
+  public static final int REMOTE_FLOW_CONTROL_WINDOW_FIELD_NUMBER = 12;
+  private com.google.protobuf.Int64Value remoteFlowControlWindow_;
+  /**
+   * <pre>
+   * The amount of window, granted to the remote endpoint by the local endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+   */
+  public boolean hasRemoteFlowControlWindow() {
+    return remoteFlowControlWindow_ != null;
+  }
+  /**
+   * <pre>
+   * The amount of window, granted to the remote endpoint by the local endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+   */
+  public com.google.protobuf.Int64Value getRemoteFlowControlWindow() {
+    return remoteFlowControlWindow_ == null ? com.google.protobuf.Int64Value.getDefaultInstance() : remoteFlowControlWindow_;
+  }
+  /**
+   * <pre>
+   * The amount of window, granted to the remote endpoint by the local endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+   */
+  public com.google.protobuf.Int64ValueOrBuilder getRemoteFlowControlWindowOrBuilder() {
+    return getRemoteFlowControlWindow();
+  }
+
+  public static final int OPTION_FIELD_NUMBER = 13;
+  private java.util.List<io.grpc.channelz.v1.SocketOption> option_;
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.SocketOption> getOptionList() {
+    return option_;
+  }
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.SocketOptionOrBuilder> 
+      getOptionOrBuilderList() {
+    return option_;
+  }
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  public int getOptionCount() {
+    return option_.size();
+  }
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  public io.grpc.channelz.v1.SocketOption getOption(int index) {
+    return option_.get(index);
+  }
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  public io.grpc.channelz.v1.SocketOptionOrBuilder getOptionOrBuilder(
+      int index) {
+    return option_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (streamsStarted_ != 0L) {
+      output.writeInt64(1, streamsStarted_);
+    }
+    if (streamsSucceeded_ != 0L) {
+      output.writeInt64(2, streamsSucceeded_);
+    }
+    if (streamsFailed_ != 0L) {
+      output.writeInt64(3, streamsFailed_);
+    }
+    if (messagesSent_ != 0L) {
+      output.writeInt64(4, messagesSent_);
+    }
+    if (messagesReceived_ != 0L) {
+      output.writeInt64(5, messagesReceived_);
+    }
+    if (keepAlivesSent_ != 0L) {
+      output.writeInt64(6, keepAlivesSent_);
+    }
+    if (lastLocalStreamCreatedTimestamp_ != null) {
+      output.writeMessage(7, getLastLocalStreamCreatedTimestamp());
+    }
+    if (lastRemoteStreamCreatedTimestamp_ != null) {
+      output.writeMessage(8, getLastRemoteStreamCreatedTimestamp());
+    }
+    if (lastMessageSentTimestamp_ != null) {
+      output.writeMessage(9, getLastMessageSentTimestamp());
+    }
+    if (lastMessageReceivedTimestamp_ != null) {
+      output.writeMessage(10, getLastMessageReceivedTimestamp());
+    }
+    if (localFlowControlWindow_ != null) {
+      output.writeMessage(11, getLocalFlowControlWindow());
+    }
+    if (remoteFlowControlWindow_ != null) {
+      output.writeMessage(12, getRemoteFlowControlWindow());
+    }
+    for (int i = 0; i < option_.size(); i++) {
+      output.writeMessage(13, option_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (streamsStarted_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, streamsStarted_);
+    }
+    if (streamsSucceeded_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(2, streamsSucceeded_);
+    }
+    if (streamsFailed_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(3, streamsFailed_);
+    }
+    if (messagesSent_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(4, messagesSent_);
+    }
+    if (messagesReceived_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(5, messagesReceived_);
+    }
+    if (keepAlivesSent_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(6, keepAlivesSent_);
+    }
+    if (lastLocalStreamCreatedTimestamp_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(7, getLastLocalStreamCreatedTimestamp());
+    }
+    if (lastRemoteStreamCreatedTimestamp_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(8, getLastRemoteStreamCreatedTimestamp());
+    }
+    if (lastMessageSentTimestamp_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(9, getLastMessageSentTimestamp());
+    }
+    if (lastMessageReceivedTimestamp_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(10, getLastMessageReceivedTimestamp());
+    }
+    if (localFlowControlWindow_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(11, getLocalFlowControlWindow());
+    }
+    if (remoteFlowControlWindow_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(12, getRemoteFlowControlWindow());
+    }
+    for (int i = 0; i < option_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(13, option_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.SocketData)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.SocketData other = (io.grpc.channelz.v1.SocketData) obj;
+
+    boolean result = true;
+    result = result && (getStreamsStarted()
+        == other.getStreamsStarted());
+    result = result && (getStreamsSucceeded()
+        == other.getStreamsSucceeded());
+    result = result && (getStreamsFailed()
+        == other.getStreamsFailed());
+    result = result && (getMessagesSent()
+        == other.getMessagesSent());
+    result = result && (getMessagesReceived()
+        == other.getMessagesReceived());
+    result = result && (getKeepAlivesSent()
+        == other.getKeepAlivesSent());
+    result = result && (hasLastLocalStreamCreatedTimestamp() == other.hasLastLocalStreamCreatedTimestamp());
+    if (hasLastLocalStreamCreatedTimestamp()) {
+      result = result && getLastLocalStreamCreatedTimestamp()
+          .equals(other.getLastLocalStreamCreatedTimestamp());
+    }
+    result = result && (hasLastRemoteStreamCreatedTimestamp() == other.hasLastRemoteStreamCreatedTimestamp());
+    if (hasLastRemoteStreamCreatedTimestamp()) {
+      result = result && getLastRemoteStreamCreatedTimestamp()
+          .equals(other.getLastRemoteStreamCreatedTimestamp());
+    }
+    result = result && (hasLastMessageSentTimestamp() == other.hasLastMessageSentTimestamp());
+    if (hasLastMessageSentTimestamp()) {
+      result = result && getLastMessageSentTimestamp()
+          .equals(other.getLastMessageSentTimestamp());
+    }
+    result = result && (hasLastMessageReceivedTimestamp() == other.hasLastMessageReceivedTimestamp());
+    if (hasLastMessageReceivedTimestamp()) {
+      result = result && getLastMessageReceivedTimestamp()
+          .equals(other.getLastMessageReceivedTimestamp());
+    }
+    result = result && (hasLocalFlowControlWindow() == other.hasLocalFlowControlWindow());
+    if (hasLocalFlowControlWindow()) {
+      result = result && getLocalFlowControlWindow()
+          .equals(other.getLocalFlowControlWindow());
+    }
+    result = result && (hasRemoteFlowControlWindow() == other.hasRemoteFlowControlWindow());
+    if (hasRemoteFlowControlWindow()) {
+      result = result && getRemoteFlowControlWindow()
+          .equals(other.getRemoteFlowControlWindow());
+    }
+    result = result && getOptionList()
+        .equals(other.getOptionList());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + STREAMS_STARTED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getStreamsStarted());
+    hash = (37 * hash) + STREAMS_SUCCEEDED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getStreamsSucceeded());
+    hash = (37 * hash) + STREAMS_FAILED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getStreamsFailed());
+    hash = (37 * hash) + MESSAGES_SENT_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getMessagesSent());
+    hash = (37 * hash) + MESSAGES_RECEIVED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getMessagesReceived());
+    hash = (37 * hash) + KEEP_ALIVES_SENT_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getKeepAlivesSent());
+    if (hasLastLocalStreamCreatedTimestamp()) {
+      hash = (37 * hash) + LAST_LOCAL_STREAM_CREATED_TIMESTAMP_FIELD_NUMBER;
+      hash = (53 * hash) + getLastLocalStreamCreatedTimestamp().hashCode();
+    }
+    if (hasLastRemoteStreamCreatedTimestamp()) {
+      hash = (37 * hash) + LAST_REMOTE_STREAM_CREATED_TIMESTAMP_FIELD_NUMBER;
+      hash = (53 * hash) + getLastRemoteStreamCreatedTimestamp().hashCode();
+    }
+    if (hasLastMessageSentTimestamp()) {
+      hash = (37 * hash) + LAST_MESSAGE_SENT_TIMESTAMP_FIELD_NUMBER;
+      hash = (53 * hash) + getLastMessageSentTimestamp().hashCode();
+    }
+    if (hasLastMessageReceivedTimestamp()) {
+      hash = (37 * hash) + LAST_MESSAGE_RECEIVED_TIMESTAMP_FIELD_NUMBER;
+      hash = (53 * hash) + getLastMessageReceivedTimestamp().hashCode();
+    }
+    if (hasLocalFlowControlWindow()) {
+      hash = (37 * hash) + LOCAL_FLOW_CONTROL_WINDOW_FIELD_NUMBER;
+      hash = (53 * hash) + getLocalFlowControlWindow().hashCode();
+    }
+    if (hasRemoteFlowControlWindow()) {
+      hash = (37 * hash) + REMOTE_FLOW_CONTROL_WINDOW_FIELD_NUMBER;
+      hash = (53 * hash) + getRemoteFlowControlWindow().hashCode();
+    }
+    if (getOptionCount() > 0) {
+      hash = (37 * hash) + OPTION_FIELD_NUMBER;
+      hash = (53 * hash) + getOptionList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketData parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketData parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketData parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.SocketData prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.SocketData}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.SocketData)
+      io.grpc.channelz.v1.SocketDataOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketData_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketData_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.SocketData.class, io.grpc.channelz.v1.SocketData.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.SocketData.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getOptionFieldBuilder();
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      streamsStarted_ = 0L;
+
+      streamsSucceeded_ = 0L;
+
+      streamsFailed_ = 0L;
+
+      messagesSent_ = 0L;
+
+      messagesReceived_ = 0L;
+
+      keepAlivesSent_ = 0L;
+
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        lastLocalStreamCreatedTimestamp_ = null;
+      } else {
+        lastLocalStreamCreatedTimestamp_ = null;
+        lastLocalStreamCreatedTimestampBuilder_ = null;
+      }
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        lastRemoteStreamCreatedTimestamp_ = null;
+      } else {
+        lastRemoteStreamCreatedTimestamp_ = null;
+        lastRemoteStreamCreatedTimestampBuilder_ = null;
+      }
+      if (lastMessageSentTimestampBuilder_ == null) {
+        lastMessageSentTimestamp_ = null;
+      } else {
+        lastMessageSentTimestamp_ = null;
+        lastMessageSentTimestampBuilder_ = null;
+      }
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        lastMessageReceivedTimestamp_ = null;
+      } else {
+        lastMessageReceivedTimestamp_ = null;
+        lastMessageReceivedTimestampBuilder_ = null;
+      }
+      if (localFlowControlWindowBuilder_ == null) {
+        localFlowControlWindow_ = null;
+      } else {
+        localFlowControlWindow_ = null;
+        localFlowControlWindowBuilder_ = null;
+      }
+      if (remoteFlowControlWindowBuilder_ == null) {
+        remoteFlowControlWindow_ = null;
+      } else {
+        remoteFlowControlWindow_ = null;
+        remoteFlowControlWindowBuilder_ = null;
+      }
+      if (optionBuilder_ == null) {
+        option_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00001000);
+      } else {
+        optionBuilder_.clear();
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketData_descriptor;
+    }
+
+    public io.grpc.channelz.v1.SocketData getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.SocketData.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.SocketData build() {
+      io.grpc.channelz.v1.SocketData result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.SocketData buildPartial() {
+      io.grpc.channelz.v1.SocketData result = new io.grpc.channelz.v1.SocketData(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      result.streamsStarted_ = streamsStarted_;
+      result.streamsSucceeded_ = streamsSucceeded_;
+      result.streamsFailed_ = streamsFailed_;
+      result.messagesSent_ = messagesSent_;
+      result.messagesReceived_ = messagesReceived_;
+      result.keepAlivesSent_ = keepAlivesSent_;
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        result.lastLocalStreamCreatedTimestamp_ = lastLocalStreamCreatedTimestamp_;
+      } else {
+        result.lastLocalStreamCreatedTimestamp_ = lastLocalStreamCreatedTimestampBuilder_.build();
+      }
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        result.lastRemoteStreamCreatedTimestamp_ = lastRemoteStreamCreatedTimestamp_;
+      } else {
+        result.lastRemoteStreamCreatedTimestamp_ = lastRemoteStreamCreatedTimestampBuilder_.build();
+      }
+      if (lastMessageSentTimestampBuilder_ == null) {
+        result.lastMessageSentTimestamp_ = lastMessageSentTimestamp_;
+      } else {
+        result.lastMessageSentTimestamp_ = lastMessageSentTimestampBuilder_.build();
+      }
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        result.lastMessageReceivedTimestamp_ = lastMessageReceivedTimestamp_;
+      } else {
+        result.lastMessageReceivedTimestamp_ = lastMessageReceivedTimestampBuilder_.build();
+      }
+      if (localFlowControlWindowBuilder_ == null) {
+        result.localFlowControlWindow_ = localFlowControlWindow_;
+      } else {
+        result.localFlowControlWindow_ = localFlowControlWindowBuilder_.build();
+      }
+      if (remoteFlowControlWindowBuilder_ == null) {
+        result.remoteFlowControlWindow_ = remoteFlowControlWindow_;
+      } else {
+        result.remoteFlowControlWindow_ = remoteFlowControlWindowBuilder_.build();
+      }
+      if (optionBuilder_ == null) {
+        if (((bitField0_ & 0x00001000) == 0x00001000)) {
+          option_ = java.util.Collections.unmodifiableList(option_);
+          bitField0_ = (bitField0_ & ~0x00001000);
+        }
+        result.option_ = option_;
+      } else {
+        result.option_ = optionBuilder_.build();
+      }
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.SocketData) {
+        return mergeFrom((io.grpc.channelz.v1.SocketData)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.SocketData other) {
+      if (other == io.grpc.channelz.v1.SocketData.getDefaultInstance()) return this;
+      if (other.getStreamsStarted() != 0L) {
+        setStreamsStarted(other.getStreamsStarted());
+      }
+      if (other.getStreamsSucceeded() != 0L) {
+        setStreamsSucceeded(other.getStreamsSucceeded());
+      }
+      if (other.getStreamsFailed() != 0L) {
+        setStreamsFailed(other.getStreamsFailed());
+      }
+      if (other.getMessagesSent() != 0L) {
+        setMessagesSent(other.getMessagesSent());
+      }
+      if (other.getMessagesReceived() != 0L) {
+        setMessagesReceived(other.getMessagesReceived());
+      }
+      if (other.getKeepAlivesSent() != 0L) {
+        setKeepAlivesSent(other.getKeepAlivesSent());
+      }
+      if (other.hasLastLocalStreamCreatedTimestamp()) {
+        mergeLastLocalStreamCreatedTimestamp(other.getLastLocalStreamCreatedTimestamp());
+      }
+      if (other.hasLastRemoteStreamCreatedTimestamp()) {
+        mergeLastRemoteStreamCreatedTimestamp(other.getLastRemoteStreamCreatedTimestamp());
+      }
+      if (other.hasLastMessageSentTimestamp()) {
+        mergeLastMessageSentTimestamp(other.getLastMessageSentTimestamp());
+      }
+      if (other.hasLastMessageReceivedTimestamp()) {
+        mergeLastMessageReceivedTimestamp(other.getLastMessageReceivedTimestamp());
+      }
+      if (other.hasLocalFlowControlWindow()) {
+        mergeLocalFlowControlWindow(other.getLocalFlowControlWindow());
+      }
+      if (other.hasRemoteFlowControlWindow()) {
+        mergeRemoteFlowControlWindow(other.getRemoteFlowControlWindow());
+      }
+      if (optionBuilder_ == null) {
+        if (!other.option_.isEmpty()) {
+          if (option_.isEmpty()) {
+            option_ = other.option_;
+            bitField0_ = (bitField0_ & ~0x00001000);
+          } else {
+            ensureOptionIsMutable();
+            option_.addAll(other.option_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.option_.isEmpty()) {
+          if (optionBuilder_.isEmpty()) {
+            optionBuilder_.dispose();
+            optionBuilder_ = null;
+            option_ = other.option_;
+            bitField0_ = (bitField0_ & ~0x00001000);
+            optionBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getOptionFieldBuilder() : null;
+          } else {
+            optionBuilder_.addAllMessages(other.option_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.SocketData parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.SocketData) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private long streamsStarted_ ;
+    /**
+     * <pre>
+     * The number of streams that have been started.
+     * </pre>
+     *
+     * <code>int64 streams_started = 1;</code>
+     */
+    public long getStreamsStarted() {
+      return streamsStarted_;
+    }
+    /**
+     * <pre>
+     * The number of streams that have been started.
+     * </pre>
+     *
+     * <code>int64 streams_started = 1;</code>
+     */
+    public Builder setStreamsStarted(long value) {
+      
+      streamsStarted_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of streams that have been started.
+     * </pre>
+     *
+     * <code>int64 streams_started = 1;</code>
+     */
+    public Builder clearStreamsStarted() {
+      
+      streamsStarted_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long streamsSucceeded_ ;
+    /**
+     * <pre>
+     * The number of streams that have ended successfully with the EoS bit set for
+     *  both end points
+     * </pre>
+     *
+     * <code>int64 streams_succeeded = 2;</code>
+     */
+    public long getStreamsSucceeded() {
+      return streamsSucceeded_;
+    }
+    /**
+     * <pre>
+     * The number of streams that have ended successfully with the EoS bit set for
+     *  both end points
+     * </pre>
+     *
+     * <code>int64 streams_succeeded = 2;</code>
+     */
+    public Builder setStreamsSucceeded(long value) {
+      
+      streamsSucceeded_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of streams that have ended successfully with the EoS bit set for
+     *  both end points
+     * </pre>
+     *
+     * <code>int64 streams_succeeded = 2;</code>
+     */
+    public Builder clearStreamsSucceeded() {
+      
+      streamsSucceeded_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long streamsFailed_ ;
+    /**
+     * <pre>
+     * The number of incoming streams that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 streams_failed = 3;</code>
+     */
+    public long getStreamsFailed() {
+      return streamsFailed_;
+    }
+    /**
+     * <pre>
+     * The number of incoming streams that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 streams_failed = 3;</code>
+     */
+    public Builder setStreamsFailed(long value) {
+      
+      streamsFailed_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of incoming streams that have a completed with a non-OK status
+     * </pre>
+     *
+     * <code>int64 streams_failed = 3;</code>
+     */
+    public Builder clearStreamsFailed() {
+      
+      streamsFailed_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long messagesSent_ ;
+    /**
+     * <pre>
+     * The number of messages successfully sent on this socket.
+     * </pre>
+     *
+     * <code>int64 messages_sent = 4;</code>
+     */
+    public long getMessagesSent() {
+      return messagesSent_;
+    }
+    /**
+     * <pre>
+     * The number of messages successfully sent on this socket.
+     * </pre>
+     *
+     * <code>int64 messages_sent = 4;</code>
+     */
+    public Builder setMessagesSent(long value) {
+      
+      messagesSent_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of messages successfully sent on this socket.
+     * </pre>
+     *
+     * <code>int64 messages_sent = 4;</code>
+     */
+    public Builder clearMessagesSent() {
+      
+      messagesSent_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long messagesReceived_ ;
+    /**
+     * <code>int64 messages_received = 5;</code>
+     */
+    public long getMessagesReceived() {
+      return messagesReceived_;
+    }
+    /**
+     * <code>int64 messages_received = 5;</code>
+     */
+    public Builder setMessagesReceived(long value) {
+      
+      messagesReceived_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 messages_received = 5;</code>
+     */
+    public Builder clearMessagesReceived() {
+      
+      messagesReceived_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long keepAlivesSent_ ;
+    /**
+     * <pre>
+     * The number of keep alives sent.  This is typically implemented with HTTP/2
+     * ping messages.
+     * </pre>
+     *
+     * <code>int64 keep_alives_sent = 6;</code>
+     */
+    public long getKeepAlivesSent() {
+      return keepAlivesSent_;
+    }
+    /**
+     * <pre>
+     * The number of keep alives sent.  This is typically implemented with HTTP/2
+     * ping messages.
+     * </pre>
+     *
+     * <code>int64 keep_alives_sent = 6;</code>
+     */
+    public Builder setKeepAlivesSent(long value) {
+      
+      keepAlivesSent_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The number of keep alives sent.  This is typically implemented with HTTP/2
+     * ping messages.
+     * </pre>
+     *
+     * <code>int64 keep_alives_sent = 6;</code>
+     */
+    public Builder clearKeepAlivesSent() {
+      
+      keepAlivesSent_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.Timestamp lastLocalStreamCreatedTimestamp_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lastLocalStreamCreatedTimestampBuilder_;
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public boolean hasLastLocalStreamCreatedTimestamp() {
+      return lastLocalStreamCreatedTimestampBuilder_ != null || lastLocalStreamCreatedTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public com.google.protobuf.Timestamp getLastLocalStreamCreatedTimestamp() {
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        return lastLocalStreamCreatedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastLocalStreamCreatedTimestamp_;
+      } else {
+        return lastLocalStreamCreatedTimestampBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public Builder setLastLocalStreamCreatedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        lastLocalStreamCreatedTimestamp_ = value;
+        onChanged();
+      } else {
+        lastLocalStreamCreatedTimestampBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public Builder setLastLocalStreamCreatedTimestamp(
+        com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        lastLocalStreamCreatedTimestamp_ = builderForValue.build();
+        onChanged();
+      } else {
+        lastLocalStreamCreatedTimestampBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public Builder mergeLastLocalStreamCreatedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        if (lastLocalStreamCreatedTimestamp_ != null) {
+          lastLocalStreamCreatedTimestamp_ =
+            com.google.protobuf.Timestamp.newBuilder(lastLocalStreamCreatedTimestamp_).mergeFrom(value).buildPartial();
+        } else {
+          lastLocalStreamCreatedTimestamp_ = value;
+        }
+        onChanged();
+      } else {
+        lastLocalStreamCreatedTimestampBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public Builder clearLastLocalStreamCreatedTimestamp() {
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        lastLocalStreamCreatedTimestamp_ = null;
+        onChanged();
+      } else {
+        lastLocalStreamCreatedTimestamp_ = null;
+        lastLocalStreamCreatedTimestampBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public com.google.protobuf.Timestamp.Builder getLastLocalStreamCreatedTimestampBuilder() {
+      
+      onChanged();
+      return getLastLocalStreamCreatedTimestampFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getLastLocalStreamCreatedTimestampOrBuilder() {
+      if (lastLocalStreamCreatedTimestampBuilder_ != null) {
+        return lastLocalStreamCreatedTimestampBuilder_.getMessageOrBuilder();
+      } else {
+        return lastLocalStreamCreatedTimestamp_ == null ?
+            com.google.protobuf.Timestamp.getDefaultInstance() : lastLocalStreamCreatedTimestamp_;
+      }
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by this endpoint.  Usually unset for
+     * servers.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
+        getLastLocalStreamCreatedTimestampFieldBuilder() {
+      if (lastLocalStreamCreatedTimestampBuilder_ == null) {
+        lastLocalStreamCreatedTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
+                getLastLocalStreamCreatedTimestamp(),
+                getParentForChildren(),
+                isClean());
+        lastLocalStreamCreatedTimestamp_ = null;
+      }
+      return lastLocalStreamCreatedTimestampBuilder_;
+    }
+
+    private com.google.protobuf.Timestamp lastRemoteStreamCreatedTimestamp_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lastRemoteStreamCreatedTimestampBuilder_;
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public boolean hasLastRemoteStreamCreatedTimestamp() {
+      return lastRemoteStreamCreatedTimestampBuilder_ != null || lastRemoteStreamCreatedTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public com.google.protobuf.Timestamp getLastRemoteStreamCreatedTimestamp() {
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        return lastRemoteStreamCreatedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastRemoteStreamCreatedTimestamp_;
+      } else {
+        return lastRemoteStreamCreatedTimestampBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public Builder setLastRemoteStreamCreatedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        lastRemoteStreamCreatedTimestamp_ = value;
+        onChanged();
+      } else {
+        lastRemoteStreamCreatedTimestampBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public Builder setLastRemoteStreamCreatedTimestamp(
+        com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        lastRemoteStreamCreatedTimestamp_ = builderForValue.build();
+        onChanged();
+      } else {
+        lastRemoteStreamCreatedTimestampBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public Builder mergeLastRemoteStreamCreatedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        if (lastRemoteStreamCreatedTimestamp_ != null) {
+          lastRemoteStreamCreatedTimestamp_ =
+            com.google.protobuf.Timestamp.newBuilder(lastRemoteStreamCreatedTimestamp_).mergeFrom(value).buildPartial();
+        } else {
+          lastRemoteStreamCreatedTimestamp_ = value;
+        }
+        onChanged();
+      } else {
+        lastRemoteStreamCreatedTimestampBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public Builder clearLastRemoteStreamCreatedTimestamp() {
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        lastRemoteStreamCreatedTimestamp_ = null;
+        onChanged();
+      } else {
+        lastRemoteStreamCreatedTimestamp_ = null;
+        lastRemoteStreamCreatedTimestampBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public com.google.protobuf.Timestamp.Builder getLastRemoteStreamCreatedTimestampBuilder() {
+      
+      onChanged();
+      return getLastRemoteStreamCreatedTimestampFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getLastRemoteStreamCreatedTimestampOrBuilder() {
+      if (lastRemoteStreamCreatedTimestampBuilder_ != null) {
+        return lastRemoteStreamCreatedTimestampBuilder_.getMessageOrBuilder();
+      } else {
+        return lastRemoteStreamCreatedTimestamp_ == null ?
+            com.google.protobuf.Timestamp.getDefaultInstance() : lastRemoteStreamCreatedTimestamp_;
+      }
+    }
+    /**
+     * <pre>
+     * The last time a stream was created by the remote endpoint.  Usually unset
+     * for clients.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
+        getLastRemoteStreamCreatedTimestampFieldBuilder() {
+      if (lastRemoteStreamCreatedTimestampBuilder_ == null) {
+        lastRemoteStreamCreatedTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
+                getLastRemoteStreamCreatedTimestamp(),
+                getParentForChildren(),
+                isClean());
+        lastRemoteStreamCreatedTimestamp_ = null;
+      }
+      return lastRemoteStreamCreatedTimestampBuilder_;
+    }
+
+    private com.google.protobuf.Timestamp lastMessageSentTimestamp_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lastMessageSentTimestampBuilder_;
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public boolean hasLastMessageSentTimestamp() {
+      return lastMessageSentTimestampBuilder_ != null || lastMessageSentTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public com.google.protobuf.Timestamp getLastMessageSentTimestamp() {
+      if (lastMessageSentTimestampBuilder_ == null) {
+        return lastMessageSentTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastMessageSentTimestamp_;
+      } else {
+        return lastMessageSentTimestampBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public Builder setLastMessageSentTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastMessageSentTimestampBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        lastMessageSentTimestamp_ = value;
+        onChanged();
+      } else {
+        lastMessageSentTimestampBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public Builder setLastMessageSentTimestamp(
+        com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (lastMessageSentTimestampBuilder_ == null) {
+        lastMessageSentTimestamp_ = builderForValue.build();
+        onChanged();
+      } else {
+        lastMessageSentTimestampBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public Builder mergeLastMessageSentTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastMessageSentTimestampBuilder_ == null) {
+        if (lastMessageSentTimestamp_ != null) {
+          lastMessageSentTimestamp_ =
+            com.google.protobuf.Timestamp.newBuilder(lastMessageSentTimestamp_).mergeFrom(value).buildPartial();
+        } else {
+          lastMessageSentTimestamp_ = value;
+        }
+        onChanged();
+      } else {
+        lastMessageSentTimestampBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public Builder clearLastMessageSentTimestamp() {
+      if (lastMessageSentTimestampBuilder_ == null) {
+        lastMessageSentTimestamp_ = null;
+        onChanged();
+      } else {
+        lastMessageSentTimestamp_ = null;
+        lastMessageSentTimestampBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public com.google.protobuf.Timestamp.Builder getLastMessageSentTimestampBuilder() {
+      
+      onChanged();
+      return getLastMessageSentTimestampFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getLastMessageSentTimestampOrBuilder() {
+      if (lastMessageSentTimestampBuilder_ != null) {
+        return lastMessageSentTimestampBuilder_.getMessageOrBuilder();
+      } else {
+        return lastMessageSentTimestamp_ == null ?
+            com.google.protobuf.Timestamp.getDefaultInstance() : lastMessageSentTimestamp_;
+      }
+    }
+    /**
+     * <pre>
+     * The last time a message was sent by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
+        getLastMessageSentTimestampFieldBuilder() {
+      if (lastMessageSentTimestampBuilder_ == null) {
+        lastMessageSentTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
+                getLastMessageSentTimestamp(),
+                getParentForChildren(),
+                isClean());
+        lastMessageSentTimestamp_ = null;
+      }
+      return lastMessageSentTimestampBuilder_;
+    }
+
+    private com.google.protobuf.Timestamp lastMessageReceivedTimestamp_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lastMessageReceivedTimestampBuilder_;
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public boolean hasLastMessageReceivedTimestamp() {
+      return lastMessageReceivedTimestampBuilder_ != null || lastMessageReceivedTimestamp_ != null;
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public com.google.protobuf.Timestamp getLastMessageReceivedTimestamp() {
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        return lastMessageReceivedTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lastMessageReceivedTimestamp_;
+      } else {
+        return lastMessageReceivedTimestampBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public Builder setLastMessageReceivedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        lastMessageReceivedTimestamp_ = value;
+        onChanged();
+      } else {
+        lastMessageReceivedTimestampBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public Builder setLastMessageReceivedTimestamp(
+        com.google.protobuf.Timestamp.Builder builderForValue) {
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        lastMessageReceivedTimestamp_ = builderForValue.build();
+        onChanged();
+      } else {
+        lastMessageReceivedTimestampBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public Builder mergeLastMessageReceivedTimestamp(com.google.protobuf.Timestamp value) {
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        if (lastMessageReceivedTimestamp_ != null) {
+          lastMessageReceivedTimestamp_ =
+            com.google.protobuf.Timestamp.newBuilder(lastMessageReceivedTimestamp_).mergeFrom(value).buildPartial();
+        } else {
+          lastMessageReceivedTimestamp_ = value;
+        }
+        onChanged();
+      } else {
+        lastMessageReceivedTimestampBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public Builder clearLastMessageReceivedTimestamp() {
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        lastMessageReceivedTimestamp_ = null;
+        onChanged();
+      } else {
+        lastMessageReceivedTimestamp_ = null;
+        lastMessageReceivedTimestampBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public com.google.protobuf.Timestamp.Builder getLastMessageReceivedTimestampBuilder() {
+      
+      onChanged();
+      return getLastMessageReceivedTimestampFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    public com.google.protobuf.TimestampOrBuilder getLastMessageReceivedTimestampOrBuilder() {
+      if (lastMessageReceivedTimestampBuilder_ != null) {
+        return lastMessageReceivedTimestampBuilder_.getMessageOrBuilder();
+      } else {
+        return lastMessageReceivedTimestamp_ == null ?
+            com.google.protobuf.Timestamp.getDefaultInstance() : lastMessageReceivedTimestamp_;
+      }
+    }
+    /**
+     * <pre>
+     * The last time a message was received by this endpoint.
+     * </pre>
+     *
+     * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
+        getLastMessageReceivedTimestampFieldBuilder() {
+      if (lastMessageReceivedTimestampBuilder_ == null) {
+        lastMessageReceivedTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
+                getLastMessageReceivedTimestamp(),
+                getParentForChildren(),
+                isClean());
+        lastMessageReceivedTimestamp_ = null;
+      }
+      return lastMessageReceivedTimestampBuilder_;
+    }
+
+    private com.google.protobuf.Int64Value localFlowControlWindow_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Int64Value, com.google.protobuf.Int64Value.Builder, com.google.protobuf.Int64ValueOrBuilder> localFlowControlWindowBuilder_;
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public boolean hasLocalFlowControlWindow() {
+      return localFlowControlWindowBuilder_ != null || localFlowControlWindow_ != null;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public com.google.protobuf.Int64Value getLocalFlowControlWindow() {
+      if (localFlowControlWindowBuilder_ == null) {
+        return localFlowControlWindow_ == null ? com.google.protobuf.Int64Value.getDefaultInstance() : localFlowControlWindow_;
+      } else {
+        return localFlowControlWindowBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public Builder setLocalFlowControlWindow(com.google.protobuf.Int64Value value) {
+      if (localFlowControlWindowBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        localFlowControlWindow_ = value;
+        onChanged();
+      } else {
+        localFlowControlWindowBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public Builder setLocalFlowControlWindow(
+        com.google.protobuf.Int64Value.Builder builderForValue) {
+      if (localFlowControlWindowBuilder_ == null) {
+        localFlowControlWindow_ = builderForValue.build();
+        onChanged();
+      } else {
+        localFlowControlWindowBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public Builder mergeLocalFlowControlWindow(com.google.protobuf.Int64Value value) {
+      if (localFlowControlWindowBuilder_ == null) {
+        if (localFlowControlWindow_ != null) {
+          localFlowControlWindow_ =
+            com.google.protobuf.Int64Value.newBuilder(localFlowControlWindow_).mergeFrom(value).buildPartial();
+        } else {
+          localFlowControlWindow_ = value;
+        }
+        onChanged();
+      } else {
+        localFlowControlWindowBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public Builder clearLocalFlowControlWindow() {
+      if (localFlowControlWindowBuilder_ == null) {
+        localFlowControlWindow_ = null;
+        onChanged();
+      } else {
+        localFlowControlWindow_ = null;
+        localFlowControlWindowBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public com.google.protobuf.Int64Value.Builder getLocalFlowControlWindowBuilder() {
+      
+      onChanged();
+      return getLocalFlowControlWindowFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    public com.google.protobuf.Int64ValueOrBuilder getLocalFlowControlWindowOrBuilder() {
+      if (localFlowControlWindowBuilder_ != null) {
+        return localFlowControlWindowBuilder_.getMessageOrBuilder();
+      } else {
+        return localFlowControlWindow_ == null ?
+            com.google.protobuf.Int64Value.getDefaultInstance() : localFlowControlWindow_;
+      }
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the local endpoint by the remote endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Int64Value, com.google.protobuf.Int64Value.Builder, com.google.protobuf.Int64ValueOrBuilder> 
+        getLocalFlowControlWindowFieldBuilder() {
+      if (localFlowControlWindowBuilder_ == null) {
+        localFlowControlWindowBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Int64Value, com.google.protobuf.Int64Value.Builder, com.google.protobuf.Int64ValueOrBuilder>(
+                getLocalFlowControlWindow(),
+                getParentForChildren(),
+                isClean());
+        localFlowControlWindow_ = null;
+      }
+      return localFlowControlWindowBuilder_;
+    }
+
+    private com.google.protobuf.Int64Value remoteFlowControlWindow_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Int64Value, com.google.protobuf.Int64Value.Builder, com.google.protobuf.Int64ValueOrBuilder> remoteFlowControlWindowBuilder_;
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public boolean hasRemoteFlowControlWindow() {
+      return remoteFlowControlWindowBuilder_ != null || remoteFlowControlWindow_ != null;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public com.google.protobuf.Int64Value getRemoteFlowControlWindow() {
+      if (remoteFlowControlWindowBuilder_ == null) {
+        return remoteFlowControlWindow_ == null ? com.google.protobuf.Int64Value.getDefaultInstance() : remoteFlowControlWindow_;
+      } else {
+        return remoteFlowControlWindowBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public Builder setRemoteFlowControlWindow(com.google.protobuf.Int64Value value) {
+      if (remoteFlowControlWindowBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        remoteFlowControlWindow_ = value;
+        onChanged();
+      } else {
+        remoteFlowControlWindowBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public Builder setRemoteFlowControlWindow(
+        com.google.protobuf.Int64Value.Builder builderForValue) {
+      if (remoteFlowControlWindowBuilder_ == null) {
+        remoteFlowControlWindow_ = builderForValue.build();
+        onChanged();
+      } else {
+        remoteFlowControlWindowBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public Builder mergeRemoteFlowControlWindow(com.google.protobuf.Int64Value value) {
+      if (remoteFlowControlWindowBuilder_ == null) {
+        if (remoteFlowControlWindow_ != null) {
+          remoteFlowControlWindow_ =
+            com.google.protobuf.Int64Value.newBuilder(remoteFlowControlWindow_).mergeFrom(value).buildPartial();
+        } else {
+          remoteFlowControlWindow_ = value;
+        }
+        onChanged();
+      } else {
+        remoteFlowControlWindowBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public Builder clearRemoteFlowControlWindow() {
+      if (remoteFlowControlWindowBuilder_ == null) {
+        remoteFlowControlWindow_ = null;
+        onChanged();
+      } else {
+        remoteFlowControlWindow_ = null;
+        remoteFlowControlWindowBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public com.google.protobuf.Int64Value.Builder getRemoteFlowControlWindowBuilder() {
+      
+      onChanged();
+      return getRemoteFlowControlWindowFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    public com.google.protobuf.Int64ValueOrBuilder getRemoteFlowControlWindowOrBuilder() {
+      if (remoteFlowControlWindowBuilder_ != null) {
+        return remoteFlowControlWindowBuilder_.getMessageOrBuilder();
+      } else {
+        return remoteFlowControlWindow_ == null ?
+            com.google.protobuf.Int64Value.getDefaultInstance() : remoteFlowControlWindow_;
+      }
+    }
+    /**
+     * <pre>
+     * The amount of window, granted to the remote endpoint by the local endpoint.
+     * This may be slightly out of date due to network latency.  This does NOT
+     * include stream level or TCP level flow control info.
+     * </pre>
+     *
+     * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Int64Value, com.google.protobuf.Int64Value.Builder, com.google.protobuf.Int64ValueOrBuilder> 
+        getRemoteFlowControlWindowFieldBuilder() {
+      if (remoteFlowControlWindowBuilder_ == null) {
+        remoteFlowControlWindowBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Int64Value, com.google.protobuf.Int64Value.Builder, com.google.protobuf.Int64ValueOrBuilder>(
+                getRemoteFlowControlWindow(),
+                getParentForChildren(),
+                isClean());
+        remoteFlowControlWindow_ = null;
+      }
+      return remoteFlowControlWindowBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.SocketOption> option_ =
+      java.util.Collections.emptyList();
+    private void ensureOptionIsMutable() {
+      if (!((bitField0_ & 0x00001000) == 0x00001000)) {
+        option_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketOption>(option_);
+        bitField0_ |= 0x00001000;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketOption, io.grpc.channelz.v1.SocketOption.Builder, io.grpc.channelz.v1.SocketOptionOrBuilder> optionBuilder_;
+
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketOption> getOptionList() {
+      if (optionBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(option_);
+      } else {
+        return optionBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public int getOptionCount() {
+      if (optionBuilder_ == null) {
+        return option_.size();
+      } else {
+        return optionBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public io.grpc.channelz.v1.SocketOption getOption(int index) {
+      if (optionBuilder_ == null) {
+        return option_.get(index);
+      } else {
+        return optionBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder setOption(
+        int index, io.grpc.channelz.v1.SocketOption value) {
+      if (optionBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureOptionIsMutable();
+        option_.set(index, value);
+        onChanged();
+      } else {
+        optionBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder setOption(
+        int index, io.grpc.channelz.v1.SocketOption.Builder builderForValue) {
+      if (optionBuilder_ == null) {
+        ensureOptionIsMutable();
+        option_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        optionBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder addOption(io.grpc.channelz.v1.SocketOption value) {
+      if (optionBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureOptionIsMutable();
+        option_.add(value);
+        onChanged();
+      } else {
+        optionBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder addOption(
+        int index, io.grpc.channelz.v1.SocketOption value) {
+      if (optionBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureOptionIsMutable();
+        option_.add(index, value);
+        onChanged();
+      } else {
+        optionBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder addOption(
+        io.grpc.channelz.v1.SocketOption.Builder builderForValue) {
+      if (optionBuilder_ == null) {
+        ensureOptionIsMutable();
+        option_.add(builderForValue.build());
+        onChanged();
+      } else {
+        optionBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder addOption(
+        int index, io.grpc.channelz.v1.SocketOption.Builder builderForValue) {
+      if (optionBuilder_ == null) {
+        ensureOptionIsMutable();
+        option_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        optionBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder addAllOption(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.SocketOption> values) {
+      if (optionBuilder_ == null) {
+        ensureOptionIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, option_);
+        onChanged();
+      } else {
+        optionBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder clearOption() {
+      if (optionBuilder_ == null) {
+        option_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00001000);
+        onChanged();
+      } else {
+        optionBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public Builder removeOption(int index) {
+      if (optionBuilder_ == null) {
+        ensureOptionIsMutable();
+        option_.remove(index);
+        onChanged();
+      } else {
+        optionBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public io.grpc.channelz.v1.SocketOption.Builder getOptionBuilder(
+        int index) {
+      return getOptionFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public io.grpc.channelz.v1.SocketOptionOrBuilder getOptionOrBuilder(
+        int index) {
+      if (optionBuilder_ == null) {
+        return option_.get(index);  } else {
+        return optionBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.SocketOptionOrBuilder> 
+         getOptionOrBuilderList() {
+      if (optionBuilder_ != null) {
+        return optionBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(option_);
+      }
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public io.grpc.channelz.v1.SocketOption.Builder addOptionBuilder() {
+      return getOptionFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.SocketOption.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public io.grpc.channelz.v1.SocketOption.Builder addOptionBuilder(
+        int index) {
+      return getOptionFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.SocketOption.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketOption.Builder> 
+         getOptionBuilderList() {
+      return getOptionFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketOption, io.grpc.channelz.v1.SocketOption.Builder, io.grpc.channelz.v1.SocketOptionOrBuilder> 
+        getOptionFieldBuilder() {
+      if (optionBuilder_ == null) {
+        optionBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.SocketOption, io.grpc.channelz.v1.SocketOption.Builder, io.grpc.channelz.v1.SocketOptionOrBuilder>(
+                option_,
+                ((bitField0_ & 0x00001000) == 0x00001000),
+                getParentForChildren(),
+                isClean());
+        option_ = null;
+      }
+      return optionBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.SocketData)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.SocketData)
+  private static final io.grpc.channelz.v1.SocketData DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.SocketData();
+  }
+
+  public static io.grpc.channelz.v1.SocketData getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<SocketData>
+      PARSER = new com.google.protobuf.AbstractParser<SocketData>() {
+    public SocketData parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new SocketData(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<SocketData> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<SocketData> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.SocketData getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketDataOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketDataOrBuilder.java
new file mode 100644
index 0000000..1fd5620
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketDataOrBuilder.java
@@ -0,0 +1,253 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SocketDataOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.SocketData)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * The number of streams that have been started.
+   * </pre>
+   *
+   * <code>int64 streams_started = 1;</code>
+   */
+  long getStreamsStarted();
+
+  /**
+   * <pre>
+   * The number of streams that have ended successfully with the EoS bit set for
+   *  both end points
+   * </pre>
+   *
+   * <code>int64 streams_succeeded = 2;</code>
+   */
+  long getStreamsSucceeded();
+
+  /**
+   * <pre>
+   * The number of incoming streams that have a completed with a non-OK status
+   * </pre>
+   *
+   * <code>int64 streams_failed = 3;</code>
+   */
+  long getStreamsFailed();
+
+  /**
+   * <pre>
+   * The number of messages successfully sent on this socket.
+   * </pre>
+   *
+   * <code>int64 messages_sent = 4;</code>
+   */
+  long getMessagesSent();
+
+  /**
+   * <code>int64 messages_received = 5;</code>
+   */
+  long getMessagesReceived();
+
+  /**
+   * <pre>
+   * The number of keep alives sent.  This is typically implemented with HTTP/2
+   * ping messages.
+   * </pre>
+   *
+   * <code>int64 keep_alives_sent = 6;</code>
+   */
+  long getKeepAlivesSent();
+
+  /**
+   * <pre>
+   * The last time a stream was created by this endpoint.  Usually unset for
+   * servers.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+   */
+  boolean hasLastLocalStreamCreatedTimestamp();
+  /**
+   * <pre>
+   * The last time a stream was created by this endpoint.  Usually unset for
+   * servers.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+   */
+  com.google.protobuf.Timestamp getLastLocalStreamCreatedTimestamp();
+  /**
+   * <pre>
+   * The last time a stream was created by this endpoint.  Usually unset for
+   * servers.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_local_stream_created_timestamp = 7;</code>
+   */
+  com.google.protobuf.TimestampOrBuilder getLastLocalStreamCreatedTimestampOrBuilder();
+
+  /**
+   * <pre>
+   * The last time a stream was created by the remote endpoint.  Usually unset
+   * for clients.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+   */
+  boolean hasLastRemoteStreamCreatedTimestamp();
+  /**
+   * <pre>
+   * The last time a stream was created by the remote endpoint.  Usually unset
+   * for clients.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+   */
+  com.google.protobuf.Timestamp getLastRemoteStreamCreatedTimestamp();
+  /**
+   * <pre>
+   * The last time a stream was created by the remote endpoint.  Usually unset
+   * for clients.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;</code>
+   */
+  com.google.protobuf.TimestampOrBuilder getLastRemoteStreamCreatedTimestampOrBuilder();
+
+  /**
+   * <pre>
+   * The last time a message was sent by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+   */
+  boolean hasLastMessageSentTimestamp();
+  /**
+   * <pre>
+   * The last time a message was sent by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+   */
+  com.google.protobuf.Timestamp getLastMessageSentTimestamp();
+  /**
+   * <pre>
+   * The last time a message was sent by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_sent_timestamp = 9;</code>
+   */
+  com.google.protobuf.TimestampOrBuilder getLastMessageSentTimestampOrBuilder();
+
+  /**
+   * <pre>
+   * The last time a message was received by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+   */
+  boolean hasLastMessageReceivedTimestamp();
+  /**
+   * <pre>
+   * The last time a message was received by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+   */
+  com.google.protobuf.Timestamp getLastMessageReceivedTimestamp();
+  /**
+   * <pre>
+   * The last time a message was received by this endpoint.
+   * </pre>
+   *
+   * <code>.google.protobuf.Timestamp last_message_received_timestamp = 10;</code>
+   */
+  com.google.protobuf.TimestampOrBuilder getLastMessageReceivedTimestampOrBuilder();
+
+  /**
+   * <pre>
+   * The amount of window, granted to the local endpoint by the remote endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+   */
+  boolean hasLocalFlowControlWindow();
+  /**
+   * <pre>
+   * The amount of window, granted to the local endpoint by the remote endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+   */
+  com.google.protobuf.Int64Value getLocalFlowControlWindow();
+  /**
+   * <pre>
+   * The amount of window, granted to the local endpoint by the remote endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value local_flow_control_window = 11;</code>
+   */
+  com.google.protobuf.Int64ValueOrBuilder getLocalFlowControlWindowOrBuilder();
+
+  /**
+   * <pre>
+   * The amount of window, granted to the remote endpoint by the local endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+   */
+  boolean hasRemoteFlowControlWindow();
+  /**
+   * <pre>
+   * The amount of window, granted to the remote endpoint by the local endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+   */
+  com.google.protobuf.Int64Value getRemoteFlowControlWindow();
+  /**
+   * <pre>
+   * The amount of window, granted to the remote endpoint by the local endpoint.
+   * This may be slightly out of date due to network latency.  This does NOT
+   * include stream level or TCP level flow control info.
+   * </pre>
+   *
+   * <code>.google.protobuf.Int64Value remote_flow_control_window = 12;</code>
+   */
+  com.google.protobuf.Int64ValueOrBuilder getRemoteFlowControlWindowOrBuilder();
+
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.SocketOption> 
+      getOptionList();
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  io.grpc.channelz.v1.SocketOption getOption(int index);
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  int getOptionCount();
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.SocketOptionOrBuilder> 
+      getOptionOrBuilderList();
+  /**
+   * <code>repeated .grpc.channelz.SocketOption option = 13;</code>
+   */
+  io.grpc.channelz.v1.SocketOptionOrBuilder getOptionOrBuilder(
+      int index);
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOption.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOption.java
new file mode 100644
index 0000000..abe56a6
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOption.java
@@ -0,0 +1,919 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.SocketOption}
+ */
+public  final class SocketOption extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.SocketOption)
+    SocketOptionOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use SocketOption.newBuilder() to construct.
+  private SocketOption(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private SocketOption() {
+    name_ = "";
+    value_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private SocketOption(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            value_ = s;
+            break;
+          }
+          case 26: {
+            com.google.protobuf.Any.Builder subBuilder = null;
+            if (additional_ != null) {
+              subBuilder = additional_.toBuilder();
+            }
+            additional_ = input.readMessage(com.google.protobuf.Any.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(additional_);
+              additional_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOption_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOption_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.SocketOption.class, io.grpc.channelz.v1.SocketOption.Builder.class);
+  }
+
+  public static final int NAME_FIELD_NUMBER = 1;
+  private volatile java.lang.Object name_;
+  /**
+   * <code>string name = 1;</code>
+   */
+  public java.lang.String getName() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string name = 1;</code>
+   */
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int VALUE_FIELD_NUMBER = 2;
+  private volatile java.lang.Object value_;
+  /**
+   * <pre>
+   * The human readable value of this socket option.  At least one of value or
+   * additional will be set.
+   * </pre>
+   *
+   * <code>string value = 2;</code>
+   */
+  public java.lang.String getValue() {
+    java.lang.Object ref = value_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      value_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * The human readable value of this socket option.  At least one of value or
+   * additional will be set.
+   * </pre>
+   *
+   * <code>string value = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getValueBytes() {
+    java.lang.Object ref = value_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      value_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int ADDITIONAL_FIELD_NUMBER = 3;
+  private com.google.protobuf.Any additional_;
+  /**
+   * <pre>
+   * Additional data associated with the socket option.  At least one of value
+   * or additional will be set.
+   * </pre>
+   *
+   * <code>.google.protobuf.Any additional = 3;</code>
+   */
+  public boolean hasAdditional() {
+    return additional_ != null;
+  }
+  /**
+   * <pre>
+   * Additional data associated with the socket option.  At least one of value
+   * or additional will be set.
+   * </pre>
+   *
+   * <code>.google.protobuf.Any additional = 3;</code>
+   */
+  public com.google.protobuf.Any getAdditional() {
+    return additional_ == null ? com.google.protobuf.Any.getDefaultInstance() : additional_;
+  }
+  /**
+   * <pre>
+   * Additional data associated with the socket option.  At least one of value
+   * or additional will be set.
+   * </pre>
+   *
+   * <code>.google.protobuf.Any additional = 3;</code>
+   */
+  public com.google.protobuf.AnyOrBuilder getAdditionalOrBuilder() {
+    return getAdditional();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!getNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
+    }
+    if (!getValueBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, value_);
+    }
+    if (additional_ != null) {
+      output.writeMessage(3, getAdditional());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!getNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
+    }
+    if (!getValueBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, value_);
+    }
+    if (additional_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, getAdditional());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.SocketOption)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.SocketOption other = (io.grpc.channelz.v1.SocketOption) obj;
+
+    boolean result = true;
+    result = result && getName()
+        .equals(other.getName());
+    result = result && getValue()
+        .equals(other.getValue());
+    result = result && (hasAdditional() == other.hasAdditional());
+    if (hasAdditional()) {
+      result = result && getAdditional()
+          .equals(other.getAdditional());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (37 * hash) + VALUE_FIELD_NUMBER;
+    hash = (53 * hash) + getValue().hashCode();
+    if (hasAdditional()) {
+      hash = (37 * hash) + ADDITIONAL_FIELD_NUMBER;
+      hash = (53 * hash) + getAdditional().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOption parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.SocketOption prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.SocketOption}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.SocketOption)
+      io.grpc.channelz.v1.SocketOptionOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOption_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOption_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.SocketOption.class, io.grpc.channelz.v1.SocketOption.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.SocketOption.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      name_ = "";
+
+      value_ = "";
+
+      if (additionalBuilder_ == null) {
+        additional_ = null;
+      } else {
+        additional_ = null;
+        additionalBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOption_descriptor;
+    }
+
+    public io.grpc.channelz.v1.SocketOption getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.SocketOption.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.SocketOption build() {
+      io.grpc.channelz.v1.SocketOption result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.SocketOption buildPartial() {
+      io.grpc.channelz.v1.SocketOption result = new io.grpc.channelz.v1.SocketOption(this);
+      result.name_ = name_;
+      result.value_ = value_;
+      if (additionalBuilder_ == null) {
+        result.additional_ = additional_;
+      } else {
+        result.additional_ = additionalBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.SocketOption) {
+        return mergeFrom((io.grpc.channelz.v1.SocketOption)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.SocketOption other) {
+      if (other == io.grpc.channelz.v1.SocketOption.getDefaultInstance()) return this;
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      if (!other.getValue().isEmpty()) {
+        value_ = other.value_;
+        onChanged();
+      }
+      if (other.hasAdditional()) {
+        mergeAdditional(other.getAdditional());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.SocketOption parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.SocketOption) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private java.lang.Object name_ = "";
+    /**
+     * <code>string name = 1;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string name = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string name = 1;</code>
+     */
+    public Builder setName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 1;</code>
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 1;</code>
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object value_ = "";
+    /**
+     * <pre>
+     * The human readable value of this socket option.  At least one of value or
+     * additional will be set.
+     * </pre>
+     *
+     * <code>string value = 2;</code>
+     */
+    public java.lang.String getValue() {
+      java.lang.Object ref = value_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        value_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The human readable value of this socket option.  At least one of value or
+     * additional will be set.
+     * </pre>
+     *
+     * <code>string value = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getValueBytes() {
+      java.lang.Object ref = value_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        value_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * The human readable value of this socket option.  At least one of value or
+     * additional will be set.
+     * </pre>
+     *
+     * <code>string value = 2;</code>
+     */
+    public Builder setValue(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      value_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The human readable value of this socket option.  At least one of value or
+     * additional will be set.
+     * </pre>
+     *
+     * <code>string value = 2;</code>
+     */
+    public Builder clearValue() {
+      
+      value_ = getDefaultInstance().getValue();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The human readable value of this socket option.  At least one of value or
+     * additional will be set.
+     * </pre>
+     *
+     * <code>string value = 2;</code>
+     */
+    public Builder setValueBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      value_ = value;
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.Any additional_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> additionalBuilder_;
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public boolean hasAdditional() {
+      return additionalBuilder_ != null || additional_ != null;
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public com.google.protobuf.Any getAdditional() {
+      if (additionalBuilder_ == null) {
+        return additional_ == null ? com.google.protobuf.Any.getDefaultInstance() : additional_;
+      } else {
+        return additionalBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public Builder setAdditional(com.google.protobuf.Any value) {
+      if (additionalBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        additional_ = value;
+        onChanged();
+      } else {
+        additionalBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public Builder setAdditional(
+        com.google.protobuf.Any.Builder builderForValue) {
+      if (additionalBuilder_ == null) {
+        additional_ = builderForValue.build();
+        onChanged();
+      } else {
+        additionalBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public Builder mergeAdditional(com.google.protobuf.Any value) {
+      if (additionalBuilder_ == null) {
+        if (additional_ != null) {
+          additional_ =
+            com.google.protobuf.Any.newBuilder(additional_).mergeFrom(value).buildPartial();
+        } else {
+          additional_ = value;
+        }
+        onChanged();
+      } else {
+        additionalBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public Builder clearAdditional() {
+      if (additionalBuilder_ == null) {
+        additional_ = null;
+        onChanged();
+      } else {
+        additional_ = null;
+        additionalBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public com.google.protobuf.Any.Builder getAdditionalBuilder() {
+      
+      onChanged();
+      return getAdditionalFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    public com.google.protobuf.AnyOrBuilder getAdditionalOrBuilder() {
+      if (additionalBuilder_ != null) {
+        return additionalBuilder_.getMessageOrBuilder();
+      } else {
+        return additional_ == null ?
+            com.google.protobuf.Any.getDefaultInstance() : additional_;
+      }
+    }
+    /**
+     * <pre>
+     * Additional data associated with the socket option.  At least one of value
+     * or additional will be set.
+     * </pre>
+     *
+     * <code>.google.protobuf.Any additional = 3;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> 
+        getAdditionalFieldBuilder() {
+      if (additionalBuilder_ == null) {
+        additionalBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder>(
+                getAdditional(),
+                getParentForChildren(),
+                isClean());
+        additional_ = null;
+      }
+      return additionalBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.SocketOption)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.SocketOption)
+  private static final io.grpc.channelz.v1.SocketOption DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.SocketOption();
+  }
+
+  public static io.grpc.channelz.v1.SocketOption getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<SocketOption>
+      PARSER = new com.google.protobuf.AbstractParser<SocketOption>() {
+    public SocketOption parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new SocketOption(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<SocketOption> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<SocketOption> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.SocketOption getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionLinger.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionLinger.java
new file mode 100644
index 0000000..fbe2cf7
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionLinger.java
@@ -0,0 +1,629 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.SocketOptionLinger}
+ */
+public  final class SocketOptionLinger extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.SocketOptionLinger)
+    SocketOptionLingerOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use SocketOptionLinger.newBuilder() to construct.
+  private SocketOptionLinger(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private SocketOptionLinger() {
+    active_ = false;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private SocketOptionLinger(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            active_ = input.readBool();
+            break;
+          }
+          case 18: {
+            com.google.protobuf.Duration.Builder subBuilder = null;
+            if (duration_ != null) {
+              subBuilder = duration_.toBuilder();
+            }
+            duration_ = input.readMessage(com.google.protobuf.Duration.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(duration_);
+              duration_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionLinger_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionLinger_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.SocketOptionLinger.class, io.grpc.channelz.v1.SocketOptionLinger.Builder.class);
+  }
+
+  public static final int ACTIVE_FIELD_NUMBER = 1;
+  private boolean active_;
+  /**
+   * <code>bool active = 1;</code>
+   */
+  public boolean getActive() {
+    return active_;
+  }
+
+  public static final int DURATION_FIELD_NUMBER = 2;
+  private com.google.protobuf.Duration duration_;
+  /**
+   * <code>.google.protobuf.Duration duration = 2;</code>
+   */
+  public boolean hasDuration() {
+    return duration_ != null;
+  }
+  /**
+   * <code>.google.protobuf.Duration duration = 2;</code>
+   */
+  public com.google.protobuf.Duration getDuration() {
+    return duration_ == null ? com.google.protobuf.Duration.getDefaultInstance() : duration_;
+  }
+  /**
+   * <code>.google.protobuf.Duration duration = 2;</code>
+   */
+  public com.google.protobuf.DurationOrBuilder getDurationOrBuilder() {
+    return getDuration();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (active_ != false) {
+      output.writeBool(1, active_);
+    }
+    if (duration_ != null) {
+      output.writeMessage(2, getDuration());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (active_ != false) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeBoolSize(1, active_);
+    }
+    if (duration_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, getDuration());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.SocketOptionLinger)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.SocketOptionLinger other = (io.grpc.channelz.v1.SocketOptionLinger) obj;
+
+    boolean result = true;
+    result = result && (getActive()
+        == other.getActive());
+    result = result && (hasDuration() == other.hasDuration());
+    if (hasDuration()) {
+      result = result && getDuration()
+          .equals(other.getDuration());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + ACTIVE_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+        getActive());
+    if (hasDuration()) {
+      hash = (37 * hash) + DURATION_FIELD_NUMBER;
+      hash = (53 * hash) + getDuration().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionLinger parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.SocketOptionLinger prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.SocketOptionLinger}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.SocketOptionLinger)
+      io.grpc.channelz.v1.SocketOptionLingerOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionLinger_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionLinger_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.SocketOptionLinger.class, io.grpc.channelz.v1.SocketOptionLinger.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.SocketOptionLinger.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      active_ = false;
+
+      if (durationBuilder_ == null) {
+        duration_ = null;
+      } else {
+        duration_ = null;
+        durationBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionLinger_descriptor;
+    }
+
+    public io.grpc.channelz.v1.SocketOptionLinger getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.SocketOptionLinger.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.SocketOptionLinger build() {
+      io.grpc.channelz.v1.SocketOptionLinger result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.SocketOptionLinger buildPartial() {
+      io.grpc.channelz.v1.SocketOptionLinger result = new io.grpc.channelz.v1.SocketOptionLinger(this);
+      result.active_ = active_;
+      if (durationBuilder_ == null) {
+        result.duration_ = duration_;
+      } else {
+        result.duration_ = durationBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.SocketOptionLinger) {
+        return mergeFrom((io.grpc.channelz.v1.SocketOptionLinger)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.SocketOptionLinger other) {
+      if (other == io.grpc.channelz.v1.SocketOptionLinger.getDefaultInstance()) return this;
+      if (other.getActive() != false) {
+        setActive(other.getActive());
+      }
+      if (other.hasDuration()) {
+        mergeDuration(other.getDuration());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.SocketOptionLinger parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.SocketOptionLinger) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private boolean active_ ;
+    /**
+     * <code>bool active = 1;</code>
+     */
+    public boolean getActive() {
+      return active_;
+    }
+    /**
+     * <code>bool active = 1;</code>
+     */
+    public Builder setActive(boolean value) {
+      
+      active_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>bool active = 1;</code>
+     */
+    public Builder clearActive() {
+      
+      active_ = false;
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.Duration duration_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> durationBuilder_;
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public boolean hasDuration() {
+      return durationBuilder_ != null || duration_ != null;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public com.google.protobuf.Duration getDuration() {
+      if (durationBuilder_ == null) {
+        return duration_ == null ? com.google.protobuf.Duration.getDefaultInstance() : duration_;
+      } else {
+        return durationBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public Builder setDuration(com.google.protobuf.Duration value) {
+      if (durationBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        duration_ = value;
+        onChanged();
+      } else {
+        durationBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public Builder setDuration(
+        com.google.protobuf.Duration.Builder builderForValue) {
+      if (durationBuilder_ == null) {
+        duration_ = builderForValue.build();
+        onChanged();
+      } else {
+        durationBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public Builder mergeDuration(com.google.protobuf.Duration value) {
+      if (durationBuilder_ == null) {
+        if (duration_ != null) {
+          duration_ =
+            com.google.protobuf.Duration.newBuilder(duration_).mergeFrom(value).buildPartial();
+        } else {
+          duration_ = value;
+        }
+        onChanged();
+      } else {
+        durationBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public Builder clearDuration() {
+      if (durationBuilder_ == null) {
+        duration_ = null;
+        onChanged();
+      } else {
+        duration_ = null;
+        durationBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public com.google.protobuf.Duration.Builder getDurationBuilder() {
+      
+      onChanged();
+      return getDurationFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    public com.google.protobuf.DurationOrBuilder getDurationOrBuilder() {
+      if (durationBuilder_ != null) {
+        return durationBuilder_.getMessageOrBuilder();
+      } else {
+        return duration_ == null ?
+            com.google.protobuf.Duration.getDefaultInstance() : duration_;
+      }
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 2;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> 
+        getDurationFieldBuilder() {
+      if (durationBuilder_ == null) {
+        durationBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder>(
+                getDuration(),
+                getParentForChildren(),
+                isClean());
+        duration_ = null;
+      }
+      return durationBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.SocketOptionLinger)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.SocketOptionLinger)
+  private static final io.grpc.channelz.v1.SocketOptionLinger DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.SocketOptionLinger();
+  }
+
+  public static io.grpc.channelz.v1.SocketOptionLinger getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<SocketOptionLinger>
+      PARSER = new com.google.protobuf.AbstractParser<SocketOptionLinger>() {
+    public SocketOptionLinger parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new SocketOptionLinger(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<SocketOptionLinger> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<SocketOptionLinger> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.SocketOptionLinger getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionLingerOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionLingerOrBuilder.java
new file mode 100644
index 0000000..9726dca
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionLingerOrBuilder.java
@@ -0,0 +1,27 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SocketOptionLingerOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.SocketOptionLinger)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>bool active = 1;</code>
+   */
+  boolean getActive();
+
+  /**
+   * <code>.google.protobuf.Duration duration = 2;</code>
+   */
+  boolean hasDuration();
+  /**
+   * <code>.google.protobuf.Duration duration = 2;</code>
+   */
+  com.google.protobuf.Duration getDuration();
+  /**
+   * <code>.google.protobuf.Duration duration = 2;</code>
+   */
+  com.google.protobuf.DurationOrBuilder getDurationOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionOrBuilder.java
new file mode 100644
index 0000000..f40562b
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionOrBuilder.java
@@ -0,0 +1,67 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SocketOptionOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.SocketOption)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string name = 1;</code>
+   */
+  java.lang.String getName();
+  /**
+   * <code>string name = 1;</code>
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+
+  /**
+   * <pre>
+   * The human readable value of this socket option.  At least one of value or
+   * additional will be set.
+   * </pre>
+   *
+   * <code>string value = 2;</code>
+   */
+  java.lang.String getValue();
+  /**
+   * <pre>
+   * The human readable value of this socket option.  At least one of value or
+   * additional will be set.
+   * </pre>
+   *
+   * <code>string value = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getValueBytes();
+
+  /**
+   * <pre>
+   * Additional data associated with the socket option.  At least one of value
+   * or additional will be set.
+   * </pre>
+   *
+   * <code>.google.protobuf.Any additional = 3;</code>
+   */
+  boolean hasAdditional();
+  /**
+   * <pre>
+   * Additional data associated with the socket option.  At least one of value
+   * or additional will be set.
+   * </pre>
+   *
+   * <code>.google.protobuf.Any additional = 3;</code>
+   */
+  com.google.protobuf.Any getAdditional();
+  /**
+   * <pre>
+   * Additional data associated with the socket option.  At least one of value
+   * or additional will be set.
+   * </pre>
+   *
+   * <code>.google.protobuf.Any additional = 3;</code>
+   */
+  com.google.protobuf.AnyOrBuilder getAdditionalOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTcpInfo.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTcpInfo.java
new file mode 100644
index 0000000..a33cb28
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTcpInfo.java
@@ -0,0 +1,2079 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * <pre>
+ * Tcp info for SOL_TCP, TCP_INFO
+ * </pre>
+ *
+ * Protobuf type {@code grpc.channelz.SocketOptionTcpInfo}
+ */
+public  final class SocketOptionTcpInfo extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.SocketOptionTcpInfo)
+    SocketOptionTcpInfoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use SocketOptionTcpInfo.newBuilder() to construct.
+  private SocketOptionTcpInfo(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private SocketOptionTcpInfo() {
+    tcpiState_ = 0;
+    tcpiCaState_ = 0;
+    tcpiRetransmits_ = 0;
+    tcpiProbes_ = 0;
+    tcpiBackoff_ = 0;
+    tcpiOptions_ = 0;
+    tcpiSndWscale_ = 0;
+    tcpiRcvWscale_ = 0;
+    tcpiRto_ = 0;
+    tcpiAto_ = 0;
+    tcpiSndMss_ = 0;
+    tcpiRcvMss_ = 0;
+    tcpiUnacked_ = 0;
+    tcpiSacked_ = 0;
+    tcpiLost_ = 0;
+    tcpiRetrans_ = 0;
+    tcpiFackets_ = 0;
+    tcpiLastDataSent_ = 0;
+    tcpiLastAckSent_ = 0;
+    tcpiLastDataRecv_ = 0;
+    tcpiLastAckRecv_ = 0;
+    tcpiPmtu_ = 0;
+    tcpiRcvSsthresh_ = 0;
+    tcpiRtt_ = 0;
+    tcpiRttvar_ = 0;
+    tcpiSndSsthresh_ = 0;
+    tcpiSndCwnd_ = 0;
+    tcpiAdvmss_ = 0;
+    tcpiReordering_ = 0;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private SocketOptionTcpInfo(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 8: {
+
+            tcpiState_ = input.readUInt32();
+            break;
+          }
+          case 16: {
+
+            tcpiCaState_ = input.readUInt32();
+            break;
+          }
+          case 24: {
+
+            tcpiRetransmits_ = input.readUInt32();
+            break;
+          }
+          case 32: {
+
+            tcpiProbes_ = input.readUInt32();
+            break;
+          }
+          case 40: {
+
+            tcpiBackoff_ = input.readUInt32();
+            break;
+          }
+          case 48: {
+
+            tcpiOptions_ = input.readUInt32();
+            break;
+          }
+          case 56: {
+
+            tcpiSndWscale_ = input.readUInt32();
+            break;
+          }
+          case 64: {
+
+            tcpiRcvWscale_ = input.readUInt32();
+            break;
+          }
+          case 72: {
+
+            tcpiRto_ = input.readUInt32();
+            break;
+          }
+          case 80: {
+
+            tcpiAto_ = input.readUInt32();
+            break;
+          }
+          case 88: {
+
+            tcpiSndMss_ = input.readUInt32();
+            break;
+          }
+          case 96: {
+
+            tcpiRcvMss_ = input.readUInt32();
+            break;
+          }
+          case 104: {
+
+            tcpiUnacked_ = input.readUInt32();
+            break;
+          }
+          case 112: {
+
+            tcpiSacked_ = input.readUInt32();
+            break;
+          }
+          case 120: {
+
+            tcpiLost_ = input.readUInt32();
+            break;
+          }
+          case 128: {
+
+            tcpiRetrans_ = input.readUInt32();
+            break;
+          }
+          case 136: {
+
+            tcpiFackets_ = input.readUInt32();
+            break;
+          }
+          case 144: {
+
+            tcpiLastDataSent_ = input.readUInt32();
+            break;
+          }
+          case 152: {
+
+            tcpiLastAckSent_ = input.readUInt32();
+            break;
+          }
+          case 160: {
+
+            tcpiLastDataRecv_ = input.readUInt32();
+            break;
+          }
+          case 168: {
+
+            tcpiLastAckRecv_ = input.readUInt32();
+            break;
+          }
+          case 176: {
+
+            tcpiPmtu_ = input.readUInt32();
+            break;
+          }
+          case 184: {
+
+            tcpiRcvSsthresh_ = input.readUInt32();
+            break;
+          }
+          case 192: {
+
+            tcpiRtt_ = input.readUInt32();
+            break;
+          }
+          case 200: {
+
+            tcpiRttvar_ = input.readUInt32();
+            break;
+          }
+          case 208: {
+
+            tcpiSndSsthresh_ = input.readUInt32();
+            break;
+          }
+          case 216: {
+
+            tcpiSndCwnd_ = input.readUInt32();
+            break;
+          }
+          case 224: {
+
+            tcpiAdvmss_ = input.readUInt32();
+            break;
+          }
+          case 232: {
+
+            tcpiReordering_ = input.readUInt32();
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTcpInfo_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTcpInfo_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.SocketOptionTcpInfo.class, io.grpc.channelz.v1.SocketOptionTcpInfo.Builder.class);
+  }
+
+  public static final int TCPI_STATE_FIELD_NUMBER = 1;
+  private int tcpiState_;
+  /**
+   * <code>uint32 tcpi_state = 1;</code>
+   */
+  public int getTcpiState() {
+    return tcpiState_;
+  }
+
+  public static final int TCPI_CA_STATE_FIELD_NUMBER = 2;
+  private int tcpiCaState_;
+  /**
+   * <code>uint32 tcpi_ca_state = 2;</code>
+   */
+  public int getTcpiCaState() {
+    return tcpiCaState_;
+  }
+
+  public static final int TCPI_RETRANSMITS_FIELD_NUMBER = 3;
+  private int tcpiRetransmits_;
+  /**
+   * <code>uint32 tcpi_retransmits = 3;</code>
+   */
+  public int getTcpiRetransmits() {
+    return tcpiRetransmits_;
+  }
+
+  public static final int TCPI_PROBES_FIELD_NUMBER = 4;
+  private int tcpiProbes_;
+  /**
+   * <code>uint32 tcpi_probes = 4;</code>
+   */
+  public int getTcpiProbes() {
+    return tcpiProbes_;
+  }
+
+  public static final int TCPI_BACKOFF_FIELD_NUMBER = 5;
+  private int tcpiBackoff_;
+  /**
+   * <code>uint32 tcpi_backoff = 5;</code>
+   */
+  public int getTcpiBackoff() {
+    return tcpiBackoff_;
+  }
+
+  public static final int TCPI_OPTIONS_FIELD_NUMBER = 6;
+  private int tcpiOptions_;
+  /**
+   * <code>uint32 tcpi_options = 6;</code>
+   */
+  public int getTcpiOptions() {
+    return tcpiOptions_;
+  }
+
+  public static final int TCPI_SND_WSCALE_FIELD_NUMBER = 7;
+  private int tcpiSndWscale_;
+  /**
+   * <code>uint32 tcpi_snd_wscale = 7;</code>
+   */
+  public int getTcpiSndWscale() {
+    return tcpiSndWscale_;
+  }
+
+  public static final int TCPI_RCV_WSCALE_FIELD_NUMBER = 8;
+  private int tcpiRcvWscale_;
+  /**
+   * <code>uint32 tcpi_rcv_wscale = 8;</code>
+   */
+  public int getTcpiRcvWscale() {
+    return tcpiRcvWscale_;
+  }
+
+  public static final int TCPI_RTO_FIELD_NUMBER = 9;
+  private int tcpiRto_;
+  /**
+   * <code>uint32 tcpi_rto = 9;</code>
+   */
+  public int getTcpiRto() {
+    return tcpiRto_;
+  }
+
+  public static final int TCPI_ATO_FIELD_NUMBER = 10;
+  private int tcpiAto_;
+  /**
+   * <code>uint32 tcpi_ato = 10;</code>
+   */
+  public int getTcpiAto() {
+    return tcpiAto_;
+  }
+
+  public static final int TCPI_SND_MSS_FIELD_NUMBER = 11;
+  private int tcpiSndMss_;
+  /**
+   * <code>uint32 tcpi_snd_mss = 11;</code>
+   */
+  public int getTcpiSndMss() {
+    return tcpiSndMss_;
+  }
+
+  public static final int TCPI_RCV_MSS_FIELD_NUMBER = 12;
+  private int tcpiRcvMss_;
+  /**
+   * <code>uint32 tcpi_rcv_mss = 12;</code>
+   */
+  public int getTcpiRcvMss() {
+    return tcpiRcvMss_;
+  }
+
+  public static final int TCPI_UNACKED_FIELD_NUMBER = 13;
+  private int tcpiUnacked_;
+  /**
+   * <code>uint32 tcpi_unacked = 13;</code>
+   */
+  public int getTcpiUnacked() {
+    return tcpiUnacked_;
+  }
+
+  public static final int TCPI_SACKED_FIELD_NUMBER = 14;
+  private int tcpiSacked_;
+  /**
+   * <code>uint32 tcpi_sacked = 14;</code>
+   */
+  public int getTcpiSacked() {
+    return tcpiSacked_;
+  }
+
+  public static final int TCPI_LOST_FIELD_NUMBER = 15;
+  private int tcpiLost_;
+  /**
+   * <code>uint32 tcpi_lost = 15;</code>
+   */
+  public int getTcpiLost() {
+    return tcpiLost_;
+  }
+
+  public static final int TCPI_RETRANS_FIELD_NUMBER = 16;
+  private int tcpiRetrans_;
+  /**
+   * <code>uint32 tcpi_retrans = 16;</code>
+   */
+  public int getTcpiRetrans() {
+    return tcpiRetrans_;
+  }
+
+  public static final int TCPI_FACKETS_FIELD_NUMBER = 17;
+  private int tcpiFackets_;
+  /**
+   * <code>uint32 tcpi_fackets = 17;</code>
+   */
+  public int getTcpiFackets() {
+    return tcpiFackets_;
+  }
+
+  public static final int TCPI_LAST_DATA_SENT_FIELD_NUMBER = 18;
+  private int tcpiLastDataSent_;
+  /**
+   * <code>uint32 tcpi_last_data_sent = 18;</code>
+   */
+  public int getTcpiLastDataSent() {
+    return tcpiLastDataSent_;
+  }
+
+  public static final int TCPI_LAST_ACK_SENT_FIELD_NUMBER = 19;
+  private int tcpiLastAckSent_;
+  /**
+   * <code>uint32 tcpi_last_ack_sent = 19;</code>
+   */
+  public int getTcpiLastAckSent() {
+    return tcpiLastAckSent_;
+  }
+
+  public static final int TCPI_LAST_DATA_RECV_FIELD_NUMBER = 20;
+  private int tcpiLastDataRecv_;
+  /**
+   * <code>uint32 tcpi_last_data_recv = 20;</code>
+   */
+  public int getTcpiLastDataRecv() {
+    return tcpiLastDataRecv_;
+  }
+
+  public static final int TCPI_LAST_ACK_RECV_FIELD_NUMBER = 21;
+  private int tcpiLastAckRecv_;
+  /**
+   * <code>uint32 tcpi_last_ack_recv = 21;</code>
+   */
+  public int getTcpiLastAckRecv() {
+    return tcpiLastAckRecv_;
+  }
+
+  public static final int TCPI_PMTU_FIELD_NUMBER = 22;
+  private int tcpiPmtu_;
+  /**
+   * <code>uint32 tcpi_pmtu = 22;</code>
+   */
+  public int getTcpiPmtu() {
+    return tcpiPmtu_;
+  }
+
+  public static final int TCPI_RCV_SSTHRESH_FIELD_NUMBER = 23;
+  private int tcpiRcvSsthresh_;
+  /**
+   * <code>uint32 tcpi_rcv_ssthresh = 23;</code>
+   */
+  public int getTcpiRcvSsthresh() {
+    return tcpiRcvSsthresh_;
+  }
+
+  public static final int TCPI_RTT_FIELD_NUMBER = 24;
+  private int tcpiRtt_;
+  /**
+   * <code>uint32 tcpi_rtt = 24;</code>
+   */
+  public int getTcpiRtt() {
+    return tcpiRtt_;
+  }
+
+  public static final int TCPI_RTTVAR_FIELD_NUMBER = 25;
+  private int tcpiRttvar_;
+  /**
+   * <code>uint32 tcpi_rttvar = 25;</code>
+   */
+  public int getTcpiRttvar() {
+    return tcpiRttvar_;
+  }
+
+  public static final int TCPI_SND_SSTHRESH_FIELD_NUMBER = 26;
+  private int tcpiSndSsthresh_;
+  /**
+   * <code>uint32 tcpi_snd_ssthresh = 26;</code>
+   */
+  public int getTcpiSndSsthresh() {
+    return tcpiSndSsthresh_;
+  }
+
+  public static final int TCPI_SND_CWND_FIELD_NUMBER = 27;
+  private int tcpiSndCwnd_;
+  /**
+   * <code>uint32 tcpi_snd_cwnd = 27;</code>
+   */
+  public int getTcpiSndCwnd() {
+    return tcpiSndCwnd_;
+  }
+
+  public static final int TCPI_ADVMSS_FIELD_NUMBER = 28;
+  private int tcpiAdvmss_;
+  /**
+   * <code>uint32 tcpi_advmss = 28;</code>
+   */
+  public int getTcpiAdvmss() {
+    return tcpiAdvmss_;
+  }
+
+  public static final int TCPI_REORDERING_FIELD_NUMBER = 29;
+  private int tcpiReordering_;
+  /**
+   * <code>uint32 tcpi_reordering = 29;</code>
+   */
+  public int getTcpiReordering() {
+    return tcpiReordering_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (tcpiState_ != 0) {
+      output.writeUInt32(1, tcpiState_);
+    }
+    if (tcpiCaState_ != 0) {
+      output.writeUInt32(2, tcpiCaState_);
+    }
+    if (tcpiRetransmits_ != 0) {
+      output.writeUInt32(3, tcpiRetransmits_);
+    }
+    if (tcpiProbes_ != 0) {
+      output.writeUInt32(4, tcpiProbes_);
+    }
+    if (tcpiBackoff_ != 0) {
+      output.writeUInt32(5, tcpiBackoff_);
+    }
+    if (tcpiOptions_ != 0) {
+      output.writeUInt32(6, tcpiOptions_);
+    }
+    if (tcpiSndWscale_ != 0) {
+      output.writeUInt32(7, tcpiSndWscale_);
+    }
+    if (tcpiRcvWscale_ != 0) {
+      output.writeUInt32(8, tcpiRcvWscale_);
+    }
+    if (tcpiRto_ != 0) {
+      output.writeUInt32(9, tcpiRto_);
+    }
+    if (tcpiAto_ != 0) {
+      output.writeUInt32(10, tcpiAto_);
+    }
+    if (tcpiSndMss_ != 0) {
+      output.writeUInt32(11, tcpiSndMss_);
+    }
+    if (tcpiRcvMss_ != 0) {
+      output.writeUInt32(12, tcpiRcvMss_);
+    }
+    if (tcpiUnacked_ != 0) {
+      output.writeUInt32(13, tcpiUnacked_);
+    }
+    if (tcpiSacked_ != 0) {
+      output.writeUInt32(14, tcpiSacked_);
+    }
+    if (tcpiLost_ != 0) {
+      output.writeUInt32(15, tcpiLost_);
+    }
+    if (tcpiRetrans_ != 0) {
+      output.writeUInt32(16, tcpiRetrans_);
+    }
+    if (tcpiFackets_ != 0) {
+      output.writeUInt32(17, tcpiFackets_);
+    }
+    if (tcpiLastDataSent_ != 0) {
+      output.writeUInt32(18, tcpiLastDataSent_);
+    }
+    if (tcpiLastAckSent_ != 0) {
+      output.writeUInt32(19, tcpiLastAckSent_);
+    }
+    if (tcpiLastDataRecv_ != 0) {
+      output.writeUInt32(20, tcpiLastDataRecv_);
+    }
+    if (tcpiLastAckRecv_ != 0) {
+      output.writeUInt32(21, tcpiLastAckRecv_);
+    }
+    if (tcpiPmtu_ != 0) {
+      output.writeUInt32(22, tcpiPmtu_);
+    }
+    if (tcpiRcvSsthresh_ != 0) {
+      output.writeUInt32(23, tcpiRcvSsthresh_);
+    }
+    if (tcpiRtt_ != 0) {
+      output.writeUInt32(24, tcpiRtt_);
+    }
+    if (tcpiRttvar_ != 0) {
+      output.writeUInt32(25, tcpiRttvar_);
+    }
+    if (tcpiSndSsthresh_ != 0) {
+      output.writeUInt32(26, tcpiSndSsthresh_);
+    }
+    if (tcpiSndCwnd_ != 0) {
+      output.writeUInt32(27, tcpiSndCwnd_);
+    }
+    if (tcpiAdvmss_ != 0) {
+      output.writeUInt32(28, tcpiAdvmss_);
+    }
+    if (tcpiReordering_ != 0) {
+      output.writeUInt32(29, tcpiReordering_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (tcpiState_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(1, tcpiState_);
+    }
+    if (tcpiCaState_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(2, tcpiCaState_);
+    }
+    if (tcpiRetransmits_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(3, tcpiRetransmits_);
+    }
+    if (tcpiProbes_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(4, tcpiProbes_);
+    }
+    if (tcpiBackoff_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(5, tcpiBackoff_);
+    }
+    if (tcpiOptions_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(6, tcpiOptions_);
+    }
+    if (tcpiSndWscale_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(7, tcpiSndWscale_);
+    }
+    if (tcpiRcvWscale_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(8, tcpiRcvWscale_);
+    }
+    if (tcpiRto_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(9, tcpiRto_);
+    }
+    if (tcpiAto_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(10, tcpiAto_);
+    }
+    if (tcpiSndMss_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(11, tcpiSndMss_);
+    }
+    if (tcpiRcvMss_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(12, tcpiRcvMss_);
+    }
+    if (tcpiUnacked_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(13, tcpiUnacked_);
+    }
+    if (tcpiSacked_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(14, tcpiSacked_);
+    }
+    if (tcpiLost_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(15, tcpiLost_);
+    }
+    if (tcpiRetrans_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(16, tcpiRetrans_);
+    }
+    if (tcpiFackets_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(17, tcpiFackets_);
+    }
+    if (tcpiLastDataSent_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(18, tcpiLastDataSent_);
+    }
+    if (tcpiLastAckSent_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(19, tcpiLastAckSent_);
+    }
+    if (tcpiLastDataRecv_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(20, tcpiLastDataRecv_);
+    }
+    if (tcpiLastAckRecv_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(21, tcpiLastAckRecv_);
+    }
+    if (tcpiPmtu_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(22, tcpiPmtu_);
+    }
+    if (tcpiRcvSsthresh_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(23, tcpiRcvSsthresh_);
+    }
+    if (tcpiRtt_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(24, tcpiRtt_);
+    }
+    if (tcpiRttvar_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(25, tcpiRttvar_);
+    }
+    if (tcpiSndSsthresh_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(26, tcpiSndSsthresh_);
+    }
+    if (tcpiSndCwnd_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(27, tcpiSndCwnd_);
+    }
+    if (tcpiAdvmss_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(28, tcpiAdvmss_);
+    }
+    if (tcpiReordering_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeUInt32Size(29, tcpiReordering_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.SocketOptionTcpInfo)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.SocketOptionTcpInfo other = (io.grpc.channelz.v1.SocketOptionTcpInfo) obj;
+
+    boolean result = true;
+    result = result && (getTcpiState()
+        == other.getTcpiState());
+    result = result && (getTcpiCaState()
+        == other.getTcpiCaState());
+    result = result && (getTcpiRetransmits()
+        == other.getTcpiRetransmits());
+    result = result && (getTcpiProbes()
+        == other.getTcpiProbes());
+    result = result && (getTcpiBackoff()
+        == other.getTcpiBackoff());
+    result = result && (getTcpiOptions()
+        == other.getTcpiOptions());
+    result = result && (getTcpiSndWscale()
+        == other.getTcpiSndWscale());
+    result = result && (getTcpiRcvWscale()
+        == other.getTcpiRcvWscale());
+    result = result && (getTcpiRto()
+        == other.getTcpiRto());
+    result = result && (getTcpiAto()
+        == other.getTcpiAto());
+    result = result && (getTcpiSndMss()
+        == other.getTcpiSndMss());
+    result = result && (getTcpiRcvMss()
+        == other.getTcpiRcvMss());
+    result = result && (getTcpiUnacked()
+        == other.getTcpiUnacked());
+    result = result && (getTcpiSacked()
+        == other.getTcpiSacked());
+    result = result && (getTcpiLost()
+        == other.getTcpiLost());
+    result = result && (getTcpiRetrans()
+        == other.getTcpiRetrans());
+    result = result && (getTcpiFackets()
+        == other.getTcpiFackets());
+    result = result && (getTcpiLastDataSent()
+        == other.getTcpiLastDataSent());
+    result = result && (getTcpiLastAckSent()
+        == other.getTcpiLastAckSent());
+    result = result && (getTcpiLastDataRecv()
+        == other.getTcpiLastDataRecv());
+    result = result && (getTcpiLastAckRecv()
+        == other.getTcpiLastAckRecv());
+    result = result && (getTcpiPmtu()
+        == other.getTcpiPmtu());
+    result = result && (getTcpiRcvSsthresh()
+        == other.getTcpiRcvSsthresh());
+    result = result && (getTcpiRtt()
+        == other.getTcpiRtt());
+    result = result && (getTcpiRttvar()
+        == other.getTcpiRttvar());
+    result = result && (getTcpiSndSsthresh()
+        == other.getTcpiSndSsthresh());
+    result = result && (getTcpiSndCwnd()
+        == other.getTcpiSndCwnd());
+    result = result && (getTcpiAdvmss()
+        == other.getTcpiAdvmss());
+    result = result && (getTcpiReordering()
+        == other.getTcpiReordering());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + TCPI_STATE_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiState();
+    hash = (37 * hash) + TCPI_CA_STATE_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiCaState();
+    hash = (37 * hash) + TCPI_RETRANSMITS_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRetransmits();
+    hash = (37 * hash) + TCPI_PROBES_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiProbes();
+    hash = (37 * hash) + TCPI_BACKOFF_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiBackoff();
+    hash = (37 * hash) + TCPI_OPTIONS_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiOptions();
+    hash = (37 * hash) + TCPI_SND_WSCALE_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiSndWscale();
+    hash = (37 * hash) + TCPI_RCV_WSCALE_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRcvWscale();
+    hash = (37 * hash) + TCPI_RTO_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRto();
+    hash = (37 * hash) + TCPI_ATO_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiAto();
+    hash = (37 * hash) + TCPI_SND_MSS_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiSndMss();
+    hash = (37 * hash) + TCPI_RCV_MSS_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRcvMss();
+    hash = (37 * hash) + TCPI_UNACKED_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiUnacked();
+    hash = (37 * hash) + TCPI_SACKED_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiSacked();
+    hash = (37 * hash) + TCPI_LOST_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiLost();
+    hash = (37 * hash) + TCPI_RETRANS_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRetrans();
+    hash = (37 * hash) + TCPI_FACKETS_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiFackets();
+    hash = (37 * hash) + TCPI_LAST_DATA_SENT_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiLastDataSent();
+    hash = (37 * hash) + TCPI_LAST_ACK_SENT_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiLastAckSent();
+    hash = (37 * hash) + TCPI_LAST_DATA_RECV_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiLastDataRecv();
+    hash = (37 * hash) + TCPI_LAST_ACK_RECV_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiLastAckRecv();
+    hash = (37 * hash) + TCPI_PMTU_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiPmtu();
+    hash = (37 * hash) + TCPI_RCV_SSTHRESH_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRcvSsthresh();
+    hash = (37 * hash) + TCPI_RTT_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRtt();
+    hash = (37 * hash) + TCPI_RTTVAR_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiRttvar();
+    hash = (37 * hash) + TCPI_SND_SSTHRESH_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiSndSsthresh();
+    hash = (37 * hash) + TCPI_SND_CWND_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiSndCwnd();
+    hash = (37 * hash) + TCPI_ADVMSS_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiAdvmss();
+    hash = (37 * hash) + TCPI_REORDERING_FIELD_NUMBER;
+    hash = (53 * hash) + getTcpiReordering();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.SocketOptionTcpInfo prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * Tcp info for SOL_TCP, TCP_INFO
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.SocketOptionTcpInfo}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.SocketOptionTcpInfo)
+      io.grpc.channelz.v1.SocketOptionTcpInfoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTcpInfo_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTcpInfo_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.SocketOptionTcpInfo.class, io.grpc.channelz.v1.SocketOptionTcpInfo.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.SocketOptionTcpInfo.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      tcpiState_ = 0;
+
+      tcpiCaState_ = 0;
+
+      tcpiRetransmits_ = 0;
+
+      tcpiProbes_ = 0;
+
+      tcpiBackoff_ = 0;
+
+      tcpiOptions_ = 0;
+
+      tcpiSndWscale_ = 0;
+
+      tcpiRcvWscale_ = 0;
+
+      tcpiRto_ = 0;
+
+      tcpiAto_ = 0;
+
+      tcpiSndMss_ = 0;
+
+      tcpiRcvMss_ = 0;
+
+      tcpiUnacked_ = 0;
+
+      tcpiSacked_ = 0;
+
+      tcpiLost_ = 0;
+
+      tcpiRetrans_ = 0;
+
+      tcpiFackets_ = 0;
+
+      tcpiLastDataSent_ = 0;
+
+      tcpiLastAckSent_ = 0;
+
+      tcpiLastDataRecv_ = 0;
+
+      tcpiLastAckRecv_ = 0;
+
+      tcpiPmtu_ = 0;
+
+      tcpiRcvSsthresh_ = 0;
+
+      tcpiRtt_ = 0;
+
+      tcpiRttvar_ = 0;
+
+      tcpiSndSsthresh_ = 0;
+
+      tcpiSndCwnd_ = 0;
+
+      tcpiAdvmss_ = 0;
+
+      tcpiReordering_ = 0;
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTcpInfo_descriptor;
+    }
+
+    public io.grpc.channelz.v1.SocketOptionTcpInfo getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.SocketOptionTcpInfo.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.SocketOptionTcpInfo build() {
+      io.grpc.channelz.v1.SocketOptionTcpInfo result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.SocketOptionTcpInfo buildPartial() {
+      io.grpc.channelz.v1.SocketOptionTcpInfo result = new io.grpc.channelz.v1.SocketOptionTcpInfo(this);
+      result.tcpiState_ = tcpiState_;
+      result.tcpiCaState_ = tcpiCaState_;
+      result.tcpiRetransmits_ = tcpiRetransmits_;
+      result.tcpiProbes_ = tcpiProbes_;
+      result.tcpiBackoff_ = tcpiBackoff_;
+      result.tcpiOptions_ = tcpiOptions_;
+      result.tcpiSndWscale_ = tcpiSndWscale_;
+      result.tcpiRcvWscale_ = tcpiRcvWscale_;
+      result.tcpiRto_ = tcpiRto_;
+      result.tcpiAto_ = tcpiAto_;
+      result.tcpiSndMss_ = tcpiSndMss_;
+      result.tcpiRcvMss_ = tcpiRcvMss_;
+      result.tcpiUnacked_ = tcpiUnacked_;
+      result.tcpiSacked_ = tcpiSacked_;
+      result.tcpiLost_ = tcpiLost_;
+      result.tcpiRetrans_ = tcpiRetrans_;
+      result.tcpiFackets_ = tcpiFackets_;
+      result.tcpiLastDataSent_ = tcpiLastDataSent_;
+      result.tcpiLastAckSent_ = tcpiLastAckSent_;
+      result.tcpiLastDataRecv_ = tcpiLastDataRecv_;
+      result.tcpiLastAckRecv_ = tcpiLastAckRecv_;
+      result.tcpiPmtu_ = tcpiPmtu_;
+      result.tcpiRcvSsthresh_ = tcpiRcvSsthresh_;
+      result.tcpiRtt_ = tcpiRtt_;
+      result.tcpiRttvar_ = tcpiRttvar_;
+      result.tcpiSndSsthresh_ = tcpiSndSsthresh_;
+      result.tcpiSndCwnd_ = tcpiSndCwnd_;
+      result.tcpiAdvmss_ = tcpiAdvmss_;
+      result.tcpiReordering_ = tcpiReordering_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.SocketOptionTcpInfo) {
+        return mergeFrom((io.grpc.channelz.v1.SocketOptionTcpInfo)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.SocketOptionTcpInfo other) {
+      if (other == io.grpc.channelz.v1.SocketOptionTcpInfo.getDefaultInstance()) return this;
+      if (other.getTcpiState() != 0) {
+        setTcpiState(other.getTcpiState());
+      }
+      if (other.getTcpiCaState() != 0) {
+        setTcpiCaState(other.getTcpiCaState());
+      }
+      if (other.getTcpiRetransmits() != 0) {
+        setTcpiRetransmits(other.getTcpiRetransmits());
+      }
+      if (other.getTcpiProbes() != 0) {
+        setTcpiProbes(other.getTcpiProbes());
+      }
+      if (other.getTcpiBackoff() != 0) {
+        setTcpiBackoff(other.getTcpiBackoff());
+      }
+      if (other.getTcpiOptions() != 0) {
+        setTcpiOptions(other.getTcpiOptions());
+      }
+      if (other.getTcpiSndWscale() != 0) {
+        setTcpiSndWscale(other.getTcpiSndWscale());
+      }
+      if (other.getTcpiRcvWscale() != 0) {
+        setTcpiRcvWscale(other.getTcpiRcvWscale());
+      }
+      if (other.getTcpiRto() != 0) {
+        setTcpiRto(other.getTcpiRto());
+      }
+      if (other.getTcpiAto() != 0) {
+        setTcpiAto(other.getTcpiAto());
+      }
+      if (other.getTcpiSndMss() != 0) {
+        setTcpiSndMss(other.getTcpiSndMss());
+      }
+      if (other.getTcpiRcvMss() != 0) {
+        setTcpiRcvMss(other.getTcpiRcvMss());
+      }
+      if (other.getTcpiUnacked() != 0) {
+        setTcpiUnacked(other.getTcpiUnacked());
+      }
+      if (other.getTcpiSacked() != 0) {
+        setTcpiSacked(other.getTcpiSacked());
+      }
+      if (other.getTcpiLost() != 0) {
+        setTcpiLost(other.getTcpiLost());
+      }
+      if (other.getTcpiRetrans() != 0) {
+        setTcpiRetrans(other.getTcpiRetrans());
+      }
+      if (other.getTcpiFackets() != 0) {
+        setTcpiFackets(other.getTcpiFackets());
+      }
+      if (other.getTcpiLastDataSent() != 0) {
+        setTcpiLastDataSent(other.getTcpiLastDataSent());
+      }
+      if (other.getTcpiLastAckSent() != 0) {
+        setTcpiLastAckSent(other.getTcpiLastAckSent());
+      }
+      if (other.getTcpiLastDataRecv() != 0) {
+        setTcpiLastDataRecv(other.getTcpiLastDataRecv());
+      }
+      if (other.getTcpiLastAckRecv() != 0) {
+        setTcpiLastAckRecv(other.getTcpiLastAckRecv());
+      }
+      if (other.getTcpiPmtu() != 0) {
+        setTcpiPmtu(other.getTcpiPmtu());
+      }
+      if (other.getTcpiRcvSsthresh() != 0) {
+        setTcpiRcvSsthresh(other.getTcpiRcvSsthresh());
+      }
+      if (other.getTcpiRtt() != 0) {
+        setTcpiRtt(other.getTcpiRtt());
+      }
+      if (other.getTcpiRttvar() != 0) {
+        setTcpiRttvar(other.getTcpiRttvar());
+      }
+      if (other.getTcpiSndSsthresh() != 0) {
+        setTcpiSndSsthresh(other.getTcpiSndSsthresh());
+      }
+      if (other.getTcpiSndCwnd() != 0) {
+        setTcpiSndCwnd(other.getTcpiSndCwnd());
+      }
+      if (other.getTcpiAdvmss() != 0) {
+        setTcpiAdvmss(other.getTcpiAdvmss());
+      }
+      if (other.getTcpiReordering() != 0) {
+        setTcpiReordering(other.getTcpiReordering());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.SocketOptionTcpInfo parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.SocketOptionTcpInfo) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private int tcpiState_ ;
+    /**
+     * <code>uint32 tcpi_state = 1;</code>
+     */
+    public int getTcpiState() {
+      return tcpiState_;
+    }
+    /**
+     * <code>uint32 tcpi_state = 1;</code>
+     */
+    public Builder setTcpiState(int value) {
+      
+      tcpiState_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_state = 1;</code>
+     */
+    public Builder clearTcpiState() {
+      
+      tcpiState_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiCaState_ ;
+    /**
+     * <code>uint32 tcpi_ca_state = 2;</code>
+     */
+    public int getTcpiCaState() {
+      return tcpiCaState_;
+    }
+    /**
+     * <code>uint32 tcpi_ca_state = 2;</code>
+     */
+    public Builder setTcpiCaState(int value) {
+      
+      tcpiCaState_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_ca_state = 2;</code>
+     */
+    public Builder clearTcpiCaState() {
+      
+      tcpiCaState_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRetransmits_ ;
+    /**
+     * <code>uint32 tcpi_retransmits = 3;</code>
+     */
+    public int getTcpiRetransmits() {
+      return tcpiRetransmits_;
+    }
+    /**
+     * <code>uint32 tcpi_retransmits = 3;</code>
+     */
+    public Builder setTcpiRetransmits(int value) {
+      
+      tcpiRetransmits_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_retransmits = 3;</code>
+     */
+    public Builder clearTcpiRetransmits() {
+      
+      tcpiRetransmits_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiProbes_ ;
+    /**
+     * <code>uint32 tcpi_probes = 4;</code>
+     */
+    public int getTcpiProbes() {
+      return tcpiProbes_;
+    }
+    /**
+     * <code>uint32 tcpi_probes = 4;</code>
+     */
+    public Builder setTcpiProbes(int value) {
+      
+      tcpiProbes_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_probes = 4;</code>
+     */
+    public Builder clearTcpiProbes() {
+      
+      tcpiProbes_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiBackoff_ ;
+    /**
+     * <code>uint32 tcpi_backoff = 5;</code>
+     */
+    public int getTcpiBackoff() {
+      return tcpiBackoff_;
+    }
+    /**
+     * <code>uint32 tcpi_backoff = 5;</code>
+     */
+    public Builder setTcpiBackoff(int value) {
+      
+      tcpiBackoff_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_backoff = 5;</code>
+     */
+    public Builder clearTcpiBackoff() {
+      
+      tcpiBackoff_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiOptions_ ;
+    /**
+     * <code>uint32 tcpi_options = 6;</code>
+     */
+    public int getTcpiOptions() {
+      return tcpiOptions_;
+    }
+    /**
+     * <code>uint32 tcpi_options = 6;</code>
+     */
+    public Builder setTcpiOptions(int value) {
+      
+      tcpiOptions_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_options = 6;</code>
+     */
+    public Builder clearTcpiOptions() {
+      
+      tcpiOptions_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiSndWscale_ ;
+    /**
+     * <code>uint32 tcpi_snd_wscale = 7;</code>
+     */
+    public int getTcpiSndWscale() {
+      return tcpiSndWscale_;
+    }
+    /**
+     * <code>uint32 tcpi_snd_wscale = 7;</code>
+     */
+    public Builder setTcpiSndWscale(int value) {
+      
+      tcpiSndWscale_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_snd_wscale = 7;</code>
+     */
+    public Builder clearTcpiSndWscale() {
+      
+      tcpiSndWscale_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRcvWscale_ ;
+    /**
+     * <code>uint32 tcpi_rcv_wscale = 8;</code>
+     */
+    public int getTcpiRcvWscale() {
+      return tcpiRcvWscale_;
+    }
+    /**
+     * <code>uint32 tcpi_rcv_wscale = 8;</code>
+     */
+    public Builder setTcpiRcvWscale(int value) {
+      
+      tcpiRcvWscale_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_rcv_wscale = 8;</code>
+     */
+    public Builder clearTcpiRcvWscale() {
+      
+      tcpiRcvWscale_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRto_ ;
+    /**
+     * <code>uint32 tcpi_rto = 9;</code>
+     */
+    public int getTcpiRto() {
+      return tcpiRto_;
+    }
+    /**
+     * <code>uint32 tcpi_rto = 9;</code>
+     */
+    public Builder setTcpiRto(int value) {
+      
+      tcpiRto_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_rto = 9;</code>
+     */
+    public Builder clearTcpiRto() {
+      
+      tcpiRto_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiAto_ ;
+    /**
+     * <code>uint32 tcpi_ato = 10;</code>
+     */
+    public int getTcpiAto() {
+      return tcpiAto_;
+    }
+    /**
+     * <code>uint32 tcpi_ato = 10;</code>
+     */
+    public Builder setTcpiAto(int value) {
+      
+      tcpiAto_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_ato = 10;</code>
+     */
+    public Builder clearTcpiAto() {
+      
+      tcpiAto_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiSndMss_ ;
+    /**
+     * <code>uint32 tcpi_snd_mss = 11;</code>
+     */
+    public int getTcpiSndMss() {
+      return tcpiSndMss_;
+    }
+    /**
+     * <code>uint32 tcpi_snd_mss = 11;</code>
+     */
+    public Builder setTcpiSndMss(int value) {
+      
+      tcpiSndMss_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_snd_mss = 11;</code>
+     */
+    public Builder clearTcpiSndMss() {
+      
+      tcpiSndMss_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRcvMss_ ;
+    /**
+     * <code>uint32 tcpi_rcv_mss = 12;</code>
+     */
+    public int getTcpiRcvMss() {
+      return tcpiRcvMss_;
+    }
+    /**
+     * <code>uint32 tcpi_rcv_mss = 12;</code>
+     */
+    public Builder setTcpiRcvMss(int value) {
+      
+      tcpiRcvMss_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_rcv_mss = 12;</code>
+     */
+    public Builder clearTcpiRcvMss() {
+      
+      tcpiRcvMss_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiUnacked_ ;
+    /**
+     * <code>uint32 tcpi_unacked = 13;</code>
+     */
+    public int getTcpiUnacked() {
+      return tcpiUnacked_;
+    }
+    /**
+     * <code>uint32 tcpi_unacked = 13;</code>
+     */
+    public Builder setTcpiUnacked(int value) {
+      
+      tcpiUnacked_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_unacked = 13;</code>
+     */
+    public Builder clearTcpiUnacked() {
+      
+      tcpiUnacked_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiSacked_ ;
+    /**
+     * <code>uint32 tcpi_sacked = 14;</code>
+     */
+    public int getTcpiSacked() {
+      return tcpiSacked_;
+    }
+    /**
+     * <code>uint32 tcpi_sacked = 14;</code>
+     */
+    public Builder setTcpiSacked(int value) {
+      
+      tcpiSacked_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_sacked = 14;</code>
+     */
+    public Builder clearTcpiSacked() {
+      
+      tcpiSacked_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiLost_ ;
+    /**
+     * <code>uint32 tcpi_lost = 15;</code>
+     */
+    public int getTcpiLost() {
+      return tcpiLost_;
+    }
+    /**
+     * <code>uint32 tcpi_lost = 15;</code>
+     */
+    public Builder setTcpiLost(int value) {
+      
+      tcpiLost_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_lost = 15;</code>
+     */
+    public Builder clearTcpiLost() {
+      
+      tcpiLost_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRetrans_ ;
+    /**
+     * <code>uint32 tcpi_retrans = 16;</code>
+     */
+    public int getTcpiRetrans() {
+      return tcpiRetrans_;
+    }
+    /**
+     * <code>uint32 tcpi_retrans = 16;</code>
+     */
+    public Builder setTcpiRetrans(int value) {
+      
+      tcpiRetrans_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_retrans = 16;</code>
+     */
+    public Builder clearTcpiRetrans() {
+      
+      tcpiRetrans_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiFackets_ ;
+    /**
+     * <code>uint32 tcpi_fackets = 17;</code>
+     */
+    public int getTcpiFackets() {
+      return tcpiFackets_;
+    }
+    /**
+     * <code>uint32 tcpi_fackets = 17;</code>
+     */
+    public Builder setTcpiFackets(int value) {
+      
+      tcpiFackets_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_fackets = 17;</code>
+     */
+    public Builder clearTcpiFackets() {
+      
+      tcpiFackets_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiLastDataSent_ ;
+    /**
+     * <code>uint32 tcpi_last_data_sent = 18;</code>
+     */
+    public int getTcpiLastDataSent() {
+      return tcpiLastDataSent_;
+    }
+    /**
+     * <code>uint32 tcpi_last_data_sent = 18;</code>
+     */
+    public Builder setTcpiLastDataSent(int value) {
+      
+      tcpiLastDataSent_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_last_data_sent = 18;</code>
+     */
+    public Builder clearTcpiLastDataSent() {
+      
+      tcpiLastDataSent_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiLastAckSent_ ;
+    /**
+     * <code>uint32 tcpi_last_ack_sent = 19;</code>
+     */
+    public int getTcpiLastAckSent() {
+      return tcpiLastAckSent_;
+    }
+    /**
+     * <code>uint32 tcpi_last_ack_sent = 19;</code>
+     */
+    public Builder setTcpiLastAckSent(int value) {
+      
+      tcpiLastAckSent_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_last_ack_sent = 19;</code>
+     */
+    public Builder clearTcpiLastAckSent() {
+      
+      tcpiLastAckSent_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiLastDataRecv_ ;
+    /**
+     * <code>uint32 tcpi_last_data_recv = 20;</code>
+     */
+    public int getTcpiLastDataRecv() {
+      return tcpiLastDataRecv_;
+    }
+    /**
+     * <code>uint32 tcpi_last_data_recv = 20;</code>
+     */
+    public Builder setTcpiLastDataRecv(int value) {
+      
+      tcpiLastDataRecv_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_last_data_recv = 20;</code>
+     */
+    public Builder clearTcpiLastDataRecv() {
+      
+      tcpiLastDataRecv_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiLastAckRecv_ ;
+    /**
+     * <code>uint32 tcpi_last_ack_recv = 21;</code>
+     */
+    public int getTcpiLastAckRecv() {
+      return tcpiLastAckRecv_;
+    }
+    /**
+     * <code>uint32 tcpi_last_ack_recv = 21;</code>
+     */
+    public Builder setTcpiLastAckRecv(int value) {
+      
+      tcpiLastAckRecv_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_last_ack_recv = 21;</code>
+     */
+    public Builder clearTcpiLastAckRecv() {
+      
+      tcpiLastAckRecv_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiPmtu_ ;
+    /**
+     * <code>uint32 tcpi_pmtu = 22;</code>
+     */
+    public int getTcpiPmtu() {
+      return tcpiPmtu_;
+    }
+    /**
+     * <code>uint32 tcpi_pmtu = 22;</code>
+     */
+    public Builder setTcpiPmtu(int value) {
+      
+      tcpiPmtu_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_pmtu = 22;</code>
+     */
+    public Builder clearTcpiPmtu() {
+      
+      tcpiPmtu_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRcvSsthresh_ ;
+    /**
+     * <code>uint32 tcpi_rcv_ssthresh = 23;</code>
+     */
+    public int getTcpiRcvSsthresh() {
+      return tcpiRcvSsthresh_;
+    }
+    /**
+     * <code>uint32 tcpi_rcv_ssthresh = 23;</code>
+     */
+    public Builder setTcpiRcvSsthresh(int value) {
+      
+      tcpiRcvSsthresh_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_rcv_ssthresh = 23;</code>
+     */
+    public Builder clearTcpiRcvSsthresh() {
+      
+      tcpiRcvSsthresh_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRtt_ ;
+    /**
+     * <code>uint32 tcpi_rtt = 24;</code>
+     */
+    public int getTcpiRtt() {
+      return tcpiRtt_;
+    }
+    /**
+     * <code>uint32 tcpi_rtt = 24;</code>
+     */
+    public Builder setTcpiRtt(int value) {
+      
+      tcpiRtt_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_rtt = 24;</code>
+     */
+    public Builder clearTcpiRtt() {
+      
+      tcpiRtt_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiRttvar_ ;
+    /**
+     * <code>uint32 tcpi_rttvar = 25;</code>
+     */
+    public int getTcpiRttvar() {
+      return tcpiRttvar_;
+    }
+    /**
+     * <code>uint32 tcpi_rttvar = 25;</code>
+     */
+    public Builder setTcpiRttvar(int value) {
+      
+      tcpiRttvar_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_rttvar = 25;</code>
+     */
+    public Builder clearTcpiRttvar() {
+      
+      tcpiRttvar_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiSndSsthresh_ ;
+    /**
+     * <code>uint32 tcpi_snd_ssthresh = 26;</code>
+     */
+    public int getTcpiSndSsthresh() {
+      return tcpiSndSsthresh_;
+    }
+    /**
+     * <code>uint32 tcpi_snd_ssthresh = 26;</code>
+     */
+    public Builder setTcpiSndSsthresh(int value) {
+      
+      tcpiSndSsthresh_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_snd_ssthresh = 26;</code>
+     */
+    public Builder clearTcpiSndSsthresh() {
+      
+      tcpiSndSsthresh_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiSndCwnd_ ;
+    /**
+     * <code>uint32 tcpi_snd_cwnd = 27;</code>
+     */
+    public int getTcpiSndCwnd() {
+      return tcpiSndCwnd_;
+    }
+    /**
+     * <code>uint32 tcpi_snd_cwnd = 27;</code>
+     */
+    public Builder setTcpiSndCwnd(int value) {
+      
+      tcpiSndCwnd_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_snd_cwnd = 27;</code>
+     */
+    public Builder clearTcpiSndCwnd() {
+      
+      tcpiSndCwnd_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiAdvmss_ ;
+    /**
+     * <code>uint32 tcpi_advmss = 28;</code>
+     */
+    public int getTcpiAdvmss() {
+      return tcpiAdvmss_;
+    }
+    /**
+     * <code>uint32 tcpi_advmss = 28;</code>
+     */
+    public Builder setTcpiAdvmss(int value) {
+      
+      tcpiAdvmss_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_advmss = 28;</code>
+     */
+    public Builder clearTcpiAdvmss() {
+      
+      tcpiAdvmss_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int tcpiReordering_ ;
+    /**
+     * <code>uint32 tcpi_reordering = 29;</code>
+     */
+    public int getTcpiReordering() {
+      return tcpiReordering_;
+    }
+    /**
+     * <code>uint32 tcpi_reordering = 29;</code>
+     */
+    public Builder setTcpiReordering(int value) {
+      
+      tcpiReordering_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>uint32 tcpi_reordering = 29;</code>
+     */
+    public Builder clearTcpiReordering() {
+      
+      tcpiReordering_ = 0;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.SocketOptionTcpInfo)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.SocketOptionTcpInfo)
+  private static final io.grpc.channelz.v1.SocketOptionTcpInfo DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.SocketOptionTcpInfo();
+  }
+
+  public static io.grpc.channelz.v1.SocketOptionTcpInfo getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<SocketOptionTcpInfo>
+      PARSER = new com.google.protobuf.AbstractParser<SocketOptionTcpInfo>() {
+    public SocketOptionTcpInfo parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new SocketOptionTcpInfo(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<SocketOptionTcpInfo> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<SocketOptionTcpInfo> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.SocketOptionTcpInfo getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTcpInfoOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTcpInfoOrBuilder.java
new file mode 100644
index 0000000..1dea283
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTcpInfoOrBuilder.java
@@ -0,0 +1,154 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SocketOptionTcpInfoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.SocketOptionTcpInfo)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>uint32 tcpi_state = 1;</code>
+   */
+  int getTcpiState();
+
+  /**
+   * <code>uint32 tcpi_ca_state = 2;</code>
+   */
+  int getTcpiCaState();
+
+  /**
+   * <code>uint32 tcpi_retransmits = 3;</code>
+   */
+  int getTcpiRetransmits();
+
+  /**
+   * <code>uint32 tcpi_probes = 4;</code>
+   */
+  int getTcpiProbes();
+
+  /**
+   * <code>uint32 tcpi_backoff = 5;</code>
+   */
+  int getTcpiBackoff();
+
+  /**
+   * <code>uint32 tcpi_options = 6;</code>
+   */
+  int getTcpiOptions();
+
+  /**
+   * <code>uint32 tcpi_snd_wscale = 7;</code>
+   */
+  int getTcpiSndWscale();
+
+  /**
+   * <code>uint32 tcpi_rcv_wscale = 8;</code>
+   */
+  int getTcpiRcvWscale();
+
+  /**
+   * <code>uint32 tcpi_rto = 9;</code>
+   */
+  int getTcpiRto();
+
+  /**
+   * <code>uint32 tcpi_ato = 10;</code>
+   */
+  int getTcpiAto();
+
+  /**
+   * <code>uint32 tcpi_snd_mss = 11;</code>
+   */
+  int getTcpiSndMss();
+
+  /**
+   * <code>uint32 tcpi_rcv_mss = 12;</code>
+   */
+  int getTcpiRcvMss();
+
+  /**
+   * <code>uint32 tcpi_unacked = 13;</code>
+   */
+  int getTcpiUnacked();
+
+  /**
+   * <code>uint32 tcpi_sacked = 14;</code>
+   */
+  int getTcpiSacked();
+
+  /**
+   * <code>uint32 tcpi_lost = 15;</code>
+   */
+  int getTcpiLost();
+
+  /**
+   * <code>uint32 tcpi_retrans = 16;</code>
+   */
+  int getTcpiRetrans();
+
+  /**
+   * <code>uint32 tcpi_fackets = 17;</code>
+   */
+  int getTcpiFackets();
+
+  /**
+   * <code>uint32 tcpi_last_data_sent = 18;</code>
+   */
+  int getTcpiLastDataSent();
+
+  /**
+   * <code>uint32 tcpi_last_ack_sent = 19;</code>
+   */
+  int getTcpiLastAckSent();
+
+  /**
+   * <code>uint32 tcpi_last_data_recv = 20;</code>
+   */
+  int getTcpiLastDataRecv();
+
+  /**
+   * <code>uint32 tcpi_last_ack_recv = 21;</code>
+   */
+  int getTcpiLastAckRecv();
+
+  /**
+   * <code>uint32 tcpi_pmtu = 22;</code>
+   */
+  int getTcpiPmtu();
+
+  /**
+   * <code>uint32 tcpi_rcv_ssthresh = 23;</code>
+   */
+  int getTcpiRcvSsthresh();
+
+  /**
+   * <code>uint32 tcpi_rtt = 24;</code>
+   */
+  int getTcpiRtt();
+
+  /**
+   * <code>uint32 tcpi_rttvar = 25;</code>
+   */
+  int getTcpiRttvar();
+
+  /**
+   * <code>uint32 tcpi_snd_ssthresh = 26;</code>
+   */
+  int getTcpiSndSsthresh();
+
+  /**
+   * <code>uint32 tcpi_snd_cwnd = 27;</code>
+   */
+  int getTcpiSndCwnd();
+
+  /**
+   * <code>uint32 tcpi_advmss = 28;</code>
+   */
+  int getTcpiAdvmss();
+
+  /**
+   * <code>uint32 tcpi_reordering = 29;</code>
+   */
+  int getTcpiReordering();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTimeout.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTimeout.java
new file mode 100644
index 0000000..fa876e5
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTimeout.java
@@ -0,0 +1,580 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * <pre>
+ * For use with SocketOption's additional field.  This is primarily used for
+ * SO_RCVTIMEO and SO_SNDTIMEO
+ * </pre>
+ *
+ * Protobuf type {@code grpc.channelz.SocketOptionTimeout}
+ */
+public  final class SocketOptionTimeout extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.SocketOptionTimeout)
+    SocketOptionTimeoutOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use SocketOptionTimeout.newBuilder() to construct.
+  private SocketOptionTimeout(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private SocketOptionTimeout() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private SocketOptionTimeout(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            com.google.protobuf.Duration.Builder subBuilder = null;
+            if (duration_ != null) {
+              subBuilder = duration_.toBuilder();
+            }
+            duration_ = input.readMessage(com.google.protobuf.Duration.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(duration_);
+              duration_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTimeout_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTimeout_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.SocketOptionTimeout.class, io.grpc.channelz.v1.SocketOptionTimeout.Builder.class);
+  }
+
+  public static final int DURATION_FIELD_NUMBER = 1;
+  private com.google.protobuf.Duration duration_;
+  /**
+   * <code>.google.protobuf.Duration duration = 1;</code>
+   */
+  public boolean hasDuration() {
+    return duration_ != null;
+  }
+  /**
+   * <code>.google.protobuf.Duration duration = 1;</code>
+   */
+  public com.google.protobuf.Duration getDuration() {
+    return duration_ == null ? com.google.protobuf.Duration.getDefaultInstance() : duration_;
+  }
+  /**
+   * <code>.google.protobuf.Duration duration = 1;</code>
+   */
+  public com.google.protobuf.DurationOrBuilder getDurationOrBuilder() {
+    return getDuration();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (duration_ != null) {
+      output.writeMessage(1, getDuration());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (duration_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getDuration());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.SocketOptionTimeout)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.SocketOptionTimeout other = (io.grpc.channelz.v1.SocketOptionTimeout) obj;
+
+    boolean result = true;
+    result = result && (hasDuration() == other.hasDuration());
+    if (hasDuration()) {
+      result = result && getDuration()
+          .equals(other.getDuration());
+    }
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasDuration()) {
+      hash = (37 * hash) + DURATION_FIELD_NUMBER;
+      hash = (53 * hash) + getDuration().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketOptionTimeout parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.SocketOptionTimeout prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * For use with SocketOption's additional field.  This is primarily used for
+   * SO_RCVTIMEO and SO_SNDTIMEO
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.SocketOptionTimeout}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.SocketOptionTimeout)
+      io.grpc.channelz.v1.SocketOptionTimeoutOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTimeout_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTimeout_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.SocketOptionTimeout.class, io.grpc.channelz.v1.SocketOptionTimeout.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.SocketOptionTimeout.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (durationBuilder_ == null) {
+        duration_ = null;
+      } else {
+        duration_ = null;
+        durationBuilder_ = null;
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketOptionTimeout_descriptor;
+    }
+
+    public io.grpc.channelz.v1.SocketOptionTimeout getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.SocketOptionTimeout.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.SocketOptionTimeout build() {
+      io.grpc.channelz.v1.SocketOptionTimeout result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.SocketOptionTimeout buildPartial() {
+      io.grpc.channelz.v1.SocketOptionTimeout result = new io.grpc.channelz.v1.SocketOptionTimeout(this);
+      if (durationBuilder_ == null) {
+        result.duration_ = duration_;
+      } else {
+        result.duration_ = durationBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.SocketOptionTimeout) {
+        return mergeFrom((io.grpc.channelz.v1.SocketOptionTimeout)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.SocketOptionTimeout other) {
+      if (other == io.grpc.channelz.v1.SocketOptionTimeout.getDefaultInstance()) return this;
+      if (other.hasDuration()) {
+        mergeDuration(other.getDuration());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.SocketOptionTimeout parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.SocketOptionTimeout) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private com.google.protobuf.Duration duration_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> durationBuilder_;
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public boolean hasDuration() {
+      return durationBuilder_ != null || duration_ != null;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public com.google.protobuf.Duration getDuration() {
+      if (durationBuilder_ == null) {
+        return duration_ == null ? com.google.protobuf.Duration.getDefaultInstance() : duration_;
+      } else {
+        return durationBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public Builder setDuration(com.google.protobuf.Duration value) {
+      if (durationBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        duration_ = value;
+        onChanged();
+      } else {
+        durationBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public Builder setDuration(
+        com.google.protobuf.Duration.Builder builderForValue) {
+      if (durationBuilder_ == null) {
+        duration_ = builderForValue.build();
+        onChanged();
+      } else {
+        durationBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public Builder mergeDuration(com.google.protobuf.Duration value) {
+      if (durationBuilder_ == null) {
+        if (duration_ != null) {
+          duration_ =
+            com.google.protobuf.Duration.newBuilder(duration_).mergeFrom(value).buildPartial();
+        } else {
+          duration_ = value;
+        }
+        onChanged();
+      } else {
+        durationBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public Builder clearDuration() {
+      if (durationBuilder_ == null) {
+        duration_ = null;
+        onChanged();
+      } else {
+        duration_ = null;
+        durationBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public com.google.protobuf.Duration.Builder getDurationBuilder() {
+      
+      onChanged();
+      return getDurationFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    public com.google.protobuf.DurationOrBuilder getDurationOrBuilder() {
+      if (durationBuilder_ != null) {
+        return durationBuilder_.getMessageOrBuilder();
+      } else {
+        return duration_ == null ?
+            com.google.protobuf.Duration.getDefaultInstance() : duration_;
+      }
+    }
+    /**
+     * <code>.google.protobuf.Duration duration = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> 
+        getDurationFieldBuilder() {
+      if (durationBuilder_ == null) {
+        durationBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder>(
+                getDuration(),
+                getParentForChildren(),
+                isClean());
+        duration_ = null;
+      }
+      return durationBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.SocketOptionTimeout)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.SocketOptionTimeout)
+  private static final io.grpc.channelz.v1.SocketOptionTimeout DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.SocketOptionTimeout();
+  }
+
+  public static io.grpc.channelz.v1.SocketOptionTimeout getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<SocketOptionTimeout>
+      PARSER = new com.google.protobuf.AbstractParser<SocketOptionTimeout>() {
+    public SocketOptionTimeout parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new SocketOptionTimeout(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<SocketOptionTimeout> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<SocketOptionTimeout> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.SocketOptionTimeout getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTimeoutOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTimeoutOrBuilder.java
new file mode 100644
index 0000000..385b0df
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOptionTimeoutOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SocketOptionTimeoutOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.SocketOptionTimeout)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.google.protobuf.Duration duration = 1;</code>
+   */
+  boolean hasDuration();
+  /**
+   * <code>.google.protobuf.Duration duration = 1;</code>
+   */
+  com.google.protobuf.Duration getDuration();
+  /**
+   * <code>.google.protobuf.Duration duration = 1;</code>
+   */
+  com.google.protobuf.DurationOrBuilder getDurationOrBuilder();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOrBuilder.java
new file mode 100644
index 0000000..dd47715
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketOrBuilder.java
@@ -0,0 +1,118 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SocketOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.Socket)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.grpc.channelz.SocketRef ref = 1;</code>
+   */
+  boolean hasRef();
+  /**
+   * <code>.grpc.channelz.SocketRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.SocketRef getRef();
+  /**
+   * <code>.grpc.channelz.SocketRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.SocketRefOrBuilder getRefOrBuilder();
+
+  /**
+   * <code>.grpc.channelz.SocketData data = 2;</code>
+   */
+  boolean hasData();
+  /**
+   * <code>.grpc.channelz.SocketData data = 2;</code>
+   */
+  io.grpc.channelz.v1.SocketData getData();
+  /**
+   * <code>.grpc.channelz.SocketData data = 2;</code>
+   */
+  io.grpc.channelz.v1.SocketDataOrBuilder getDataOrBuilder();
+
+  /**
+   * <pre>
+   * The locally bound address.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address local = 3;</code>
+   */
+  boolean hasLocal();
+  /**
+   * <pre>
+   * The locally bound address.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address local = 3;</code>
+   */
+  io.grpc.channelz.v1.Address getLocal();
+  /**
+   * <pre>
+   * The locally bound address.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address local = 3;</code>
+   */
+  io.grpc.channelz.v1.AddressOrBuilder getLocalOrBuilder();
+
+  /**
+   * <pre>
+   * The remote bound address.  May be absent.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address remote = 4;</code>
+   */
+  boolean hasRemote();
+  /**
+   * <pre>
+   * The remote bound address.  May be absent.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address remote = 4;</code>
+   */
+  io.grpc.channelz.v1.Address getRemote();
+  /**
+   * <pre>
+   * The remote bound address.  May be absent.
+   * </pre>
+   *
+   * <code>.grpc.channelz.Address remote = 4;</code>
+   */
+  io.grpc.channelz.v1.AddressOrBuilder getRemoteOrBuilder();
+
+  /**
+   * <code>.grpc.channelz.Security security = 5;</code>
+   */
+  boolean hasSecurity();
+  /**
+   * <code>.grpc.channelz.Security security = 5;</code>
+   */
+  io.grpc.channelz.v1.Security getSecurity();
+  /**
+   * <code>.grpc.channelz.Security security = 5;</code>
+   */
+  io.grpc.channelz.v1.SecurityOrBuilder getSecurityOrBuilder();
+
+  /**
+   * <pre>
+   * Optional, represents the name of the remote endpoint, if different than
+   * the original target name.
+   * </pre>
+   *
+   * <code>string remote_name = 6;</code>
+   */
+  java.lang.String getRemoteName();
+  /**
+   * <pre>
+   * Optional, represents the name of the remote endpoint, if different than
+   * the original target name.
+   * </pre>
+   *
+   * <code>string remote_name = 6;</code>
+   */
+  com.google.protobuf.ByteString
+      getRemoteNameBytes();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketRef.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketRef.java
new file mode 100644
index 0000000..7515af0
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketRef.java
@@ -0,0 +1,603 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.SocketRef}
+ */
+public  final class SocketRef extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.SocketRef)
+    SocketRefOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use SocketRef.newBuilder() to construct.
+  private SocketRef(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private SocketRef() {
+    socketId_ = 0L;
+    name_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private SocketRef(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 24: {
+
+            socketId_ = input.readInt64();
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketRef_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketRef_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.SocketRef.class, io.grpc.channelz.v1.SocketRef.Builder.class);
+  }
+
+  public static final int SOCKET_ID_FIELD_NUMBER = 3;
+  private long socketId_;
+  /**
+   * <code>int64 socket_id = 3;</code>
+   */
+  public long getSocketId() {
+    return socketId_;
+  }
+
+  public static final int NAME_FIELD_NUMBER = 4;
+  private volatile java.lang.Object name_;
+  /**
+   * <pre>
+   * An optional name associated with the socket.
+   * </pre>
+   *
+   * <code>string name = 4;</code>
+   */
+  public java.lang.String getName() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * An optional name associated with the socket.
+   * </pre>
+   *
+   * <code>string name = 4;</code>
+   */
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (socketId_ != 0L) {
+      output.writeInt64(3, socketId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, name_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (socketId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(3, socketId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, name_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.SocketRef)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.SocketRef other = (io.grpc.channelz.v1.SocketRef) obj;
+
+    boolean result = true;
+    result = result && (getSocketId()
+        == other.getSocketId());
+    result = result && getName()
+        .equals(other.getName());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + SOCKET_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getSocketId());
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SocketRef parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.SocketRef prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.SocketRef}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.SocketRef)
+      io.grpc.channelz.v1.SocketRefOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketRef_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketRef_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.SocketRef.class, io.grpc.channelz.v1.SocketRef.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.SocketRef.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      socketId_ = 0L;
+
+      name_ = "";
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SocketRef_descriptor;
+    }
+
+    public io.grpc.channelz.v1.SocketRef getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.SocketRef.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.SocketRef build() {
+      io.grpc.channelz.v1.SocketRef result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.SocketRef buildPartial() {
+      io.grpc.channelz.v1.SocketRef result = new io.grpc.channelz.v1.SocketRef(this);
+      result.socketId_ = socketId_;
+      result.name_ = name_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.SocketRef) {
+        return mergeFrom((io.grpc.channelz.v1.SocketRef)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.SocketRef other) {
+      if (other == io.grpc.channelz.v1.SocketRef.getDefaultInstance()) return this;
+      if (other.getSocketId() != 0L) {
+        setSocketId(other.getSocketId());
+      }
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.SocketRef parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.SocketRef) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long socketId_ ;
+    /**
+     * <code>int64 socket_id = 3;</code>
+     */
+    public long getSocketId() {
+      return socketId_;
+    }
+    /**
+     * <code>int64 socket_id = 3;</code>
+     */
+    public Builder setSocketId(long value) {
+      
+      socketId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 socket_id = 3;</code>
+     */
+    public Builder clearSocketId() {
+      
+      socketId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object name_ = "";
+    /**
+     * <pre>
+     * An optional name associated with the socket.
+     * </pre>
+     *
+     * <code>string name = 4;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the socket.
+     * </pre>
+     *
+     * <code>string name = 4;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the socket.
+     * </pre>
+     *
+     * <code>string name = 4;</code>
+     */
+    public Builder setName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the socket.
+     * </pre>
+     *
+     * <code>string name = 4;</code>
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the socket.
+     * </pre>
+     *
+     * <code>string name = 4;</code>
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.SocketRef)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.SocketRef)
+  private static final io.grpc.channelz.v1.SocketRef DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.SocketRef();
+  }
+
+  public static io.grpc.channelz.v1.SocketRef getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<SocketRef>
+      PARSER = new com.google.protobuf.AbstractParser<SocketRef>() {
+    public SocketRef parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new SocketRef(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<SocketRef> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<SocketRef> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.SocketRef getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SocketRefOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SocketRefOrBuilder.java
new file mode 100644
index 0000000..77f1542
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SocketRefOrBuilder.java
@@ -0,0 +1,32 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SocketRefOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.SocketRef)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 socket_id = 3;</code>
+   */
+  long getSocketId();
+
+  /**
+   * <pre>
+   * An optional name associated with the socket.
+   * </pre>
+   *
+   * <code>string name = 4;</code>
+   */
+  java.lang.String getName();
+  /**
+   * <pre>
+   * An optional name associated with the socket.
+   * </pre>
+   *
+   * <code>string name = 4;</code>
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/Subchannel.java b/services/src/generated/main/java/io/grpc/channelz/v1/Subchannel.java
new file mode 100644
index 0000000..0f589c1
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/Subchannel.java
@@ -0,0 +1,2282 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * <pre>
+ * Subchannel is a logical grouping of channels, subchannels, and sockets.
+ * A subchannel is load balanced over by it's ancestor
+ * </pre>
+ *
+ * Protobuf type {@code grpc.channelz.Subchannel}
+ */
+public  final class Subchannel extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.Subchannel)
+    SubchannelOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use Subchannel.newBuilder() to construct.
+  private Subchannel(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private Subchannel() {
+    channelRef_ = java.util.Collections.emptyList();
+    subchannelRef_ = java.util.Collections.emptyList();
+    socket_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private Subchannel(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 10: {
+            io.grpc.channelz.v1.SubchannelRef.Builder subBuilder = null;
+            if (ref_ != null) {
+              subBuilder = ref_.toBuilder();
+            }
+            ref_ = input.readMessage(io.grpc.channelz.v1.SubchannelRef.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(ref_);
+              ref_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            io.grpc.channelz.v1.ChannelData.Builder subBuilder = null;
+            if (data_ != null) {
+              subBuilder = data_.toBuilder();
+            }
+            data_ = input.readMessage(io.grpc.channelz.v1.ChannelData.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(data_);
+              data_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 26: {
+            if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+              channelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.ChannelRef>();
+              mutable_bitField0_ |= 0x00000004;
+            }
+            channelRef_.add(
+                input.readMessage(io.grpc.channelz.v1.ChannelRef.parser(), extensionRegistry));
+            break;
+          }
+          case 34: {
+            if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+              subchannelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.SubchannelRef>();
+              mutable_bitField0_ |= 0x00000008;
+            }
+            subchannelRef_.add(
+                input.readMessage(io.grpc.channelz.v1.SubchannelRef.parser(), extensionRegistry));
+            break;
+          }
+          case 42: {
+            if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+              socket_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>();
+              mutable_bitField0_ |= 0x00000010;
+            }
+            socket_.add(
+                input.readMessage(io.grpc.channelz.v1.SocketRef.parser(), extensionRegistry));
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+        channelRef_ = java.util.Collections.unmodifiableList(channelRef_);
+      }
+      if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
+        subchannelRef_ = java.util.Collections.unmodifiableList(subchannelRef_);
+      }
+      if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
+        socket_ = java.util.Collections.unmodifiableList(socket_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Subchannel_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Subchannel_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.Subchannel.class, io.grpc.channelz.v1.Subchannel.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int REF_FIELD_NUMBER = 1;
+  private io.grpc.channelz.v1.SubchannelRef ref_;
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+   */
+  public boolean hasRef() {
+    return ref_ != null;
+  }
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.SubchannelRef getRef() {
+    return ref_ == null ? io.grpc.channelz.v1.SubchannelRef.getDefaultInstance() : ref_;
+  }
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+   */
+  public io.grpc.channelz.v1.SubchannelRefOrBuilder getRefOrBuilder() {
+    return getRef();
+  }
+
+  public static final int DATA_FIELD_NUMBER = 2;
+  private io.grpc.channelz.v1.ChannelData data_;
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  public boolean hasData() {
+    return data_ != null;
+  }
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.ChannelData getData() {
+    return data_ == null ? io.grpc.channelz.v1.ChannelData.getDefaultInstance() : data_;
+  }
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  public io.grpc.channelz.v1.ChannelDataOrBuilder getDataOrBuilder() {
+    return getData();
+  }
+
+  public static final int CHANNEL_REF_FIELD_NUMBER = 3;
+  private java.util.List<io.grpc.channelz.v1.ChannelRef> channelRef_;
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.ChannelRef> getChannelRefList() {
+    return channelRef_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.ChannelRefOrBuilder> 
+      getChannelRefOrBuilderList() {
+    return channelRef_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public int getChannelRefCount() {
+    return channelRef_.size();
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public io.grpc.channelz.v1.ChannelRef getChannelRef(int index) {
+    return channelRef_.get(index);
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  public io.grpc.channelz.v1.ChannelRefOrBuilder getChannelRefOrBuilder(
+      int index) {
+    return channelRef_.get(index);
+  }
+
+  public static final int SUBCHANNEL_REF_FIELD_NUMBER = 4;
+  private java.util.List<io.grpc.channelz.v1.SubchannelRef> subchannelRef_;
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.SubchannelRef> getSubchannelRefList() {
+    return subchannelRef_;
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+      getSubchannelRefOrBuilderList() {
+    return subchannelRef_;
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public int getSubchannelRefCount() {
+    return subchannelRef_.size();
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public io.grpc.channelz.v1.SubchannelRef getSubchannelRef(int index) {
+    return subchannelRef_.get(index);
+  }
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  public io.grpc.channelz.v1.SubchannelRefOrBuilder getSubchannelRefOrBuilder(
+      int index) {
+    return subchannelRef_.get(index);
+  }
+
+  public static final int SOCKET_FIELD_NUMBER = 5;
+  private java.util.List<io.grpc.channelz.v1.SocketRef> socket_;
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public java.util.List<io.grpc.channelz.v1.SocketRef> getSocketList() {
+    return socket_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getSocketOrBuilderList() {
+    return socket_;
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public int getSocketCount() {
+    return socket_.size();
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public io.grpc.channelz.v1.SocketRef getSocket(int index) {
+    return socket_.get(index);
+  }
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  public io.grpc.channelz.v1.SocketRefOrBuilder getSocketOrBuilder(
+      int index) {
+    return socket_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (ref_ != null) {
+      output.writeMessage(1, getRef());
+    }
+    if (data_ != null) {
+      output.writeMessage(2, getData());
+    }
+    for (int i = 0; i < channelRef_.size(); i++) {
+      output.writeMessage(3, channelRef_.get(i));
+    }
+    for (int i = 0; i < subchannelRef_.size(); i++) {
+      output.writeMessage(4, subchannelRef_.get(i));
+    }
+    for (int i = 0; i < socket_.size(); i++) {
+      output.writeMessage(5, socket_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (ref_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getRef());
+    }
+    if (data_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, getData());
+    }
+    for (int i = 0; i < channelRef_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, channelRef_.get(i));
+    }
+    for (int i = 0; i < subchannelRef_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(4, subchannelRef_.get(i));
+    }
+    for (int i = 0; i < socket_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(5, socket_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.Subchannel)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.Subchannel other = (io.grpc.channelz.v1.Subchannel) obj;
+
+    boolean result = true;
+    result = result && (hasRef() == other.hasRef());
+    if (hasRef()) {
+      result = result && getRef()
+          .equals(other.getRef());
+    }
+    result = result && (hasData() == other.hasData());
+    if (hasData()) {
+      result = result && getData()
+          .equals(other.getData());
+    }
+    result = result && getChannelRefList()
+        .equals(other.getChannelRefList());
+    result = result && getSubchannelRefList()
+        .equals(other.getSubchannelRefList());
+    result = result && getSocketList()
+        .equals(other.getSocketList());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasRef()) {
+      hash = (37 * hash) + REF_FIELD_NUMBER;
+      hash = (53 * hash) + getRef().hashCode();
+    }
+    if (hasData()) {
+      hash = (37 * hash) + DATA_FIELD_NUMBER;
+      hash = (53 * hash) + getData().hashCode();
+    }
+    if (getChannelRefCount() > 0) {
+      hash = (37 * hash) + CHANNEL_REF_FIELD_NUMBER;
+      hash = (53 * hash) + getChannelRefList().hashCode();
+    }
+    if (getSubchannelRefCount() > 0) {
+      hash = (37 * hash) + SUBCHANNEL_REF_FIELD_NUMBER;
+      hash = (53 * hash) + getSubchannelRefList().hashCode();
+    }
+    if (getSocketCount() > 0) {
+      hash = (37 * hash) + SOCKET_FIELD_NUMBER;
+      hash = (53 * hash) + getSocketList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.Subchannel parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.Subchannel prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * Subchannel is a logical grouping of channels, subchannels, and sockets.
+   * A subchannel is load balanced over by it's ancestor
+   * </pre>
+   *
+   * Protobuf type {@code grpc.channelz.Subchannel}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.Subchannel)
+      io.grpc.channelz.v1.SubchannelOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Subchannel_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Subchannel_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.Subchannel.class, io.grpc.channelz.v1.Subchannel.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.Subchannel.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getChannelRefFieldBuilder();
+        getSubchannelRefFieldBuilder();
+        getSocketFieldBuilder();
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      if (refBuilder_ == null) {
+        ref_ = null;
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+      if (dataBuilder_ == null) {
+        data_ = null;
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+      if (channelRefBuilder_ == null) {
+        channelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+      } else {
+        channelRefBuilder_.clear();
+      }
+      if (subchannelRefBuilder_ == null) {
+        subchannelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000008);
+      } else {
+        subchannelRefBuilder_.clear();
+      }
+      if (socketBuilder_ == null) {
+        socket_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000010);
+      } else {
+        socketBuilder_.clear();
+      }
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_Subchannel_descriptor;
+    }
+
+    public io.grpc.channelz.v1.Subchannel getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.Subchannel.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.Subchannel build() {
+      io.grpc.channelz.v1.Subchannel result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.Subchannel buildPartial() {
+      io.grpc.channelz.v1.Subchannel result = new io.grpc.channelz.v1.Subchannel(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (refBuilder_ == null) {
+        result.ref_ = ref_;
+      } else {
+        result.ref_ = refBuilder_.build();
+      }
+      if (dataBuilder_ == null) {
+        result.data_ = data_;
+      } else {
+        result.data_ = dataBuilder_.build();
+      }
+      if (channelRefBuilder_ == null) {
+        if (((bitField0_ & 0x00000004) == 0x00000004)) {
+          channelRef_ = java.util.Collections.unmodifiableList(channelRef_);
+          bitField0_ = (bitField0_ & ~0x00000004);
+        }
+        result.channelRef_ = channelRef_;
+      } else {
+        result.channelRef_ = channelRefBuilder_.build();
+      }
+      if (subchannelRefBuilder_ == null) {
+        if (((bitField0_ & 0x00000008) == 0x00000008)) {
+          subchannelRef_ = java.util.Collections.unmodifiableList(subchannelRef_);
+          bitField0_ = (bitField0_ & ~0x00000008);
+        }
+        result.subchannelRef_ = subchannelRef_;
+      } else {
+        result.subchannelRef_ = subchannelRefBuilder_.build();
+      }
+      if (socketBuilder_ == null) {
+        if (((bitField0_ & 0x00000010) == 0x00000010)) {
+          socket_ = java.util.Collections.unmodifiableList(socket_);
+          bitField0_ = (bitField0_ & ~0x00000010);
+        }
+        result.socket_ = socket_;
+      } else {
+        result.socket_ = socketBuilder_.build();
+      }
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.Subchannel) {
+        return mergeFrom((io.grpc.channelz.v1.Subchannel)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.Subchannel other) {
+      if (other == io.grpc.channelz.v1.Subchannel.getDefaultInstance()) return this;
+      if (other.hasRef()) {
+        mergeRef(other.getRef());
+      }
+      if (other.hasData()) {
+        mergeData(other.getData());
+      }
+      if (channelRefBuilder_ == null) {
+        if (!other.channelRef_.isEmpty()) {
+          if (channelRef_.isEmpty()) {
+            channelRef_ = other.channelRef_;
+            bitField0_ = (bitField0_ & ~0x00000004);
+          } else {
+            ensureChannelRefIsMutable();
+            channelRef_.addAll(other.channelRef_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.channelRef_.isEmpty()) {
+          if (channelRefBuilder_.isEmpty()) {
+            channelRefBuilder_.dispose();
+            channelRefBuilder_ = null;
+            channelRef_ = other.channelRef_;
+            bitField0_ = (bitField0_ & ~0x00000004);
+            channelRefBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getChannelRefFieldBuilder() : null;
+          } else {
+            channelRefBuilder_.addAllMessages(other.channelRef_);
+          }
+        }
+      }
+      if (subchannelRefBuilder_ == null) {
+        if (!other.subchannelRef_.isEmpty()) {
+          if (subchannelRef_.isEmpty()) {
+            subchannelRef_ = other.subchannelRef_;
+            bitField0_ = (bitField0_ & ~0x00000008);
+          } else {
+            ensureSubchannelRefIsMutable();
+            subchannelRef_.addAll(other.subchannelRef_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.subchannelRef_.isEmpty()) {
+          if (subchannelRefBuilder_.isEmpty()) {
+            subchannelRefBuilder_.dispose();
+            subchannelRefBuilder_ = null;
+            subchannelRef_ = other.subchannelRef_;
+            bitField0_ = (bitField0_ & ~0x00000008);
+            subchannelRefBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getSubchannelRefFieldBuilder() : null;
+          } else {
+            subchannelRefBuilder_.addAllMessages(other.subchannelRef_);
+          }
+        }
+      }
+      if (socketBuilder_ == null) {
+        if (!other.socket_.isEmpty()) {
+          if (socket_.isEmpty()) {
+            socket_ = other.socket_;
+            bitField0_ = (bitField0_ & ~0x00000010);
+          } else {
+            ensureSocketIsMutable();
+            socket_.addAll(other.socket_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.socket_.isEmpty()) {
+          if (socketBuilder_.isEmpty()) {
+            socketBuilder_.dispose();
+            socketBuilder_ = null;
+            socket_ = other.socket_;
+            bitField0_ = (bitField0_ & ~0x00000010);
+            socketBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getSocketFieldBuilder() : null;
+          } else {
+            socketBuilder_.addAllMessages(other.socket_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.Subchannel parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.Subchannel) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private io.grpc.channelz.v1.SubchannelRef ref_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder> refBuilder_;
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public boolean hasRef() {
+      return refBuilder_ != null || ref_ != null;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef getRef() {
+      if (refBuilder_ == null) {
+        return ref_ == null ? io.grpc.channelz.v1.SubchannelRef.getDefaultInstance() : ref_;
+      } else {
+        return refBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public Builder setRef(io.grpc.channelz.v1.SubchannelRef value) {
+      if (refBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ref_ = value;
+        onChanged();
+      } else {
+        refBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public Builder setRef(
+        io.grpc.channelz.v1.SubchannelRef.Builder builderForValue) {
+      if (refBuilder_ == null) {
+        ref_ = builderForValue.build();
+        onChanged();
+      } else {
+        refBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public Builder mergeRef(io.grpc.channelz.v1.SubchannelRef value) {
+      if (refBuilder_ == null) {
+        if (ref_ != null) {
+          ref_ =
+            io.grpc.channelz.v1.SubchannelRef.newBuilder(ref_).mergeFrom(value).buildPartial();
+        } else {
+          ref_ = value;
+        }
+        onChanged();
+      } else {
+        refBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public Builder clearRef() {
+      if (refBuilder_ == null) {
+        ref_ = null;
+        onChanged();
+      } else {
+        ref_ = null;
+        refBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef.Builder getRefBuilder() {
+      
+      onChanged();
+      return getRefFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRefOrBuilder getRefOrBuilder() {
+      if (refBuilder_ != null) {
+        return refBuilder_.getMessageOrBuilder();
+      } else {
+        return ref_ == null ?
+            io.grpc.channelz.v1.SubchannelRef.getDefaultInstance() : ref_;
+      }
+    }
+    /**
+     * <pre>
+     * The identifier for this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+        getRefFieldBuilder() {
+      if (refBuilder_ == null) {
+        refBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder>(
+                getRef(),
+                getParentForChildren(),
+                isClean());
+        ref_ = null;
+      }
+      return refBuilder_;
+    }
+
+    private io.grpc.channelz.v1.ChannelData data_ = null;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelData, io.grpc.channelz.v1.ChannelData.Builder, io.grpc.channelz.v1.ChannelDataOrBuilder> dataBuilder_;
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public boolean hasData() {
+      return dataBuilder_ != null || data_ != null;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ChannelData getData() {
+      if (dataBuilder_ == null) {
+        return data_ == null ? io.grpc.channelz.v1.ChannelData.getDefaultInstance() : data_;
+      } else {
+        return dataBuilder_.getMessage();
+      }
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder setData(io.grpc.channelz.v1.ChannelData value) {
+      if (dataBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        data_ = value;
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder setData(
+        io.grpc.channelz.v1.ChannelData.Builder builderForValue) {
+      if (dataBuilder_ == null) {
+        data_ = builderForValue.build();
+        onChanged();
+      } else {
+        dataBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder mergeData(io.grpc.channelz.v1.ChannelData value) {
+      if (dataBuilder_ == null) {
+        if (data_ != null) {
+          data_ =
+            io.grpc.channelz.v1.ChannelData.newBuilder(data_).mergeFrom(value).buildPartial();
+        } else {
+          data_ = value;
+        }
+        onChanged();
+      } else {
+        dataBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public Builder clearData() {
+      if (dataBuilder_ == null) {
+        data_ = null;
+        onChanged();
+      } else {
+        data_ = null;
+        dataBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ChannelData.Builder getDataBuilder() {
+      
+      onChanged();
+      return getDataFieldBuilder().getBuilder();
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    public io.grpc.channelz.v1.ChannelDataOrBuilder getDataOrBuilder() {
+      if (dataBuilder_ != null) {
+        return dataBuilder_.getMessageOrBuilder();
+      } else {
+        return data_ == null ?
+            io.grpc.channelz.v1.ChannelData.getDefaultInstance() : data_;
+      }
+    }
+    /**
+     * <pre>
+     * Data specific to this channel.
+     * </pre>
+     *
+     * <code>.grpc.channelz.ChannelData data = 2;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelData, io.grpc.channelz.v1.ChannelData.Builder, io.grpc.channelz.v1.ChannelDataOrBuilder> 
+        getDataFieldBuilder() {
+      if (dataBuilder_ == null) {
+        dataBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.grpc.channelz.v1.ChannelData, io.grpc.channelz.v1.ChannelData.Builder, io.grpc.channelz.v1.ChannelDataOrBuilder>(
+                getData(),
+                getParentForChildren(),
+                isClean());
+        data_ = null;
+      }
+      return dataBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.ChannelRef> channelRef_ =
+      java.util.Collections.emptyList();
+    private void ensureChannelRefIsMutable() {
+      if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+        channelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.ChannelRef>(channelRef_);
+        bitField0_ |= 0x00000004;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder> channelRefBuilder_;
+
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.ChannelRef> getChannelRefList() {
+      if (channelRefBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(channelRef_);
+      } else {
+        return channelRefBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public int getChannelRefCount() {
+      if (channelRefBuilder_ == null) {
+        return channelRef_.size();
+      } else {
+        return channelRefBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef getChannelRef(int index) {
+      if (channelRefBuilder_ == null) {
+        return channelRef_.get(index);
+      } else {
+        return channelRefBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder setChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef value) {
+      if (channelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelRefIsMutable();
+        channelRef_.set(index, value);
+        onChanged();
+      } else {
+        channelRefBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder setChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef.Builder builderForValue) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        channelRefBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(io.grpc.channelz.v1.ChannelRef value) {
+      if (channelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelRefIsMutable();
+        channelRef_.add(value);
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef value) {
+      if (channelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureChannelRefIsMutable();
+        channelRef_.add(index, value);
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(
+        io.grpc.channelz.v1.ChannelRef.Builder builderForValue) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.add(builderForValue.build());
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addChannelRef(
+        int index, io.grpc.channelz.v1.ChannelRef.Builder builderForValue) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        channelRefBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder addAllChannelRef(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.ChannelRef> values) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, channelRef_);
+        onChanged();
+      } else {
+        channelRefBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder clearChannelRef() {
+      if (channelRefBuilder_ == null) {
+        channelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000004);
+        onChanged();
+      } else {
+        channelRefBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public Builder removeChannelRef(int index) {
+      if (channelRefBuilder_ == null) {
+        ensureChannelRefIsMutable();
+        channelRef_.remove(index);
+        onChanged();
+      } else {
+        channelRefBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef.Builder getChannelRefBuilder(
+        int index) {
+      return getChannelRefFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRefOrBuilder getChannelRefOrBuilder(
+        int index) {
+      if (channelRefBuilder_ == null) {
+        return channelRef_.get(index);  } else {
+        return channelRefBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.ChannelRefOrBuilder> 
+         getChannelRefOrBuilderList() {
+      if (channelRefBuilder_ != null) {
+        return channelRefBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(channelRef_);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef.Builder addChannelRefBuilder() {
+      return getChannelRefFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.ChannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public io.grpc.channelz.v1.ChannelRef.Builder addChannelRefBuilder(
+        int index) {
+      return getChannelRefFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.ChannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of channel refs.
+     * There may not be cycles in the ref graph.
+     * A channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.ChannelRef.Builder> 
+         getChannelRefBuilderList() {
+      return getChannelRefFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder> 
+        getChannelRefFieldBuilder() {
+      if (channelRefBuilder_ == null) {
+        channelRefBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.ChannelRef, io.grpc.channelz.v1.ChannelRef.Builder, io.grpc.channelz.v1.ChannelRefOrBuilder>(
+                channelRef_,
+                ((bitField0_ & 0x00000004) == 0x00000004),
+                getParentForChildren(),
+                isClean());
+        channelRef_ = null;
+      }
+      return channelRefBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.SubchannelRef> subchannelRef_ =
+      java.util.Collections.emptyList();
+    private void ensureSubchannelRefIsMutable() {
+      if (!((bitField0_ & 0x00000008) == 0x00000008)) {
+        subchannelRef_ = new java.util.ArrayList<io.grpc.channelz.v1.SubchannelRef>(subchannelRef_);
+        bitField0_ |= 0x00000008;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder> subchannelRefBuilder_;
+
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SubchannelRef> getSubchannelRefList() {
+      if (subchannelRefBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(subchannelRef_);
+      } else {
+        return subchannelRefBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public int getSubchannelRefCount() {
+      if (subchannelRefBuilder_ == null) {
+        return subchannelRef_.size();
+      } else {
+        return subchannelRefBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef getSubchannelRef(int index) {
+      if (subchannelRefBuilder_ == null) {
+        return subchannelRef_.get(index);
+      } else {
+        return subchannelRefBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder setSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef value) {
+      if (subchannelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.set(index, value);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder setSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef.Builder builderForValue) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        subchannelRefBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(io.grpc.channelz.v1.SubchannelRef value) {
+      if (subchannelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(value);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef value) {
+      if (subchannelRefBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(index, value);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(
+        io.grpc.channelz.v1.SubchannelRef.Builder builderForValue) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(builderForValue.build());
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addSubchannelRef(
+        int index, io.grpc.channelz.v1.SubchannelRef.Builder builderForValue) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder addAllSubchannelRef(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.SubchannelRef> values) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, subchannelRef_);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder clearSubchannelRef() {
+      if (subchannelRefBuilder_ == null) {
+        subchannelRef_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000008);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public Builder removeSubchannelRef(int index) {
+      if (subchannelRefBuilder_ == null) {
+        ensureSubchannelRefIsMutable();
+        subchannelRef_.remove(index);
+        onChanged();
+      } else {
+        subchannelRefBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef.Builder getSubchannelRefBuilder(
+        int index) {
+      return getSubchannelRefFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRefOrBuilder getSubchannelRefOrBuilder(
+        int index) {
+      if (subchannelRefBuilder_ == null) {
+        return subchannelRef_.get(index);  } else {
+        return subchannelRefBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+         getSubchannelRefOrBuilderList() {
+      if (subchannelRefBuilder_ != null) {
+        return subchannelRefBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(subchannelRef_);
+      }
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef.Builder addSubchannelRefBuilder() {
+      return getSubchannelRefFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.SubchannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public io.grpc.channelz.v1.SubchannelRef.Builder addSubchannelRefBuilder(
+        int index) {
+      return getSubchannelRefFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.SubchannelRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+     * There are no ordering guarantees on the order of subchannel refs.
+     * There may not be cycles in the ref graph.
+     * A sub channel ref may be present in more than one channel or subchannel.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SubchannelRef.Builder> 
+         getSubchannelRefBuilderList() {
+      return getSubchannelRefFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+        getSubchannelRefFieldBuilder() {
+      if (subchannelRefBuilder_ == null) {
+        subchannelRefBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.SubchannelRef, io.grpc.channelz.v1.SubchannelRef.Builder, io.grpc.channelz.v1.SubchannelRefOrBuilder>(
+                subchannelRef_,
+                ((bitField0_ & 0x00000008) == 0x00000008),
+                getParentForChildren(),
+                isClean());
+        subchannelRef_ = null;
+      }
+      return subchannelRefBuilder_;
+    }
+
+    private java.util.List<io.grpc.channelz.v1.SocketRef> socket_ =
+      java.util.Collections.emptyList();
+    private void ensureSocketIsMutable() {
+      if (!((bitField0_ & 0x00000010) == 0x00000010)) {
+        socket_ = new java.util.ArrayList<io.grpc.channelz.v1.SocketRef>(socket_);
+        bitField0_ |= 0x00000010;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> socketBuilder_;
+
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef> getSocketList() {
+      if (socketBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(socket_);
+      } else {
+        return socketBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public int getSocketCount() {
+      if (socketBuilder_ == null) {
+        return socket_.size();
+      } else {
+        return socketBuilder_.getCount();
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef getSocket(int index) {
+      if (socketBuilder_ == null) {
+        return socket_.get(index);
+      } else {
+        return socketBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder setSocket(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (socketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketIsMutable();
+        socket_.set(index, value);
+        onChanged();
+      } else {
+        socketBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder setSocket(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        socketBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(io.grpc.channelz.v1.SocketRef value) {
+      if (socketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketIsMutable();
+        socket_.add(value);
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(
+        int index, io.grpc.channelz.v1.SocketRef value) {
+      if (socketBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureSocketIsMutable();
+        socket_.add(index, value);
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(
+        io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.add(builderForValue.build());
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addSocket(
+        int index, io.grpc.channelz.v1.SocketRef.Builder builderForValue) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        socketBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder addAllSocket(
+        java.lang.Iterable<? extends io.grpc.channelz.v1.SocketRef> values) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, socket_);
+        onChanged();
+      } else {
+        socketBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder clearSocket() {
+      if (socketBuilder_ == null) {
+        socket_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000010);
+        onChanged();
+      } else {
+        socketBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public Builder removeSocket(int index) {
+      if (socketBuilder_ == null) {
+        ensureSocketIsMutable();
+        socket_.remove(index);
+        onChanged();
+      } else {
+        socketBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder getSocketBuilder(
+        int index) {
+      return getSocketFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRefOrBuilder getSocketOrBuilder(
+        int index) {
+      if (socketBuilder_ == null) {
+        return socket_.get(index);  } else {
+        return socketBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+         getSocketOrBuilderList() {
+      if (socketBuilder_ != null) {
+        return socketBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(socket_);
+      }
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addSocketBuilder() {
+      return getSocketFieldBuilder().addBuilder(
+          io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public io.grpc.channelz.v1.SocketRef.Builder addSocketBuilder(
+        int index) {
+      return getSocketFieldBuilder().addBuilder(
+          index, io.grpc.channelz.v1.SocketRef.getDefaultInstance());
+    }
+    /**
+     * <pre>
+     * There are no ordering guarantees on the order of sockets.
+     * </pre>
+     *
+     * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+     */
+    public java.util.List<io.grpc.channelz.v1.SocketRef.Builder> 
+         getSocketBuilderList() {
+      return getSocketFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder> 
+        getSocketFieldBuilder() {
+      if (socketBuilder_ == null) {
+        socketBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            io.grpc.channelz.v1.SocketRef, io.grpc.channelz.v1.SocketRef.Builder, io.grpc.channelz.v1.SocketRefOrBuilder>(
+                socket_,
+                ((bitField0_ & 0x00000010) == 0x00000010),
+                getParentForChildren(),
+                isClean());
+        socket_ = null;
+      }
+      return socketBuilder_;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.Subchannel)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.Subchannel)
+  private static final io.grpc.channelz.v1.Subchannel DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.Subchannel();
+  }
+
+  public static io.grpc.channelz.v1.Subchannel getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<Subchannel>
+      PARSER = new com.google.protobuf.AbstractParser<Subchannel>() {
+    public Subchannel parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new Subchannel(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<Subchannel> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<Subchannel> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.Subchannel getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelOrBuilder.java
new file mode 100644
index 0000000..7aaf083
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelOrBuilder.java
@@ -0,0 +1,216 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SubchannelOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.Subchannel)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+   */
+  boolean hasRef();
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.SubchannelRef getRef();
+  /**
+   * <pre>
+   * The identifier for this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.SubchannelRef ref = 1;</code>
+   */
+  io.grpc.channelz.v1.SubchannelRefOrBuilder getRefOrBuilder();
+
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  boolean hasData();
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  io.grpc.channelz.v1.ChannelData getData();
+  /**
+   * <pre>
+   * Data specific to this channel.
+   * </pre>
+   *
+   * <code>.grpc.channelz.ChannelData data = 2;</code>
+   */
+  io.grpc.channelz.v1.ChannelDataOrBuilder getDataOrBuilder();
+
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.ChannelRef> 
+      getChannelRefList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  io.grpc.channelz.v1.ChannelRef getChannelRef(int index);
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  int getChannelRefCount();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.ChannelRefOrBuilder> 
+      getChannelRefOrBuilderList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of channel refs.
+   * There may not be cycles in the ref graph.
+   * A channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.ChannelRef channel_ref = 3;</code>
+   */
+  io.grpc.channelz.v1.ChannelRefOrBuilder getChannelRefOrBuilder(
+      int index);
+
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.SubchannelRef> 
+      getSubchannelRefList();
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  io.grpc.channelz.v1.SubchannelRef getSubchannelRef(int index);
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  int getSubchannelRefCount();
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.SubchannelRefOrBuilder> 
+      getSubchannelRefOrBuilderList();
+  /**
+   * <pre>
+   * At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
+   * There are no ordering guarantees on the order of subchannel refs.
+   * There may not be cycles in the ref graph.
+   * A sub channel ref may be present in more than one channel or subchannel.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SubchannelRef subchannel_ref = 4;</code>
+   */
+  io.grpc.channelz.v1.SubchannelRefOrBuilder getSubchannelRefOrBuilder(
+      int index);
+
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  java.util.List<io.grpc.channelz.v1.SocketRef> 
+      getSocketList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  io.grpc.channelz.v1.SocketRef getSocket(int index);
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  int getSocketCount();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  java.util.List<? extends io.grpc.channelz.v1.SocketRefOrBuilder> 
+      getSocketOrBuilderList();
+  /**
+   * <pre>
+   * There are no ordering guarantees on the order of sockets.
+   * </pre>
+   *
+   * <code>repeated .grpc.channelz.SocketRef socket = 5;</code>
+   */
+  io.grpc.channelz.v1.SocketRefOrBuilder getSocketOrBuilder(
+      int index);
+}
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelRef.java b/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelRef.java
new file mode 100644
index 0000000..1154ffd
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelRef.java
@@ -0,0 +1,619 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+/**
+ * Protobuf type {@code grpc.channelz.SubchannelRef}
+ */
+public  final class SubchannelRef extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:grpc.channelz.SubchannelRef)
+    SubchannelRefOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use SubchannelRef.newBuilder() to construct.
+  private SubchannelRef(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private SubchannelRef() {
+    subchannelId_ = 0L;
+    name_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private SubchannelRef(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          default: {
+            if (!parseUnknownFieldProto3(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+          case 56: {
+
+            subchannelId_ = input.readInt64();
+            break;
+          }
+          case 66: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SubchannelRef_descriptor;
+  }
+
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SubchannelRef_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.grpc.channelz.v1.SubchannelRef.class, io.grpc.channelz.v1.SubchannelRef.Builder.class);
+  }
+
+  public static final int SUBCHANNEL_ID_FIELD_NUMBER = 7;
+  private long subchannelId_;
+  /**
+   * <pre>
+   * The globally unique id for this subchannel.  Must be a positive number.
+   * </pre>
+   *
+   * <code>int64 subchannel_id = 7;</code>
+   */
+  public long getSubchannelId() {
+    return subchannelId_;
+  }
+
+  public static final int NAME_FIELD_NUMBER = 8;
+  private volatile java.lang.Object name_;
+  /**
+   * <pre>
+   * An optional name associated with the subchannel.
+   * </pre>
+   *
+   * <code>string name = 8;</code>
+   */
+  public java.lang.String getName() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * An optional name associated with the subchannel.
+   * </pre>
+   *
+   * <code>string name = 8;</code>
+   */
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (subchannelId_ != 0L) {
+      output.writeInt64(7, subchannelId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 8, name_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (subchannelId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(7, subchannelId_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, name_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.grpc.channelz.v1.SubchannelRef)) {
+      return super.equals(obj);
+    }
+    io.grpc.channelz.v1.SubchannelRef other = (io.grpc.channelz.v1.SubchannelRef) obj;
+
+    boolean result = true;
+    result = result && (getSubchannelId()
+        == other.getSubchannelId());
+    result = result && getName()
+        .equals(other.getName());
+    result = result && unknownFields.equals(other.unknownFields);
+    return result;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + SUBCHANNEL_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getSubchannelId());
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.grpc.channelz.v1.SubchannelRef parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.grpc.channelz.v1.SubchannelRef prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code grpc.channelz.SubchannelRef}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:grpc.channelz.SubchannelRef)
+      io.grpc.channelz.v1.SubchannelRefOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SubchannelRef_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SubchannelRef_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.grpc.channelz.v1.SubchannelRef.class, io.grpc.channelz.v1.SubchannelRef.Builder.class);
+    }
+
+    // Construct using io.grpc.channelz.v1.SubchannelRef.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    public Builder clear() {
+      super.clear();
+      subchannelId_ = 0L;
+
+      name_ = "";
+
+      return this;
+    }
+
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.grpc.channelz.v1.ChannelzProto.internal_static_grpc_channelz_SubchannelRef_descriptor;
+    }
+
+    public io.grpc.channelz.v1.SubchannelRef getDefaultInstanceForType() {
+      return io.grpc.channelz.v1.SubchannelRef.getDefaultInstance();
+    }
+
+    public io.grpc.channelz.v1.SubchannelRef build() {
+      io.grpc.channelz.v1.SubchannelRef result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    public io.grpc.channelz.v1.SubchannelRef buildPartial() {
+      io.grpc.channelz.v1.SubchannelRef result = new io.grpc.channelz.v1.SubchannelRef(this);
+      result.subchannelId_ = subchannelId_;
+      result.name_ = name_;
+      onBuilt();
+      return result;
+    }
+
+    public Builder clone() {
+      return (Builder) super.clone();
+    }
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.setField(field, value);
+    }
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return (Builder) super.clearField(field);
+    }
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return (Builder) super.clearOneof(oneof);
+    }
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return (Builder) super.setRepeatedField(field, index, value);
+    }
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return (Builder) super.addRepeatedField(field, value);
+    }
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.grpc.channelz.v1.SubchannelRef) {
+        return mergeFrom((io.grpc.channelz.v1.SubchannelRef)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.grpc.channelz.v1.SubchannelRef other) {
+      if (other == io.grpc.channelz.v1.SubchannelRef.getDefaultInstance()) return this;
+      if (other.getSubchannelId() != 0L) {
+        setSubchannelId(other.getSubchannelId());
+      }
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.grpc.channelz.v1.SubchannelRef parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.grpc.channelz.v1.SubchannelRef) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long subchannelId_ ;
+    /**
+     * <pre>
+     * The globally unique id for this subchannel.  Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 subchannel_id = 7;</code>
+     */
+    public long getSubchannelId() {
+      return subchannelId_;
+    }
+    /**
+     * <pre>
+     * The globally unique id for this subchannel.  Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 subchannel_id = 7;</code>
+     */
+    public Builder setSubchannelId(long value) {
+      
+      subchannelId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * The globally unique id for this subchannel.  Must be a positive number.
+     * </pre>
+     *
+     * <code>int64 subchannel_id = 7;</code>
+     */
+    public Builder clearSubchannelId() {
+      
+      subchannelId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object name_ = "";
+    /**
+     * <pre>
+     * An optional name associated with the subchannel.
+     * </pre>
+     *
+     * <code>string name = 8;</code>
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the subchannel.
+     * </pre>
+     *
+     * <code>string name = 8;</code>
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * An optional name associated with the subchannel.
+     * </pre>
+     *
+     * <code>string name = 8;</code>
+     */
+    public Builder setName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the subchannel.
+     * </pre>
+     *
+     * <code>string name = 8;</code>
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * An optional name associated with the subchannel.
+     * </pre>
+     *
+     * <code>string name = 8;</code>
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFieldsProto3(unknownFields);
+    }
+
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:grpc.channelz.SubchannelRef)
+  }
+
+  // @@protoc_insertion_point(class_scope:grpc.channelz.SubchannelRef)
+  private static final io.grpc.channelz.v1.SubchannelRef DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.grpc.channelz.v1.SubchannelRef();
+  }
+
+  public static io.grpc.channelz.v1.SubchannelRef getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<SubchannelRef>
+      PARSER = new com.google.protobuf.AbstractParser<SubchannelRef>() {
+    public SubchannelRef parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new SubchannelRef(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<SubchannelRef> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<SubchannelRef> getParserForType() {
+    return PARSER;
+  }
+
+  public io.grpc.channelz.v1.SubchannelRef getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelRefOrBuilder.java b/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelRefOrBuilder.java
new file mode 100644
index 0000000..4b4f311
--- /dev/null
+++ b/services/src/generated/main/java/io/grpc/channelz/v1/SubchannelRefOrBuilder.java
@@ -0,0 +1,36 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: io/grpc/channelz.proto
+
+package io.grpc.channelz.v1;
+
+public interface SubchannelRefOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:grpc.channelz.SubchannelRef)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <pre>
+   * The globally unique id for this subchannel.  Must be a positive number.
+   * </pre>
+   *
+   * <code>int64 subchannel_id = 7;</code>
+   */
+  long getSubchannelId();
+
+  /**
+   * <pre>
+   * An optional name associated with the subchannel.
+   * </pre>
+   *
+   * <code>string name = 8;</code>
+   */
+  java.lang.String getName();
+  /**
+   * <pre>
+   * An optional name associated with the subchannel.
+   * </pre>
+   *
+   * <code>string name = 8;</code>
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+}
