o
    iv                     @   s   d Z ddlZddlZddlZddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZ ddlmZ ddlmZ G dd deZG dd deZG dd deZdS )a   Language Server stdio-mode readers

Parts of this code are derived from:

> https://github.com/palantir/python-jsonrpc-server/blob/0.2.0/pyls_jsonrpc/streams.py#L83   # noqa
> https://github.com/palantir/python-jsonrpc-server/blob/45ed1931e4b2e5100cc61b3992c16d6f68af2e80/pyls_jsonrpc/streams.py  # noqa
> > MIT License   https://github.com/palantir/python-jsonrpc-server/blob/0.2.0/LICENSE
> > Copyright 2018 Palantir Technologies, Inc.
    N)ThreadPoolExecutor)ListOptionalText)run_on_executor)convert_yielded)HTTPHeaders)IOLoop)Queue)FloatInstancedefault)LoggingConfigurable   )make_non_blockingc                       sN   e Zd ZdZdZeejddZee	ddZ
dd Z fdd	Zd
d Z  ZS )LspStdIoBasezGNon-blocking, queued base for communicating with stdio Language ServersNzthe stream to read/writehelpzqueue to get/putc                 C   s   d | jj| jS )Nz<{}(parent={})>)format	__class____name__parentself r   L/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/jupyter_lsp/stdio.py__repr__&   s   zLspStdIoBase.__repr__c                    s0   t  jdi | | jd|  tdd| _d S )Nz%s initializedr   )max_workersr   )super__init__logdebugr   executor)r   kwargsr   r   r   r   )   s   zLspStdIoBase.__init__c                 C   s   | j   | jd|  d S )Nz	%s closed)streamcloser    r!   r   r   r   r   r&   .   s   
zLspStdIoBase.close)r   
__module____qualname____doc__r"   r   io	RawIOBaser%   r
   queuer   r   r&   __classcell__r   r   r$   r   r      s    r   c                   @   s   e Zd ZdZeddjddZedddjddZedddjddZe	d	d
d Z
dd Zdd ZdddZ	ddedee fddZdefddZedefddZdS )LspStdIoReaderzLanguage Server stdio Reader

    Because non-blocking (but still synchronous) IO is used, rudimentary
    exponential backoff is used.
    z#maximum time to wait on idle streamr   T)configg?z#minimum time to wait on idle streamz next time to wait on idle streammax_waitc                 C   s   t jdkrdS | jd S )Nntg?   )osnamemin_waitr   r   r   r   _default_max_wait>   s   z LspStdIoReader._default_max_waitc                    sP   | j jrdS t| jd | j| _zt| jI dH  W dS  ty'   Y dS w )z'Simple exponential backoff for sleepingNr2   )r%   closedmin	next_waitr0   asynciosleep	Exceptionr   r   r   r   r;   B   s   zLspStdIoReader.sleepc                 C   s   | j | _dS )zReset the wait timeN)r5   waitr   r   r   r   wakeL   s   zLspStdIoReader.wakereturnNc              
      s   t | j | jjsWd}z"|  I dH }|s|  I dH  W q|   t | j	j
| W n" tyP } z| jd| || |  I dH  W Y d}~nd}~ww | jjr
dS dS )z.Read from a Language Server until it is closedNz$%s couldn't enqueue message: %s (%s))r   r%   r7   read_oner;   r>   r	   currentadd_callbackr,   
put_nowaitr<   r    	exception)r   messageer   r   r   readP   s&   
zLspStdIoReader.read     lengthc              
      s   d}g }d}||k rTt ||k rT|dkrTd}z
| j|| }W n	 ty*   Y nw |du r;|d8 }|  I dH  q|t |7 }|| ||k rTt ||k rT|dks|rud|}t ||kru| jdt | d| d| d|  |S )	a  Read the full length of the message unless exceeding max_parts or
           max_empties empty reads occur.

        See https://github.com/jupyter-lsp/jupyterlab-lsp/issues/450

        Crucial docs or read():
            "If the argument is positive, and the underlying raw
             stream is not interactive, multiple raw reads may be issued
             to satisfy the byte count (unless EOF is reached first)"

        Args:
           - length: the content length
           - max_parts: prevent absurdly long messages (1000 parts is several MBs):
             1 part is usually sufficient but not enough for some long
             messages 2 or 3 parts are often needed.
        Nr   r       z%Readout and content-length mismatch: z vs z;remaining empties: z; remaining parts: )	lenr%   rG   OSErrorr;   appendjoinr    warning)r   rJ   	max_partsmax_emptiesraw	raw_partsreceived_sizepartr   r   r   _read_contentf   s:   

zLspStdIoReader._read_contentc                    s   d}t  }t|  I dH }|rS|r+| r+|| t|  I dH }|r+| st|dd}|rS| j|dI dH }|durK|d }|S | j	
d| | |S )zRead a single message Nzcontent-length0)rJ   utf-8z&%s failed to read message of length %s)r   r   	_readlinestrip
parse_lineintgetrW   decoder    rP   )r   rE   headerslinecontent_lengthrS   r   r   r   r@      s*   
zLspStdIoReader.read_onec                 C   s,   z| j  d W S  ty   Y dS w )z(Read a line (or immediately return None)rZ   rX   )r%   readliner`   r\   rM   r   r   r   r   r[      s
   zLspStdIoReader._readliner?   N)rH   rI   )r   r'   r(   r)   r   tagr0   r5   r9   r   r6   r;   r>   rG   r^   r   bytesrW   r   r@   r   r[   r   r   r   r   r.   3   s&    



-r.   c                   @   s(   e Zd ZdZdddZedddZdS )	LspStdIoWriterzLanguage Server stdio Writerr?   Nc                    s   | j jsO| j I dH }z5z|d}dt||}t| |dI dH  W n t	y;   | j
d| | Y nw W | j  n| j  w | j jrdS dS )z*Write to a Language Server until it closesNrZ   zContent-Length: {}

{}z%s couldn't write message: %s)r%   r7   r,   r_   encoder   rL   r   
_write_oner<   r    rD   	task_done)r   rE   bodyresponser   r   r   write   s   
zLspStdIoWriter.writec                 C   s   | j | | j   d S )N)r%   rn   flush)r   rE   r   r   r   rj      s   zLspStdIoWriter._write_onere   )r   r'   r(   r)   rn   r   rj   r   r   r   r   rh      s
    
rh   )r)   r:   r*   r3   concurrent.futuresr   typingr   r   r   tornado.concurrentr   tornado.genr   tornado.httputilr   tornado.ioloopr	   tornado.queuesr
   	traitletsr   r   r   traitlets.configr   non_blockingr   r   r.   rh   r   r   r   r   <module>   s$    
 