o
    hU2                     @   s   d dl mZ d dlZd dlmZ d dlmZ d dlmZm	Z	 d dl
mZ d!ddZd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZG dd  d eZdS )"    )dequeN)misc_to_space_after)Tree)DependencyGraphFlattenedParseTree)resolve_classpathc                 C   sN   t |}|du rtdtjdd||g|  tjdd}| }||j |S )zq
    Use subprocess to run a Java protobuf processor on the given request

    Returns the protobuf response
    NzClasspath is None,  Perhaps you need to set the $CLASSPATH or $CORENLP_HOME environment variable to point to a CoreNLP install.java-cpT)inputstdoutcheck)r   
ValueError
subprocessrunSerializeToStringPIPEParseFromStringr   )requestresponse_type	java_main	classpathpiperesponse r   _/var/www/html/env_mimamsha/lib/python3.10/site-packages/stanza/server/java_protobuf_requests.pysend_request	   s   r   c                 C   sx   | j  }d|_|d ur||_| j  }|j|_|jD ]}| r+| j  }|j|_qt| |d  q| j  }d|_	d S )NT)
nodesaddopenNodescorelabelvaluechildrenis_leafadd_tree_nodes	closeNode)
proto_treetreer   nodechildr   r   r   r$      s   






r$   c                 C   s   t  }t|| | |S )aV  
    Builds a FlattenedParseTree from CoreNLP.proto

    Populates the value field from tree.label and iterates through the
    children via tree.children.  Should work on any tree structure
    which follows that layout

    The score will be added to the top node (if it is not None)

    Operates by recursively calling add_tree_nodes
    )r   r$   )r'   r   r&   r   r   r   
build_tree2   s   r*   c           
      C   sr  d}t  }| jD ]}|dr|du r|j}|jr9t|dkr3t|d tjr3|d jr3t	d
| || q|jsHt|jd}|| qt|dkrUt	d
| g }| }t|tjsp|| | }t|tjrat|dkr}t	d	
| |  |d }|dd }t|j|d
}|| qt|dkrt	d
| | }	t|	tst	d
| |	|fS )z}
    Convert a FlattenedParseTree back into a Tree

    returns Tree, score
      (score might be None if it is missing)
    Nr   r   z'Got a proto with no label on a node: {})r       z.Got a proto with too many close operations: {}z<Got a proto with an open immediately followed by a close: {})r    r"   z5Got a proto which does not close all of the nodes: {}z1Got a proto which was just one Open operation: {})r   r   HasFieldr   r   len
isinstancer   Noder   formatappendr%   r   r!   popreverser    )
r&   r   stackr(   r)   r"   nextNoder    subtreer'   r   r   r   	from_treeB   sF   
&



r8   c                 C   s  |du rt |jtrtd|  }|j|_|j|_|jdur#|j|_|j	dur,|j	|_
|jdur5|j|_|jr]|jdkr]|jdD ]}|jddd\}}|jj| |jj| qC|dur|jdurj|j|_|durt|jdkr|j|_d|_|jd	 |jk|_|jd
 |jkrn|j|_|j|_nt|j|_|jd	 |_|jd |_|jr|jdkr|j|_|dur|jr|jdkr|j|_dS dS dS dS )z
    Add a token to a proto request.

    CoreNLP tokens have components of both word and token from stanza.

    We pass along "after" but not "before"
    Nz.Only expected word w/o token for 'extra' words_|=r,   maxsplitTr   r+   )r/   idintAssertionErrorr   textwordr!   lemmaxposposupos	coarseTagfeatssplitconllUFeatureskeyr2   nerr.   mwtTextisMWT
isFirstMWTspaces_afterafterindexr   misc
emptyIndex
conllUMiscmwtMisc)
token_listrB   tokenquery_tokenfeaturerK   r!   r   r   r   	add_tokens   sF   




r[   c                 C   sR   |   }||_|tdd |jD  |_|jD ]}|jD ]	}t|j|| qq|S )zQ
    Add the tokens for this stanza sentence to a list of protobuf sentences
    c                 s   s    | ]}t |jV  qd S N)r.   words).0rX   r   r   r   	<genexpr>   s    zadd_sentence.<locals>.<genexpr>)r   tokenOffsetBeginsumtokenstokenOffsetEndr]   r[   rX   )request_sentencessentence
num_tokensrequest_sentencerX   rB   r   r   r   add_sentence   s   

rh   c                 C   sv   | j  }|d |_|d |_|jdkr7|jdur9| j }|j|_|d |_|jdur2|j|_	dS d|_	dS dS dS )zQ
    Add a node and possibly an edge for a word in a basic dependency graph.
    r,   r   Nr9   )
r(   r   sentenceIndexrR   headedgesourcetargetdepreldep)graphrB   sent_idxword_idxr(   rk   r   r   r   add_word_to_graph   s   






rs   c                 C   sV  |j D ]}|jD ]	}t| j|| qq|jD ]	}t| j|d q|j}|D ]}|dkr,q%||D ]S}|dkrA| jt	| j
 q1|||D ]<}| j }	t|trW||	_n|d |	_|d dkrg|d |	_t|trp||	_n|d |	_|d dkr|d |	_||	_qGq1| j
 }
|d |
_t|tr||
_q%|d |
_|d dkr|d |
_q%| S )zK
    Turns a networkx graph into a DependencyGraph from the proto file
    Nr   r,   )rb   r]   r[   rX   empty_words_enhanced_dependenciespredecessorsrootNoder2   r.   r(   get_edge_datark   r   r/   r?   rl   sourceEmptyrm   targetEmptyro   ri   rR   rT   )graph_protore   rq   rX   rB   dependenciesrm   rl   rn   rk   r(   r   r   r   convert_networkx_graph   sJ   














r}   c                 C   s8   | sd S t | jdkrd S ddd t| j| jD S )Nr   r:   c                 s   s     | ]\}}d ||f V  qdS )z%s=%sNr   )r^   rK   r!   r   r   r   r_      s    z%features_to_string.<locals>.<genexpr>)r.   rK   joinzipr!   )featuresr   r   r   features_to_string   s
   r   c                 C   N   | du s| dks| dkr| S |  d}dd |D }t|dkr%d|S dS )z3
    Return only the space-related misc pieces
    N r9   r:   c                 S   s&   g | ]}|j d ddd dv r|qS r;   r,   r<   r   )
SpaceAfterSpacesAfterSpacesBeforerI   r^   xr   r   r   
<listcomp>     & z%misc_space_pieces.<locals>.<listcomp>r   rI   r.   r~   rS   piecesr   r   r   misc_space_pieces      

r   c                 C   r   )z=
    Remove any pieces from misc which are space-related
    Nr   r9   r:   c                 S   s&   g | ]}|j d ddd dvr|qS r   r   r   r   r   r   r     r   z%remove_space_misc.<locals>.<listcomp>r   r   r   r   r   r   remove_space_misc  r   r   c                 C   s   |r| dng }d }d }|D ]}|dr|}q|ds#|dr&|}qtd| |  d}g }|D ]*}|drF|rE|| d }q5|dsP|drZ|rY|| d }q5|| q5|rg|| |rn|| t|dkrvd S d|S )Nr:   SpaceBeforer   r   z6An unknown piece wound up in the misc space fields: %sr   )rI   
startswithr@   r2   r.   r~   )rS   
space_miscspace_misc_piecesspace_misc_afterspace_misc_beforepiecer   
new_piecesr   r   r   substitute_space_misc  s<   







r   c                   @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )JavaProtobufContextzb
    A generic context for sending requests to a java program using protobufs in a subprocess
    Nc                 C   s2   t || _|| _|| _|d u rg }|| _d | _d S r\   )r   r   build_responser   
extra_argsr   )selfr   r   r   r   r   r   r   __init__9  s   

zJavaProtobufContext.__init__c                 C   s.   t jdd| j| jdg| j t jt jd| _d S )Nr   r	   z	-multiple)stdinr   )r   Popenr   r   r   r   r   r   r   r   r   	open_pipeC  s   zJavaProtobufContext.open_pipec                 C   s>   | j  d u r| j jddd | j j  d | _ d S d S )Nr      big)r   pollr   writeto_bytesflushr   r   r   r   
close_pipeH  s
   
zJavaProtobufContext.close_pipec                 C   s   |    | S r\   )r   r   r   r   r   	__enter__N  s   zJavaProtobufContext.__enter__c                 C   s   |    d S r\   )r   )r   typer!   	tracebackr   r   r   __exit__R  s   zJavaProtobufContext.__exit__c                 C   s   | j d u r	td| }| j jt|dd | j j| | j j  | j j	d}t|dk r8t
dt|d}| j j	|}|  }|| |S )Nz.Pipe to java process is not open or was closedr   r   z(Could not communicate with java process!)r   RuntimeErrorr   r   r   r.   r   r   r   readBrokenPipeErrorr?   
from_bytesr   r   )r   r   rA   response_lengthresponse_textr   r   r   r   process_requestU  s   

z#JavaProtobufContext.process_requestr\   )
__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   5  s    

r   r\   )collectionsr   r   stanza.models.common.utilsr   %stanza.models.constituency.parse_treer   stanza.protobufr   r   stanza.server.clientr   r   r$   r*   r8   r[   rh   rs   r}   r   r   r   r   objectr   r   r   r   r   <module>   s&    
15/!