U
    /e                     @  s   d Z ddlmZ ddlZeeZddlmZm	Z	m
Z
mZmZmZ ddlmZ ddlmZmZ ernddlmZ d	Zeeef ZG d
d dZdS )zn Assemble WebSocket wire message fragments into complete Bokeh Server
message objects that can be processed.

    )annotationsN)TYPE_CHECKINGAnyCallableListUnioncast   )ValidationError)BufferHeaderMessage)Protocol)Receiverc                   @  s   e Zd ZU dZded< ded< ded< ded	< ded
< dddddZdddddZdddddZdddddZdddddZ	dddddZ
dddddZdddd Zdd!dd"d#Zdd$dd%d&Zd'S )(r   a   Receive wire message fragments and assemble complete Bokeh server
    message objects.

    On ``MessageError`` or ``ValidationError``, the receiver will reset its
    state and attempt to consume a new message.

    The *fragment* received can be either bytes or unicode, depending on
    the transport's semantics (WebSocket allows both).

    .. code-block:: python

        [
            # these are required
            b'{header}',        # serialized header dict
            b'{metadata}',      # serialized metadata dict
            b'{content},        # serialized content dict

            # these are optional, and come in pairs; header contains num_buffers
            b'{buf_header}',    # serialized buffer header dict
            b'array'            # raw buffer payload data
            ...
        ]

    The ``header`` fragment will have the form:

    .. code-block:: python

        header = {
            # these are required
            'msgid'       : <str> # a unique id for the message
            'msgtype'     : <str> # a message type, e.g. 'ACK', 'PATCH-DOC', etc

            # these are optional
            'num_buffers' : <int> # the number of additional buffers, if any
        }

    The ``metadata`` fragment may contain any arbitrary information. It is not
    processed by Bokeh for any purpose, but may be useful for external
    monitoring or instrumentation tools.

    The ``content`` fragment is defined by the specific message type.

    z$Callable[[Receiver, Fragment], None]_current_consumerzList[Fragment]
_fragmentszMessage[Any] | None_messagezBufferHeader | None_buf_header_partialr   None)protocolreturnc                 C  s$   || _ | j| _d| _d| _d| _dS )z Configure a Receiver with a specific Bokeh protocol.

        Args:
            protocol (Protocol) :
                A Bokeh protocol object to use to assemble collected message
                fragments.
        N)	_protocol_HEADERr   r   r   r   )selfr    r   ;/tmp/pip-unpacked-wheel-f5fndrjf/bokeh/protocol/receiver.py__init__n   s
    zReceiver.__init__Fragment)fragmentr   c                   s   |  | | jS )a    Consume individual protocol message fragments.

        Args:
            fragment (``JSON``) :
                A message fragment to assemble. When a complete message is
                assembled, the receiver state will reset to begin consuming a
                new message.

        )r   r   r   r   r   r   r   consume|   s    

zReceiver.consumec                 C  s&   d | _ d | _| |g| _| j| _d S N)r   r   _assume_textr   	_METADATAr   r   r   r   r   r      s    zReceiver._HEADERc                 C  s"   |  |}| j| | j| _d S r!   )r"   r   append_CONTENTr   )r   r   metadatar   r   r   r#      s    
zReceiver._METADATAc                   sV     |} j|  fdd jd d D \}}} j||| _   d S )Nc                   s   g | ]}  |qS r   )r"   ).0xr   r   r   
<listcomp>   s     z%Receiver._CONTENT.<locals>.<listcomp>   )r"   r   r$   r   Zassembler   _check_complete)r   r   contentZheader_jsonZmetadata_jsonZcontent_jsonr   r)   r   r%      s
    
"zReceiver._CONTENTc                 C  s   |  || _| j| _d S r!   )r"   r   _BUFFER_PAYLOADr   r   r   r   r   _BUFFER_HEADER   s    zReceiver._BUFFER_HEADERc                 C  s6   |  |}ttt | jtt| j| |   d S r!   )	_assume_binaryr   r   r   r   Zassemble_bufferr   r   r,   )r   r   payloadr   r   r   r.      s    
 zReceiver._BUFFER_PAYLOAD)r   c                 C  s,   | j r | j jr | j | _| j| _n| j| _d S r!   )r   Zcompleter   r   r   r/   r)   r   r   r   r,      s    
zReceiver._check_completestrc                 C  s    t |tstd| jj |S )Nz8expected text fragment but received binary fragment for )
isinstancer2   r
   r   __name__r   r   r   r   r"      s    
zReceiver._assume_textbytesc                 C  s    t |tstd| jj |S )Nz8expected binary fragment but received text fragment for )r3   r5   r
   r   r4   r   r   r   r   r0      s    
zReceiver._assume_binaryN)r4   
__module____qualname____doc____annotations__r   r    r   r#   r%   r/   r.   r,   r"   r0   r   r   r   r   r   ;   s    
,
r   )r8   
__future__r   logging	getLoggerr4   logtypingr   r   r   r   r   r   
exceptionsr
   messager   r    r   __all__r2   r5   r   r   r   r   r   r   <module>   s   
 
