U
    c                     @   sp  d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
 ddlmZmZmZmZmZmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ ddlmZ eeZddddddgZ eedddZ!edddZ"G dd dZ#eddG dd de#Z$eddG dd de#Z%G dd  d ej&Z'eddG d!d dZ(G d"d dZ)G d#d dZ*G d$d% d%e)Z+dS )&z
Module defining common API types for use by rules and policies.

In principle, these aren't relevant to the high-level validation API.
    N)	dataclass)field)IterableOptionalTupleUnion)ArrayObjectDereferenceableDictionaryObjectIndirectObject	ReferenceTrailerReference)HistoricalResolver
RawPdfPath   )misc)
PdfHandler)TrailerDictionary   )ModificationLevelQualifiedWhitelistRuleWhitelistRuleReferenceUpdateContextRelativeContextAbsoluteContextabc                 C   sT   t | trt |trdS t | ttfrLt |ttfrL| j|jkoJ| j|jkS dS d S )NTF)
isinstancer   r   r   idnum
generationr    r"   H/tmp/pip-unpacked-wheel-0kb_yl26/pyhanko/sign/diff_analysis/rules_api.py	_eq_deref#   s    r$   r   c                 C   s6   t | trtdS t | ttfr2td| j| jfS d S )N)r   r   r   r   )r   r   hashr   r   r    r!   r%   r"   r"   r#   _hash_deref-   s    
r'   c                   @   sd   e Zd ZeeeddddZeeee	f eee
ef ddddZeee
ef d d	d
dZdS )r   r   )pdf_handlerabsolute_pathreturnc                 C   s   t ||dS )N)r(   path)r   )clsr(   r)   r"   r"   r#   from_absolute6   s    zContext.from_absoluter   )startr+   r*   c           	      C   s   |j }t|ttfrt|}|j|dd}t }t|D ]F\}\}}t|trh|t|k rh|j	}t }q8t|ttfr8||7 }q8t
||S )NF)Ztransparent_dereference)Zcontainer_refr   intstrr   Z
walk_nodes	enumerater   len	referencer   )	r,   r.   r+   Zcur_refwalkrel_pathixnodeobjr"   r"   r#   relative_to;   s    
zContext.relative_tor+   r*   c                 C   s   t d S NNotImplementedErrorselfr+   r"   r"   r#   descendN   s    zContext.descendN)__name__
__module____qualname__classmethodr   r   r-   r   r
   r   r/   r0   r9   r@   r"   r"   r"   r#   r   4   s   
 T)frozenc                   @   sH   e Zd ZU eed< eed< eeeef d dddZ	dd Z
dd	 Zd
S )r   anchorrelative_pathr:   c                 C   sF   | j  }tttf}t||s2td| j  d| j	|| j
| S )NzAnchor z is not a container object)rF   Z
get_objectr
   r   r   r   r   ZPdfReadError	__class__r9   rG   )r?   r+   rootZ
containersr"   r"   r#   r@   _   s    


zRelativeContext.descendc                 C   s   t dt| j| jfS )Nrel)r&   r'   rF   rG   r?   r"   r"   r#   __hash__h   s    zRelativeContext.__hash__c                 C   s$   t |to"|j| jko"t|j| jS r;   )r   r   rG   r$   rF   )r?   otherr"   r"   r#   __eq__k   s
    

zRelativeContext.__eq__N)rA   rB   rC   r	   __annotations__r   r   r/   r0   r@   rL   rN   r"   r"   r"   r#   r   R   s
   
	c                   @   sZ   e Zd ZU eed< edddddZeed< ee	dddZ
eeeef d d	d
dZdS )r   r+   FN)reprr&   comparedefaultr(   r*   c                 C   s   t | jj| jS r;   )r   r9   r(   Ztrailer_viewr+   rK   r"   r"   r#   relative_view   s    zAbsoluteContext.relative_viewr:   c                 C   s   t | j| | jS r;   )r   r+   r(   r>   r"   r"   r#   r@      s    zAbsoluteContext.descend)rA   rB   rC   r   rO   dataclass_fieldr(   r   propertyr   rT   r   r/   r0   r@   r"   r"   r"   r#   r   q   s   
   c                   @   s   e Zd ZdZdZdZdS )ApprovalTyper   r      N)rA   rB   rC   BLANKET_APPROVEAPPROVE_RELATIVE_CONTEXTAPPROVE_PATHr"   r"   r"   r#   rW      s   rW   c                   @   sD   e Zd ZU eed< dZee ed< edd Z	e
edddZdS )	r   updated_refNcontext_checkedc                    s    fddS )Nc                    s    f d| iS )Nr\   r"   )refr,   kwargsr"   r#   <lambda>       z+ReferenceUpdate.curry_ref.<locals>.<lambda>r"   r_   r"   r_   r#   	curry_ref   s    zReferenceUpdate.curry_refrS   c                 C   s0   | j }t|trtjS t|tr&tjS tjS d S r;   )r]   r   r   rW   rZ   r   r[   rY   )r?   contextr"   r"   r#   approval_type   s    

zReferenceUpdate.approval_type)rA   rB   rC   r   rO   r]   r   r   rD   rc   rV   rW   re   r"   r"   r"   r#   r      s   

c                   @   s.   e Zd ZdZeeeeeef  dddZ	dS )r   a  
    Abstract base class for a whitelisting rule that outputs references together
    with the modification level at which they're cleared.

    This is intended for use by complicated whitelisting rules that need to
    differentiate between multiple levels.
    oldnewr*   c                 C   s   t dS z
        Apply the rule to the changes between two revisions.

        :param old:
            The older, base revision.
        :param new:
            The newer revision to be vetted.
        Nr<   r?   rg   rh   r"   r"   r#   apply_qualified   s    
z&QualifiedWhitelistRule.apply_qualifiedN)
rA   rB   rC   __doc__r   r   r   r   r   rk   r"   r"   r"   r#   r      s   c                   @   s6   e Zd ZdZeeee dddZee	dddZ
dS )	r   aM  
    Abstract base class for a whitelisting rule that simply outputs
    cleared references without specifying a modification level.

    These rules are more flexible than rules of type
    :class:`.QualifiedWhitelistRule`, since the modification level can be
    specified separately (see :meth:`.WhitelistRule.as_qualified`).
    rf   c                 C   s   t dS ri   r<   rj   r"   r"   r#   apply   s    
zWhitelistRule.apply)levelr*   c                 C   s
   t | |S )ae  
        Construct a new :class:`QualifiedWhitelistRule` that whitelists the
        object references from this rule at the level specified.

        :param level:
            The modification level at which the output of this rule should be
            cleared.
        :return:
            A :class:`.QualifiedWhitelistRule` backed by this rule.
        )_WrappingQualifiedWhitelistRule)r?   rn   r"   r"   r#   as_qualified   s    zWhitelistRule.as_qualifiedN)rA   rB   rC   rl   r   r   r   rm   r   r   rp   r"   r"   r"   r#   r      s
   	c                   @   s:   e Zd ZeedddZeeeeee	f  dddZ
dS )ro   rulern   c                 C   s   || _ || _d S r;   rq   )r?   rr   rn   r"   r"   r#   __init__   s    z(_WrappingQualifiedWhitelistRule.__init__rf   c                 c   s$   | j ||D ]}| j|fV  qd S r;   )rr   rm   rn   )r?   rg   rh   r^   r"   r"   r#   rk      s    z/_WrappingQualifiedWhitelistRule.apply_qualifiedN)rA   rB   rC   r   r   rs   r   r   r   r   rk   r"   r"   r"   r#   ro      s   ro   ),rl   loggingZdataclassesr   r   rU   typingr   r   r   r   Zpyhanko.pdf_utils.genericr   r	   r
   r   r   r   Zpyhanko.pdf_utils.readerr   r   Z	pdf_utilsr   Zpdf_utils.rw_commonr   Zpdf_utils.xrefr   Z
policy_apir   	getLoggerrA   logger__all__r$   r'   r   r   r   ZOrderedEnumrW   r   r   r   ro   r"   r"   r"   r#   <module>   s>    
    
$