code: func ChainStreamClient(interceptors ...grpc.StreamClientInterceptor) grpc.StreamClientInterceptor {
  	n := len(interceptors)
  
  	if n > 1 {
  		lastI := n - 1
  		return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
  			var (
  				chainHandler grpc.Streamer
  				curI         int
  			)
  
  			chainHandler = func(currentCtx context.Context, currentDesc *grpc.StreamDesc, currentConn *grpc.ClientConn, currentMethod string, currentOpts ...grpc.CallOption) (grpc.ClientStream, error) {
  				if curI == lastI {
  					return streamer(currentCtx, currentDesc, currentConn, currentMethod, currentOpts...)
  				}
  				curI++
  				stream, err := interceptors[curI](currentCtx, currentDesc, currentConn, currentMethod, chainHandler, currentOpts...)
  				curI--
  				return stream, err
  			}
  
  			return interceptors[0](ctx, desc, cc, method, chainHandler, opts...)
  		}
  	}
  
  	if n == 1 {
  		return interceptors[0]
  	}
  
  	// n == 0; Dummy interceptor maintained for backward compatibility to avoid returning nil.
  	return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
  		return streamer(ctx, desc, cc, method, opts...)
  	}
  }
docs: // ChainStreamClient creates a single interceptor out of a chain of many interceptors.
  //
  // Execution is done in left-to-right order, including passing of context.
  // For example ChainStreamClient(one, two, three) will execute one before two before three.