
    y                        S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SS	KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKrSr\R@                  " S5      r!\R@                  " S5      r"\#" SS\	RH                  -   SS\	RH                  -   /5      r%S r&S r'SSS\RP                  RR                  SSSSS\RT                  RV                  \RX                  RV                  S\RZ                  R\                  SSSS4S jr/S r0 " S S\Rb                  " \Rd                  5      5      r3 " S S\35      r4 " S S \35      r5 " S! S"5      r6S# r7g)$z1Utilities for expanding wildcarded GCS pathnames.    )absolute_import)division)unicode_literalsN)Iterator)api_factory)	cloud_api)errors)request_config_factory)folder_util)storage_url)resource_reference)log)debug_outputz!Expected files but got stream: {}z\*{3,}z[*?\[\]].z..c                 d    U R                  [        R                  5      S   R                  S5      $ )N   r   )
rpartitionossep
startswith)paths    ;lib/googlecloudsdk/command_lib/storage/wildcard_iterator.py
_is_hiddenr   3   s%    		 	#	.	.s	33    c                 >    [        [        R                  U 5      5      $ )zuChecks whether url_string contains a wildcard.

Args:
  url_string: URL string to check.

Returns:
  bool indicator.
)boolWILDCARD_REGEXsearch)
url_strings    r   contains_wildcardr    7   s     
n##J/	00r   TFc                 &   [         R                  " U 5      n[        U[         R                  5      (       a  [	        UUUUUUUUU
UUUUUUS9$ [        U[         R
                  5      (       a  [        UUUUU	US9$ [        R                  " SU-  5      e)a  Instantiate a WildcardIterator for the given URL string.

Args:
  url_str (str): URL string which may contain wildcard characters.
  error_on_missing_key (bool): If true, and the encryption key needed to
    decrypt an object is missing, the iterator raises an error for that
    object.
  exclude_patterns (Patterns|None): Don't return resources whose URLs or local
    file paths matched these regex patterns.
  fetch_encrypted_object_hashes (bool): Fall back to GET requests for
    encrypted cloud objects in order to fetch their hash values.
  fields_scope (cloud_api.FieldsScope): Determines amount of metadata returned
    by API.
  files_only (bool): Skips containers. Raises error for stream types. Still
    returns symlinks.
  force_include_hidden_files (bool): Include local hidden files even if not
    recursive iteration. URL should be for directory or directory followed by
    wildcards.
  get_bucket_metadata (bool): If true, perform a bucket GET request when
    fetching bucket resources.
  halt_on_empty_response (bool): Stops querying after empty list response. See
    CloudApi for details.
  ignore_symlinks (bool): Skip over symlinks instead of following them.
  managed_folder_setting (folder_util.ManagedFolderSetting): Indicates how to
    deal with managed folders.
   folder_setting (folder_util.FolderSetting): Indicates how to deal with
     folders.
  next_page_token (str|None): Used to resume LIST calls.
  object_state (cloud_api.ObjectState): Versions of objects to query.
  preserve_symlinks (bool): Preserve symlinks instead of following them.
  raise_managed_folder_precondition_errors (bool): If True, raises
    precondition errors from managed folder listing. Otherwise, suppresses
    these errors. This is helpful in commands that list managed folders by
    default.
  soft_deleted_buckets (bool): If true, soft deleted buckets will be queried.
  list_filter (str|None): If provided, objects with matching filters
    will be returned, The prefixes would still be returned regardless of
    whether they match the specified filter, See
    go/gcs-object-context-filtering for more details.

Returns:
  A WildcardIterator object.
)error_on_missing_keyexclude_patternsfetch_encrypted_object_hashesfields_scope
files_onlyget_bucket_metadatahalt_on_empty_responsemanaged_folder_settingfolder_settingnext_page_tokenobject_state(raise_managed_folder_precondition_errorssoft_deleted_bucketslist_filter)r#   r&   force_include_hidden_filesignore_symlinkspreserve_symlinkszUnknown url type %s.)	r   storage_url_from_string
isinstanceCloudUrlCloudWildcardIteratorFileUrlFileWildcardIteratorcommand_errorsInvalidUrlError)url_strr"   r#   r$   r%   r&   r0   r'   r(   r1   r)   r*   r+   r,   r2   r-   r.   r/   urls                      r   get_wildcard_iteratorr=   C   s    ~ 	++G4#[))** 1)&C!/55%'!1Y1 " #{**++)#='+  
(
()?#)E
FFr   c                     [         R                  " [        SU R                  5      nU R                  b  USU R                  -   -  n[
        R                  " U5      $ )zAsterisk counts greater than two treated as single * to mimic globs.

Args:
  url (StorageUrl): Url to compress wildcards in.

Returns:
  StorageUrl built from string with compressed wildcards.
*#)resubCOMPRESS_WILDCARDS_REGEXversionless_url_string
generationr   r3   )r<   compressed_url_strings     r   _compress_url_wildcardsrG      sQ     &&!93!$!;!;=^^S3>>11		,	,-B	CCr   c                   ,    \ rS rSrSr  SS jrS rSrg)WildcardIterator   zClass for iterating over Google Cloud Storage strings containing wildcards.

The base class is abstract; you should instantiate using the
wildcard_iterator() static factory method, which chooses the right
implementation depending on the base string.
Nc                 <    [        U5      U l        X l        X0l        g)z@Initializes class. See get_wildcard_iterator for Args docstring.N)rG   _url_exclude_patterns_files_only)selfr<   r#   r&   s       r   __init__WildcardIterator.__init__   s     (,DI-!r   c                 6    S[        U R                  SS5      -  $ )z2Returns string representation of WildcardIterator.zWildcardIterator(%s)r   N)getattrrL   rO   s    r   __repr__WildcardIterator.__repr__   s    !GDII|T$JJJr   )rM   rN   rL   )NF)__name__
__module____qualname____firstlineno____doc__rP   rU   __static_attributes__ r   r   rI   rI      s     		"Kr   rI   c                   @   ^  \ rS rSrSr     SU 4S jjrS rSrU =r$ )r8      z,Class to iterate over files and directories.c                   > [         [        U ]  UUUS9  XPl        X`l        U(       aF  UR
                  R                  S5      S   [        R                  :w  a  [        R                  " S5      eU R                  R
                  U l        SU R                  ;   U l        U R                  =(       d    U=(       d    [        U R                  5      U l        g)a9  Initialize FileWildcardIterator instance.

Args:
  url (FileUrl): A FileUrl instance representing a file path.
  exclude_patterns (Patterns|None): See get_wildcard_iterator.
  files_only (bool): Returns files and symlinks, skips folders, errors on
    streams.
  force_include_hidden_files (bool): Include hidden files even if not
    recursive iteration. URL should be for directory or directory followed
    by wildcards.
  ignore_symlinks (bool): Skip over symlinks instead of following them.
  preserve_symlinks (bool): Preserve symlinks instead of following them.
)r&   r?   z`If force-including hidden files, input URL must be directory or directory followed by wildcards.**N)superr8   rP   _ignore_symlinks_preserve_symlinksresource_namerstripr   r   r9   r:   rL   _path_recurser   _include_hidden_files)rO   r<   r#   r&   r0   r1   r2   	__class__s          r   rP   FileWildcardIterator.__init__   s    , 

. / 
 ,/ 	#$$S)"-7**.  ((DJDJJ&DMM3Mz$**7M 	r   c              #   @	  ^
#    U R                   R                  (       aq  U R                  (       a=  [        R                  " [
        R                  U R                   R                  5      5      e[        R                  " U R                   5      v   g U R                  [        ;   a#  [        R                  " U R                   5      v   g [        R                  " U R                  5      R                  5       nUR                   (       aB  [#        UR$                  SS  5      n[&        R(                  R*                  " U6 nUR,                  nOSnU R                  nUR/                  S5      (       a   [&        R(                  R+                  US5      nS[&        R0                  -   nU R                  R3                  U5      (       a  Um
OSm
U
4S j[        R                  " U5      R5                  U5       5       nU GH  nU R6                  (       a   U R6                  R9                  U5      (       d!  U R:                  (       d  [=        U5      (       a  MX  U R                  (       a~  [&        R(                  R?                  U5      (       dZ  [@        RB                  " U5      (       a=  [        R                  " [
        R                  U R                   R                  5      5      eM  [&        R(                  RE                  U5      nU(       an  U RF                  (       d]  [&        R(                  RI                  U5      (       d  U RJ                  (       a(  [L        RN                  " SR                  U5      5        GM{  U R                  R/                  S5      (       ac  U(       a  U RF                  (       dK  [&        R(                  RQ                  U5      (       a$  [&        R(                  RI                  U5      (       a  GM  [@        RR                  " U5      n	U(       d?  [&        R(                  RI                  U5      (       a  [        R                  " U	5      v   GMZ  U(       a,  U RF                  (       a  [        RT                  " U	5      v   GM  [        R                  " XS9v   GM     g 7f)	N   r   rb   r?    c              3   @   >#    U  H  nT[        U5      -   v   M     g 7fN)str).0ppath_prefixs     r   	<genexpr>0FileWildcardIterator.__iter__.<locals>.<genexpr>  s!      ?A 	c!f?s   zSkipping symlink {})
is_symlink)+rL   is_stdiorN   r9   r:   _FILES_ONLY_ERROR_FORMATformatrf   r   FileObjectResourcerh   _RELATIVE_PATH_SYMBOLSFileDirectoryResourcepathlibPath
expanduserrootlistpartsr   r   joinanchorendswithr   r   globrM   matchrj   r   isfiler   is_named_pipeislinkre   isdirrd   r   warningexistsr7   FileSymlinkPlaceholderResource)rO   pathlib_path path_components_relative_to_rootpath_relative_to_rootr    current_working_directory_prefixpath_iteratorr   rx   file_urlru   s             @r   __iter__FileWildcardIterator.__iter__   s    yy			,,$++DII,C,CD
 	
 11$))<<zz++ 44TYY??<<

+668L *.l.@.@.D)E& ggll,LM  dd"jj%%d++ ggll+@#F (+RVV|$zz=>>4kkd#(()>?M
 

 
 T%;%;%A%A$%G%G((Z-=-=			"''.."6"6$$T**..&--dii.E.EF  	
 77>>$'j
))ww}}T""d&;&;)0067 **

d
#
#$"9"977>>$''277==+>+>$$T*hBGGMM$// 66x@@$11 ??II 33
 	
U s   RR)rd   rj   rh   re   ri   )NFFFF)	rW   rX   rY   rZ   r[   rP   r   r\   __classcell__rk   s   @r   r8   r8      s)    4
 !&*XV
 V
r   r8   c                     ^  \ rS rSrSrSSS\R                  R                  SSS\R                  R                  \R                  R                  S\R                  R                  SSS4U 4S jjrS rS rS	 rSS
 jrS r SS jr SS jrS rSS jrSS jrS rS rS rS\S\\R>                     4S jr S\S\\R>                     4S jr!S r"Sr#U =r$$ )r6   iR  zAClass to iterate over Cloud Storage strings containing wildcards.TNFc                   > [         [        U ]  XUS9  [        R                  " U R
                  R                  5      U l        X l        X@l	        XPl
        Xpl        Xl        Xl        Xl        Xl        Xl        UU l        Xl        Xl        U[(        R*                  R,                  L a7  U R
                  R.                  b   [(        R*                  R0                  U l        OXl        U[(        R*                  R4                  L U l        U R                   [(        R*                  R0                  L =(       d+    U R6                  =(       a    U R
                  R.                  SL U l        g)a  Instantiates an iterator that matches the wildcard URL.

Args:
  url (CloudUrl): CloudUrl that may contain wildcard that needs expansion.
  error_on_missing_key (bool): If true, and the encryption key needed to
    decrypt an object is missing, the iterator raises an error for that
    object.
  exclude_patterns (Patterns|None): See get_wildcard_iterator.
  fetch_encrypted_object_hashes (bool): Fall back to GET requests for
    encrypted objects in order to fetch their hash values.
  fields_scope (cloud_api.FieldsScope): Determines amount of metadata
    returned by API.
  files_only (bool): Returns cloud objects, not prefixes or buckets. Also
    skips directory placeholder objects, although they are technically
    objects.
  get_bucket_metadata (bool): If true, perform a bucket GET request when
    fetching bucket resources. Otherwise, bucket URLs without wildcards may
    be returned without verifying the buckets exist.
  halt_on_empty_response (bool): Stops querying after empty list response.
    See CloudApi for details.
  managed_folder_setting (folder_util.ManagedFolderSetting): Indicates how
    to deal with managed folders.
  folder_setting (folder_util.FolderSetting): Indicates how to deal with
    folders.
  next_page_token (str|None): Used to resume LIST calls.
  object_state (cloud_api.ObjectState): Versions of objects to query.
  raise_managed_folder_precondition_errors (bool): If True, raises
    precondition errors from managed folder listing. Otherwise, suppresses
    these errors. This is helpful in commands that list managed folders by
    default.
  soft_deleted_buckets (bool): If true, soft deleted buckets will be
    queried.
  list_filter (str|None): If provided, objects with matching
    contexts will be returned. The prefixes would still be returned
    regardless of whether they match the specified context, See
    go/gcs-object-context-filtering for more details.
)r#   r&   N)rc   r6   rP   r   get_apirL   scheme_client_error_on_missing_key_fetch_encrypted_object_hashes_fields_scope_get_bucket_metadata_halt_on_empty_response_managed_folder_setting_folder_setting_next_page_token_object_state)_raise_managed_folder_precondition_errors_soft_deleted_buckets_list_filterr   ObjectStateLIVErE   LIVE_AND_NONCURRENT_object_state_for_listingSOFT_DELETED_soft_deleted _object_state_requires_expansion)rO   r<   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   rk   s                   r   rP   CloudWildcardIterator.__init__U  s+   n 

/: 0  &&tyy'7'78DL!5*G'% 3#9 #9 )+%0 	2 "6# 		--222II  ,'0'<'<'P'Pd$'3$%)>)>)K)KKDi33GGG 	A?499#7#74#? 	)r   c              #   ,  #    U R                   (       a?  U R                  R                  5       (       d  U R                  R                  5       (       a  g U R                  R                  5       (       a:  U R                  R                  U R                  U R                  S9 H  nUv   M	     g U R                  5        GH  nU R                  R                  5       (       a  Uv   M)  U R                  UR                  R                  5      nU R                  UR                  R                  US9 GH[  nU R                  (       a6  U R                  R                  UR                  R                  5      (       a  MK  U R                   (       ai  [!        U["        R$                  5      (       aH  UR                  R&                  R)                  [        R*                  5      (       a  UR,                  S:X  a  M  U R.                  [0        R2                  R4                  L a"  [!        U["        R6                  5      (       d  GM  U R8                  [0        R:                  R4                  L a"  [!        U["        R<                  5      (       d  GMW  Uv   GM^     GM     g 7f)Nr%   soft_deleted)is_hns_bucketr   )rN   rL   is_provider	is_bucketr   list_bucketsr   r   _fetch_buckets_is_hns_bucketr   bucket_name_fetch_sub_bucket_resourcesrM   r   rD   r4   r   ObjectResourcerf   r   CLOUD_URL_DELIMITERsizer   r   ManagedFolderSettingLIST_WITHOUT_OBJECTSManagedFolderResourcer   FolderSettingFolderResource)rO   bucket_resourcebucket_or_unknown_resourcer   resources        r   r   CloudWildcardIterator.__iter__  s    TYY2244		8K8K8M8Myy!\\66))11 7 / 	 )-(;(;(=
$99  *
* --(44@@- ::(44@@) ; h %%$*@*@*F*F$$;;+ + x);)J)JKK((66??#77  !*  ,,33HHI"0FF   $$,,AAB"8-?-N-NOONI )>s   JJc           	         U R                   (       Ga  [        R                  R                  U R                  R
                  ;   Ga  U R                  [        R                  R                  :w  Gai  [        U[        R                  5      (       GaI  UR                  (       Gd7  UR                  (       Gd%  UR                  (       aY  U R                  R                  UR                   UR"                  U R$                  R&                  U R                  U R(                  S9$ UR*                  (       a  [,        R.                  " UR0                  UR*                  U R2                  S9n[5        UR6                  SS 5      (       aZ  U R                  R                  UR                   UR"                  UU R$                  R&                  U R                  U R(                  S9$ U$ )NrE   r%   r   )decryption_key_hash_sha256r"   decryption_key)r   r   
Capability
ENCRYPTIONr   capabilitiesr   FieldsScopeSHORTr4   r   r   crc32c_hashmd5_hashkms_keyget_object_metadatabucketnamerL   rE   r   r   r
   get_request_configr   r   rS   resource_args)rO   r   request_configs      r   _decrypt_resource_if_necessary4CloudWildcardIterator._decrypt_resource_if_necessary  sf   +++  ++t||/H/HH)"7"7"="==x!3!B!BCC%%%):):): 
		||//OOMMyy++++++ 0 
 	
 
	,	,/BB  '/'J'J!%!;!;= >//1A4HH11oomm------ 2   Or   c           	          U R                   R                  UU R                  R                  [        R
                  " U R                  5      U R                  R                  U R                  U R                  S9nU R                  U5      $ ! [        R                   a     g[        R                   a  nUR                  S:X  ay  S[        U5      ;   aj  U R                  R                  R!                  U R                  R"                  5      (       a,  U R                  (       a  [$        R&                  " S5         SnAge SnAff = f)z/Matches user input that doesn't need expansion.r   i  zYou must specify a generationzGET failed with "must specify generation" error. This is expected for a soft-deleted object listed with a trailing slash. Falling back to a LIST call.N)r   r   rL   rf   r
   r   rE   r   r   r   
api_errorsNotFoundErrorGcsApiErrorstatus_coderr   r   r   	delimiterr   debug)rO   r   r   es       r   _try_getting_object_directly2CloudWildcardIterator._try_getting_object_directly  s
   11

))
!
!
 
3
3DII
>YY)))))) 2 h 00::## 
" ! !!  --3
-Q7ii""++DII,?,?@@  		3	

 	  	s%   BB E!E4BD>=D>>Ec                 L   [        U R                  R                  5      =(       dL    U R                  =(       d9    U R                  R                  R                  U R                  R                  5      nU(       d  U R                  U5      nU(       a  U/$ U R                  X5      $ )z:Fetch all objects for the given bucket that match the URL.)	r    rL   rf   r   r   r   r   r   _expand_object_path)rO   r   r   needs_further_expansiondirect_query_results        r   r   1CloudWildcardIterator._fetch_sub_bucket_resources/  s     	$))112 	>00	>99(()<)<= 
 # ==kJ	#$$##K??r   c              #     #    UR                   S L nU R                  [        R                  R                  [        R                  R
                  4;   n U(       af  [        R                  R                  U R                  R                  ;   a4  U(       a-  U R                  R                  XR                  =(       d    S S9nO/ nU H  nUv   M	     g ! [        R                   a    U R                  (       a  e  g f = f7f)Nr   prefix)r   r   r   r   LIST_WITH_OBJECTSr   r   r   MANAGED_FOLDERSr   r   list_managed_foldersr   r   PreconditionFailedErrorr   )rO   r   wildcard_partsis_recursive_expansionshould_list_managed_foldersmanaged_folder_iteratorr   s          r   _get_managed_folder_iterator2CloudWildcardIterator._get_managed_folder_iterator>  s      ,55="&">">((::((==C #
%""22dll6O6OO$"&,,"C"C#,A,A,IT #D #
 #%-( .-- 		7	7 
8s+   AC<A<C C<&C96C<8C99C<c              #   Z  #    UR                   S L nU R                  [        R                  R                  L =(       a    UnU R                  [        R                  R
                  4;   =(       d    UnUR                  (       a<  UR                  R                  S5      (       d  UR                  S-   OUR                  nOS nU(       aT  [        R                  R                  U R                  R                  ;   a"  U(       a  U R                  R                  UUS9nO/ nU H  n	U	v   M	     g 7f)N/r   )r   r   r   r   LIST_AS_FOLDERSr   r   r   r   r   FOLDERSr   r   list_folders)
rO   r   r   r   r   is_list_as_foldersshould_list_foldersmodified_prefixfolder_iteratorr   s
             r   _get_folder_iterator*CloudWildcardIterator._get_folder_iteratorY  s     ,55= 9 9 I II 	 
 	%%::<	= 	    &&//44 

#
%$$  o 	  ((DLL,E,EE"11!  2 o
 o#n $s   D)D+c                    U R                   [        R                  R                  La'  U R                  [        R
                  R                  Ld  UR                  (       a  U R                   [        R                  R                  L =(       a&    U R                  [        R
                  R                  L n[        UR                  5      nU(       d  U(       d  S OSnU R                  R                  UUR                  U R                  U R                  UU R                  UR                  =(       d    S U R                  U R                   S9	nO/ nU R#                  X5      nU R%                  XU5      n	[&        R(                  " UUU	S S9$ )NT)	r   r   r%   r(   include_folders_as_prefixesr+   r   r,   r/   c                 .    U R                   R                  $ rq   )r   r   )r   s    r   <lambda>>CloudWildcardIterator._get_resource_iterator.<locals>.<lambda>  s    X11<<r   )key)r   r   r   r   r   r   r   DO_NOT_LISTr   r   list_objectsr   r   r   r   r   r   r   r  heapqmerge)
rO   r   r   r   setting_is_do_not_listuses_delimiterr  object_iteratorr   r  s
             r   _get_resource_iterator,CloudWildcardIterator._get_resource_iterator  sg   
 ((33HHI$$,,AAB ##
 
&
&--99: L""k&?&?&K&KK  N445n )$D " 11!",,))!%!=!=&A//&&.$55'' 2 
o o"?? //]O ;;<	 r   c                    [        U5      [        R                  Ldt  U R                  [        R
                  R                  [        R
                  R                  1;  d2  [        R                  R                  U R                  R                  ;  a  U$  UR                  nU R                  R                  UR                  UR                   5      $ ! ["        R$                   a    Us $ f = f)zDIf resource is a prefix, attempts to convert it to a managed folder.)typer   PrefixResourcer   r   r   r   r   r   r   r   r   r   r   get_managed_folderr   rf   r   r   )rO   r   
prefix_urls      r   '_maybe_convert_prefix_to_managed_folder=CloudWildcardIterator._maybe_convert_prefix_to_managed_folder  s    
 	X0???'',,>>,,AA


 //t||7P7PPo''j\\,,

 
 *":":  ## os   ;C C)(C)c                 8   [        U5      [        R                  Ldt  U R                  [        R
                  R                  [        R
                  R                  1;  d2  [        R                  R                  U R                  R                  ;  a  U$ U R                  [        R
                  R                  L a	  U(       d  U$  UR                  nU R                  R                  UR                  UR                   5      $ ! ["        R$                   a    Us $ f = f)z<If resource is a prefix, attempts to convert it to a folder.)r  r   r  r   r   r   r   r   r   r   r   r   r   r   
get_folderr   rf   r   r   )rO   r   r   r  s       r   _maybe_convert_prefix_to_folder5CloudWildcardIterator._maybe_convert_prefix_to_folder  s    
 	X0???%%::%%55


 ''t||/H/HHo 	 9 9 I IIo''j\\$$

 
 *":":  ## os   ;D   DDc              #   B  #    U R                   R                  nUR                  U R                   R                  5      (       aW  [	        U R                   R                  5      (       d  U R                  U5      nU(       a  Uv   [        R                  " U5      nOUn[        R                  " U/5      nSnU(       Ga  UR                  5       n[        R                  XR                   R                  5      n	U R                  XU5      n
U R                  U
U	R                  U	R                   -   5      nU GHS  nUR                  R                  nU	R"                  (       a~  [%        U5      [&        R(                  L a`  [*        R-                  U5      (       a'  [.        R0                  " SR3                  U5      5      nM  UR5                  XR"                  -   5        M  M  UR                  U R                   R                  5      (       d,  UR                  U R                   R                  5      (       a  M  U R7                  X5      n[9        U[&        R:                  5      (       d  U R=                  U5      nU R?                  U5      v   GMV     U(       a  GM  U(       a  Ueg7f)a  Expands object names.

Args:
  bucket_name (str): Name of the bucket.
  is_hns_bucket (bool): Whether the bucket is an HNS bucket.

Yields:
  resource_reference.Resource objects where each resource can be
  an ObjectResource object or a PrefixResource object.
NzECloud folders named with wildcards are not supported. API returned {}) rL   rf   r   r   r    r   r   rstrip_one_delimitercollectionsdequepopleftCloudWildcardPartsfrom_stringr  _filter_resourcesr   filter_patternsuffixr  r   r  r   r   r9   r:   r{   appendr  r4   r   r  r   )rO   r   r   original_object_namer   object_namenames_needing_expansionerrorr   r   resource_iteratorfiltered_resourcesr   resource_paths                 r   r   )CloudWildcardIterator._expand_object_path  s2      9922$$TYY%8%899tyy6677"??L#
#445IJk(k)//>E
!$,,.d *55dII<O<OPn 55
}  11



."?"?
?
 )( ,,::   (^1@@@
 $$]33$44%%+VH%5e
 &,,"7"77 A$ ''ii!! $--dii.A.ABB
 99( H&8&G&GHHCCHMH33H=
=K )+ "
!x k s   JJ
Jc                    U/nUR                  [        R                  5      (       d"  UR                  U[        R                  -   5        SU;   a$  UR	                  SS5      nUR                  U5        OUnX4 H/  nUR                  S5      (       d  M  UR                  USS 5        M1     U Vs/ s H-  n[        R                  " [        R                  " U5      5      PM/     sn$ s  snf )a  Returns list of regex patterns derived from the wildcard patterns.

Args:
  wildcard_pattern (str): A wilcard_pattern to filter the resources.

Returns:
  List of compiled regex patterns.

This translates the wildcard_pattern and also creates some additional
patterns so that we can treat ** in a/b/c/**/d.txt as zero or more folders.
This means, a/b/c/d.txt will also be returned along with a/b/c/e/f/d.txt.
z/**/r   z**/   N)
r   r   r   r*  replacer   rA   compilefnmatch	translate)rO   wildcard_patternwildcard_patternsupdated_patternpatternrt   s         r   _get_regex_patterns)CloudWildcardIterator._get_regex_patternsN  s     **$$[%D%DEE/*>> ? @ !! )00=o/(o$6			E	"	" 	  - 7 7HH6GBJJw((+,6GHHHs   04C'c              #   J  #    U R                  U5      nU H  nU R                  R                  (       a0  UR                  R                  U R                  R                  :w  a  MN  U H4  nUR	                  UR                  R
                  5      (       d  M/  Uv     M     M     g7f)a.  Filter out resources that do not match the wildcard_pattern.

Args:
  resource_iterator (iterable): An iterable resource_reference.Resource
    objects.
  wildcard_pattern (str): The wildcard_pattern to filter the resources.

Yields:
  resource_reference.Resource objects matching the wildcard_pattern
N)r=  rL   rE   r   r   rf   )rO   r/  r9  regex_patternsr   regex_patterns         r   r'  'CloudWildcardIterator._filter_resourcest  s      --.>?N%
))





)
)TYY-A-A
A)-x33AABB.
 * &s   BB#B#c                    [        U R                  R                  5      (       a%  U R                  U R                  R                  5      $ U R                  R	                  5       (       a  U R
                  (       ao  U R                  (       a%  U R                  U R                  R                  5      $ U R                  R                  U R                  R                  U R                  S9/$ [        R                  " U R                  5      /$ )ztFetch the bucket(s) corresponding to the url.

Returns:
  An iterable of BucketResource or UnknownResource objects.
)r   r%   )r    rL   r   _list_buckets_matching_wildcardr   r   r   -_fetch_all_soft_deleted_generations_of_bucketr   
get_bucketr   r   UnknownResourcerT   s    r   r   $CloudWildcardIterator._fetch_buckets  s     ..//11$))2G2GHH					4#<#< 
	#	#AAII!!
 	

 ,,
!
!))//-- "   !00;<<r   r   returnc              #      #    U R                   R                  U R                  U R                  S9 H  nXR                  :X  d  M  Uv   M     g7f)a  Fetch the soft-deleted buckets with the given name.

  List_buckets retrieves all versions of a bucket, including
  soft-deleted ones. Get_bucket retrieves the live bucket or a specific
  soft-deleted version of the bucket if generation is specified. This is
  useful when needing to access a particular deleted version that has been
  identified from the List_buckets output.

Args:
  bucket_name (str): Bucket name.

Yields:
  BucketResource objects.
r   N)r   r   r   r   r   )rO   r   r   s      r   rE  CCloudWildcardIterator._fetch_all_soft_deleted_generations_of_bucket  sK     $  <<44''// 5  
,,	,s   ?A	Ac              #     #    [         R                  " U5      n[        R                  " U5      nU R                  R                  U R                  U R                  S9 H)  nUR                  UR                  5      (       d  M%  Uv   M+     g7f)zList buckets matching the wildcard pattern.

Args:
  bucket_name (str): Bucket name with wildcard.

Yields:
  BucketResource objects.
r   N)
r7  r8  rA   r6  r   r   r   r   r   r   )rO   r   regexbucket_patternr   s        r   rD  5CloudWildcardIterator._list_buckets_matching_wildcard  st      k*EZZ&N<<44''// 5  
		o22	3	3s   A<B	Bc                    U R                   [        R                  R                  Ld2  [        R
                  R                  U R                  R                  ;  a  g U R                  R                  U5      n[        [        USS 5      =(       a    UR                   R"                  5      $ ! [        R                   a%  nUR                  R                  S:w  a  e  S nAgS nAff = f)NFi  hierarchicalNamespace)r   r   r   r   r   r   STORAGE_LAYOUTr   r   get_storage_layoutr   r   payloadr   r   rS   rQ  enabled)rO   r   bucket_layoutr.  s       r   r   $CloudWildcardIterator._is_hns_bucket  s    K$=$=$M$MM..dll6O6OO
ll55kBm 6= 	8//77  !! 
 
	"	"c	)s   B* *C#>CC#)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )F)%rW   rX   rY   rZ   r[   r   r   NO_ACLr   r   r  r   r   r   rP   r   r   r   r   r   r  r  r  r  r   r=  r'  r   rr   r   r   BucketResourcerE  rD  r   r\   r   r   s   @r   r6   r6   R  s
   I
  $)((//!(==II ..::((--/3 !Un:x"H!F@8 8=$N 8=?B0<Vp$IL,=4"1122"112( r   r6   c                   b    \ rS rSrSrS r\\R                  R                  4S j5       r
S rSrg)r%  i  zGDifferent parts of the wildcard string used for querying and filtering.c                 4    Xl         X l        X0l        X@l        g)a  Initialize the CloudWildcardParts object.

Args:
  prefix (str): The prefix string to be passed to the API request.
    This is the substring before the first occurrance of the wildcard.
  filter_pattern (str): The pattern to be used to filter out the results
    returned by the list_objects call. This is a substring starting from
    the first occurance of the wildcard upto the first delimiter.
  delimiter (str): The delimiter to be passed to the api request.
  suffix (str): The substirng after the first delimiter in the wildcard.
N)r   r(  r   r)  )rO   r   r(  r   r)  s        r   rP   CloudWildcardParts.__init__  s     K(NKr   c                 n    [        U5      u  p4UR                  U5      u  pVnSU;   a  SnUnSnU " X5X'5      $ )zCreate a CloudWildcardParts instance from a string.

Args:
  string (str): String that needs to be splitted into different parts.
  delimiter (str): The delimiter to be used for splitting the string.

Returns:
  WildcardParts object.
rb   N)_split_on_wildcard	partition)clsstringr   r   wildcard_stringr(  _r)  s           r   r&  CloudWildcardParts.from_string  sN     18F !0 9 9) DNv~ i&nfvy99r   c                 .    [         R                  " U 5      $ rq   )r   generic_reprrT   s    r   rU   CloudWildcardParts.__repr__  s    $$T**r   )r   r(  r   r)  N)rW   rX   rY   rZ   r[   rP   classmethodr   r5   CLOUD_URL_DELIMr&  rU   r\   r]   r   r   r%  r%    s2    O" )4)=)=)M)M : :6+r   r%  c                 r    [         R                  U 5      nUc  U S4$ UR                  5       nU SU nXS nX44$ )a  Split the string into two such that first part does not have any wildcard.

Args:
  string (str): The string to be split.

Returns:
  A 2-tuple where first part doesn't have any wildcard, and second part does
  have a wildcard. If wildcard is not found, the second part is empty.
  If string starts with a wildcard then first part is empty.
  For example:
    _split_on_wildcard('a/b/c/d*e/f/*.txt') => ('a/b/c/d', '*e/f/*.txt')
    _split_on_wildcard('*e/f/*.txt') => ('', '*e/f/*.txt')
    _split_on_wildcard('a/b/c/d') => ('a/b/c/d', '')
Nro   )r   r   start)ra  r   first_wildcard_idxr   wildcard_strs        r   r^  r^    sQ     


'%
]2:{{}%%&&+,,		r   )8r[   
__future__r   r   r   abcr"  r7  r  r   r   rA   typingr   googlecloudsdk.api_lib.storager   r   r	   r   r
   "googlecloudsdk.command_lib.storager9   r   r   ,googlecloudsdk.command_lib.storage.resourcesr   googlecloudsdk.corer   googlecloudsdk.core.utilr   sixrz   r6  rC   r   	frozensetr   r}   r   r    r   rX  r   r  r   r   r   r=   rG   with_metaclassABCMetarI   r8   r6   r%  r^  r]   r   r   <module>rz     s_    8 &  ' 
    	  	  6 4 ? A G : : K # 1 
 ? ::i0 K("CrvvtTBFF]#KL 4	1 "'&&--$&;;GG,,88&&++-2%\G~D Ks))#++6 K0E
+ E
PU
, U
p1+ 1+hr   