
     h                     8   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
Jr  SSKJr  SSKJr  SSKrSS	KJr  S
rSr " S S\R*                  5      r\" \R0                  \R2                  /5      r\" \R6                  \R8                  /5      r\" \ V s/ s H  o R<                  PM     sn 5      rSr Sr!\RD                  " S5      r#\RD                  " S5      r$\RD                  " S5      r%\RD                  " S5      r&S r' " S S\RP                  " \RR                  5      5      r* " S S\*5      r+ " S S\*5      r, " S S\,5      r- " S S\,5      r. " S S \*5      r/ " S! S"\/5      r0S# r1S*S$ jr2\/Rf                  4S% jr4S& r5S' r6S( r7S) r8gs  sn f )+z*File and Cloud URL representation classes.    )absolute_import)division)unicode_literalsN)errors)log)	platforms)urllibz://z_.gstmpc                   4    \ rS rSrSrSrSrSrSrSr	Sr
S	rS
rg)ProviderPrefix'   z)Provider prefix strings for storage URLs.filegshdfshttphttpsposixs3 N)__name__
__module____qualname____firstlineno____doc__FILEGCSHDFSHTTPHTTPSPOSIXS3__static_attributes__r       5lib/googlecloudsdk/command_lib/storage/storage_url.pyr   r   '   s(    1	$#	$	$
%
%"r"   r   /zblob.core.windows.netz$(?P<name>.+)#(?P<generation>[0-9]+)$z (?P<name>.+)#(?P<version_id>.+)$z;^(?P<access_point>arn:aws:s3::.+:accesspoint\/(?:.+\.mrap))z.*\/\/(?P<key>.+)$c                     [         R                  R                  U 5      =(       a4    [        R                  " [         R                  " U 5      R
                  5      $ N)ospathexistsstatS_ISFIFOst_mode)r(   s    r#   is_named_piper-   G   s1    			F$--0E0E"FFr"   c                       \ rS rSrSr\R                  S 5       r\S 5       r	\S 5       r
\R                  S 5       r\R                  S 5       rS rS	 rS
 rS rSrg)
StorageUrlK   z4Abstract base class for file and Cloud Storage URLs.c                     g)z"Returns the delimiter for the url.Nr   selfs    r#   	delimiterStorageUrl.delimiterN       r"   c                     [         ezFReturns True if the URL points to a named pipe (FIFO) or other stream.NotImplementedErrorr2   s    r#   	is_streamStorageUrl.is_streamR   
     r"   c                     [         e)2Returns True if the URL points to stdin or stdout.r9   r2   s    r#   is_stdioStorageUrl.is_stdioW   r=   r"   c                     g)2Returns the string representation of the instance.Nr   r2   s    r#   
url_stringStorageUrl.url_string\   r6   r"   c                     g)zFReturns the string representation of the instance without the version.Nr   r2   s    r#   versionless_url_string!StorageUrl.versionless_url_string`   r6   r"   c                     [        U R                  U R                  5      nUR                  U R                  5      (       a  USS OUnSR	                  X R                  U5      n[        U5      $ )aE  Appends part at the end of url_string.

The join is performed in 3 steps:
1) Strip off one delimiter (if present) from the right of the url_string.
2) Strip off one delimiter (if present) from the left of the part.
3) Join the two strings with delimiter in between.

Note that the behavior is slight different from os.path.join for cases
where the part starts with a delimiter.
os.path.join('a/b', '/c') => '/c'
But this join method will return a StorageUrl with url_string as 'a/b/c'.
This is done to be consistent across FileUrl and CloudUrl.

The delimiter of the instance will be used. So, if you are trying to append
a Windows path to a CloudUrl instance, you have to make sure to convert
the Windows path before passing it to this method.

Args:
  part (str): The part that needs to be appended.

Returns:
  A StorageUrl instance.
   N{}{}{})rstrip_one_delimiterrG   r4   
startswithformatstorage_url_from_string)r3   partleftrightnew_url_strings        r#   joinStorageUrl.joind   sX    0   ; ;T^^LD77DHTE__T>>5AN">22r"   c                 t    [        U[        U 5      5      (       d  [        $ U R                  UR                  :H  $ r&   )
isinstancetypeNotImplementedrD   )r3   others     r#   __eq__StorageUrl.__eq__   s.    eT$Z((??e....r"   c                 ,    [        U R                  5      $ r&   )hashrD   r2   s    r#   __hash__StorageUrl.__hash__   s      r"   c                     U R                   $ r&   rD   r2   s    r#   __str__StorageUrl.__str__   s    ??r"   r   N)r   r   r   r   r   abcabstractpropertyr4   propertyr;   r@   rD   rG   rT   r[   r_   rc   r!   r   r"   r#   r/   r/   K   s    <- -     = = Q Q3:/
!r"   r/   c                      ^  \ rS rSrSrU 4S jrS r\S 5       r\S 5       r	\S 5       r
S rS	 r\S
 5       r\S 5       rSrU =r$ )FileUrl   a  File URL class providing parsing and convenience methods.

This class assists with usage and manipulation of an
(optionally wildcarded) file URL string.  Depending on the string
contents, this class represents one or more directories or files.

Attributes:
  scheme (ProviderPrefix): This will always be "file" for FileUrl.
  bucket_name (str): None for FileUrl.
  resource_name (str): The file/directory path.
  generation (str): None for FileUrl.
c                 |  > [         [        U ]  5         [        R                  U l        SU l        SU l        UR                  S5      (       a  U[        S5      S nOUn[        R                  R                  5       (       a&  UR                  S[        R                  5      U l        OX l        U R#                  5         g)z^Initialize FileUrl instance.

Args:
  url_string (str): The string representing the filepath.
Nzfile://r$   )superri   __init__r   r   schemebucket_name
generationrM   lenr   OperatingSystem	IsWindowsreplacer'   sepresource_name$_warn_if_unsupported_double_wildcard)r3   rD   filename	__class__s      r#   rm   FileUrl.__init__   s     
'4!# %%DKDDOY''C	NO,hh
   **,,#++C8d#--/r"   c                 Z   U R                   (       d  gU R                  U R                   -   U R                  -   nUR                  SR                  U R                  S95      nSR	                  U5      nSU;   a4  [
        R                  " SR                  [        R                  5      5        gg)z4Log warning if ** use may lead to undefined results.Nz{delim}**{delim})delim z**zv** behavior is undefined if directly preceded or followed by with characters other than / in the cloud and {} locally.)	rv   r4   splitrN   rT   r   warningr'   ru   )r3   delimiter_bounded_url	split_url+removed_correct_double_wildcards_url_strings       r#   rw   ,FileUrl._warn_if_unsupported_double_wildcard   s      NNT-?-??$..P%++!!!79I24'')2D/::	kkGGMvffH ;r"   c                 "    [         R                  $ )z8Returns the pathname separator character used by the OS.)r'   ru   r2   s    r#   r4   FileUrl.delimiter   s     66Mr"   c                 R    U R                   =(       d    [        U R                  5      $ r8   )r@   r-   rv   r2   s    r#   r;   FileUrl.is_stream   s     ===M$*<*<==r"   c                      U R                   S:H  $ )r?   -)rv   r2   s    r#   r@   FileUrl.is_stdio   s     $$r"   c                 T    [         R                  R                  U R                  5      $ )z*Returns True if the file/directory exists.)r'   r(   r)   rv   r2   s    r#   r)   FileUrl.exists   s    77>>$,,--r"   c                 T    [         R                  R                  U R                  5      $ )z0Returns True if the path represents a directory.)r'   r(   isdirrv   r2   s    r#   r   FileUrl.isdir   s    77==++,,r"   c                 l    SR                  U R                  R                  [        U R                  5      $ rC   rK   rN   rn   valueSCHEME_DELIMITERrv   r2   s    r#   rD   FileUrl.url_string   -     ??4;;,,.>--/ /r"   c                     U R                   $ znReturns the string representation of the instance.

Same as url_string because these files are not versioned.
rb   r2   s    r#   rG   FileUrl.versionless_url_string        ??r"   ro   rp   rv   rn   )r   r   r   r   r   rm   rw   rg   r4   r;   r@   r)   r   rD   rG   r!   __classcell__ry   s   @r#   ri   ri      s    04(   > > % %.- / /
  r"   ri   c                   \   ^  \ rS rSrSrU 4S jr\S 5       r\S 5       r\S 5       r	Sr
U =r$ )BaseHdfsAndPosixUrl   zBase class designed for HDFS and POSIX file system URLs.

Attributes:
  scheme (ProviderPrefix): The cloud provider, must be either POSIX or HDFS.
  bucket_name (str): None.
  resource_name (str): The file/directory path.
  generation (str): None.
c           	      d  > [         [        U ]  5         Xl        SU l        SU l        U[        UR                  [        -   5      S U l	        U R                  [        R                  [        R                  4;  a#  [        R                  " SU R                  -  5      eU R                  R                  U R                   5      (       dj  ["        R$                  " SR'                  U R                  R(                  U R                  R                  [        U R                   U R                  5      5        gg)z*Initialize BaseHadoopAndPosixUrl instance.NUnrecognized scheme "%s"zE{} URLs typically start at the root directory. Did you mean: {}{}{}{})rl   r   rm   rn   ro   rp   rq   r   r   rv   r   r   r   r   InvalidUrlErrorrM   r4   r   r   rN   name)r3   rn   rD   ry   s      r#   rm   BaseHdfsAndPosixUrl.__init__   s    	
t-/KDDO#C(8)9 %: %; <D{{>//1D1DEE""#=#KLL((88	kkfkkkknn  	 9r"   c                     g)z@Returns the pathname separator character used by POSIX and HDFS.r$   r   r2   s    r#   r4   BaseHdfsAndPosixUrl.delimiter  s     r"   c                 l    SR                  U R                  R                  [        U R                  5      $ r   r   r2   s    r#   rD   BaseHdfsAndPosixUrl.url_string  r   r"   c                     U R                   $ r   rb   r2   s    r#   rG   *BaseHdfsAndPosixUrl.versionless_url_string  r   r"   r   )r   r   r   r   r   rm   rg   r4   rD   rG   r!   r   r   s   @r#   r   r      sI    ,   / /
  r"   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )HdfsUrli#  a  HDFS URL class providing parsing and convenience methods.

Attributes:
  scheme (ProviderPrefix): This will always be "hdfs" for HdfsUrl.
  bucket_name (str): None for HdfsUrl.
  resource_name (str): The file/directory path.
  generation (str): None for HdfsUrl.
c                 J   > [         [        U ]  [        R                  U5        g)z^Initialize HdfsUrl instance.

Args:
  url_string (str): The string representing the filepath.
N)rl   r   rm   r   r   r3   rD   ry   s     r#   rm   HdfsUrl.__init__-  s     
'4!."5"5zBr"   r   r   r   r   r   r   rm   r!   r   r   s   @r#   r   r   #  s    C Cr"   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )PosixFileSystemUrli6  a  URL class representing local and external POSIX file systems.

*Intended for transfer component.*

This class is different from FileUrl in many ways:
1) It supports only POSIX file systems (not Windows).
2) It can represent file systems on external machines.
3) It cannot run checks on the address of the URL like "exists" or "is_stream"
   because the URL may point to a different machine.
4) The class is intended for use in "agent transfers". This is when a
   Transfer Service customer installs agents on one machine or multiple and
   uses the agent software to upload and download files on the machine(s).

We implement this class in the "storage" component for convenience and
because the "storage" and "transfer" products are tightly coupled.

Attributes:
  scheme (ProviderPrefix): This will always be "posix" for PosixFileSystemUrl.
  bucket_name (None): N/A
  resource_name (str): The file/directory path.
  generation (None): N/A
c                 J   > [         [        U ]  [        R                  U5        g)zfInitialize PosixFileSystemUrl instance.

Args:
  url_string (str): Local or external POSIX file path.
N)rl   r   rm   r   r   r   s     r#   rm   PosixFileSystemUrl.__init__N  s     

d,^-A-A:Nr"   r   r   r   s   @r#   r   r   6  s    .O Or"   r   c                      ^  \ rS rSrSrSr  SU 4S jjr\SS j5       rS r	S r
\S 5       r\S	 5       r\S
 5       r\S 5       r\S 5       rS rS rS rS rSrU =r$ )CloudUrliW  ay  Cloud URL class providing parsing and convenience methods.

This class assists with usage and manipulation of an
(optionally wildcarded) cloud URL string.  Depending on the string
contents, this class represents a provider, bucket(s), or object(s).

This class operates only on strings.  No cloud storage API calls are
made from this class.

Attributes:
  scheme (ProviderPrefix): The cloud provider.
  bucket_name (str|None): The bucket name if url represents an object or
    bucket.
  resource_name (str|None): The object name if url represents a resource or
    prefix.
  generation (str|None): The generation number if present.
r$   c                 <  > [         [        U ]  5         U(       a  UOS U l        U(       a  UOS U l        U(       a  UOS U l        U(       a  UOS U l        U(       a  UOS U l        U(       a  [        U5      OS U l        U R                  5         U R                  5         g r&   )
rl   r   rm   rn   ro   rv   strrp   _validate_scheme_validate_resource_name)r3   rn   ro   rv   rp   ry   s        r#   rm   CloudUrl.__init__k  sq    	(D"$"&DK&1{tD"&DK&1{tD*7TD)3c*oDO  "r"   c                 L   [        U5      nU[        UR                  [        -   5      S nUR	                  S5      (       a*  [
        R                  " SR                  [        U5      5      eU[        R                  :X  a  [        R                  U5      OSnU(       aC  UR                  S5      n[        R                  U5      nU(       a  UR                  S5      OSnSn	O=UR                  [        5      u  pjn[!        X85      u  pUc  U(       a  [!        UU5      u  piU " X6X5      $ )aV  Parse the url string and return the storage url object.

Args:
  url_string (str): Cloud storage url of the form gs://bucket/object.
  is_bucket_gen_parsing_allowed (bool): If true, bucket generation parsing
    is allowed in the url.

Returns:
  CloudUrl object

Raises:
  InvalidUrlError: Raised if the url_string is not a valid cloud url.
Nr$   zOCloud URL scheme should be followed by colon and two slashes: "{}". Found: "{}"access_pointkey)_get_scheme_from_url_stringrq   r   r   rM   r   r   rN   r   r    _S3_MRAP_ARN_REGEX_ACCESS_POINTmatchgroup_S3_MRAP_ARN_REGEX_KEY	partitionCLOUD_URL_DELIMITERget_generation_number_from_name)clsrD   is_bucket_gen_parsing_allowedrn   schemeless_url_strings3_mrap_ap_matchro   s3_mrap_key_matchrv   rp   _s              r#   from_url_stringCloudUrl.from_url_stringw  s1    )4F 's6<<:J+J'K'MN'',,""#F#Z0	  ^&&& 	(--.CD 
  %**>:k0667LM,=

!
!%
(4  j '<&E&E
'#km #B
#m 
	#@ #B#

 vM>>r"   c                 r    U R                   [        ;  a#  [        R                  " SU R                   -  5      eg )Nr   )rn   VALID_CLOUD_SCHEMESr   r   r2   s    r#   r   CloudUrl._validate_scheme  s/    {{--""#=#KLL .r"   c                     U R                   S:X  d  U R                   S:X  a#  [        R                  " SU R                   -  5      eg )N.z..z(%s is an invalid root-level object name.)rv   r   r   r2   s    r#   r    CloudUrl._validate_resource_name  sF    S D$6$6$$>""#M#'#5#5$6 7 7 %?r"   c                     g)z@Cloud URLs cannot represent named pipes (FIFO) or other streams.Fr   r2   s    r#   r;   CloudUrl.is_stream       r"   c                     g)z,Cloud URLs cannot represent stdin or stdout.Fr   r2   s    r#   r@   CloudUrl.is_stdio  r   r"   c                 2   U R                   (       a{  U R                  5       (       a@  SR                  U R                  R                  [
        U R                  U R                   5      $ SR                  U R                  U R                   5      $ U R                  $ )Nz	{}{}{}#{}z{}#{})rp   	is_bucketrN   rn   r   r   ro   rG   r2   s    r#   rD   CloudUrl.url_string  sr    			!!KKOO	
 	
 ^^D77II(((r"   c                 >   U R                  5       (       a*  SR                  U R                  R                  [        5      $ U R                  5       (       a5  SR                  U R                  R                  [        U R                  5      $ U R                  5       (       a@  SR                  U R                  R                  [        U R                  U R                  5      $ SR                  U R                  R                  [        U R                  U R                  5      $ )Nz{}{}z{}{}{}/z
{}{}{}//{}z	{}{}{}/{})	is_providerrN   rn   r   r   r   ro   is_s3_mrap_bucketrv   r2   s    r#   rG   CloudUrl.versionless_url_string  s    ]]4;;,,.>?? 
		
++

-t/?/?  
			!	!  
++








	  	 r"   c                 F    U R                  5       (       a  gU R                  $ )Nz//)r   CLOUD_URL_DELIMr2   s    r#   r4   CloudUrl.delimiter  s     r"   c                 \    [        U R                  =(       a    U R                  (       + 5      $ r&   boolro   rv   r2   s    r#   r   CloudUrl.is_bucket  s!      ;););%;<<r"   c                 R    [        U R                  =(       a    U R                  5      $ r&   r   r2   s    r#   	is_objectCloudUrl.is_object  s      7T%7%788r"   c                 R    [        [        R                  U R                  5      5      $ r&   )r   r   r   ro   r2   s    r#   r   CloudUrl.is_s3_mrap_bucket  s    /55d6F6FGHHr"   c                 \    [        U R                  =(       a    U R                  (       + 5      $ r&   )r   rn   ro   r2   s    r#   r   CloudUrl.is_provider  s    4D$4$4 455r"   r   )NNNF)r   r   r   r   r   r   rm   classmethodr   r   r   rg   r;   r@   rD   rG   r4   r   r   r   r   r!   r   r   s   @r#   r   r   W  s    " /=A
# <? <?|M7
     ) )  0    =9I6 6r"   r   c                      ^  \ rS rSrSr     SU 4S jjr\S 5       r\S 5       rS r	\S 5       r
\S 5       r\S	 5       rS
rU =r$ )AzureUrli  a  CloudUrl subclass for Azure's unique blob storage URL structure.

Attributes:
  scheme (ProviderPrefix): AZURE (http) or AZURE_TLS (https).
  bucket_name (str|None): Storage container name in URL.
  resource_name (str|None): Storage resource name in URL.
  generation (str|None): Equivalent to Azure 'versionId'. Datetime string.
  snapshot (str|None): Similar to 'versionId'. URL parameter used to capture a
    specific version of a storage object. Datetime string.
  account (str): Account owning storage resource.
c                    > [         [        U ]  XX45        U(       a  UOS U l        U(       d  [        R
                  " S5      eX`l        g )Nz(Azure URLs must contain an account name.)rl   r   rm   snapshotr   r   account)r3   rn   ro   rv   rp   r   r   ry   s          r#   rm   AzureUrl.__init__  s@     
(D"] !)HdDM""#MNNLr"   c           	         [        U5      n[        R                  X5        U[        UR                  [
        -   5      S nUR                  [        5      u  pEnUR                  S5      u  n  nUR                  [        5      u  pn	U	R                  S5      u  pn[        R                  R                  U5      nU " UUU
SU;   a  US   S   OSSU;   a  US   S   US9$ SUS9$ )a  Parses the url string and return the storage URL object.

Args:
  url_string (str): Azure storage URL of the form:
    http://account.blob.core.windows.net/container/blob

Returns:
  AzureUrl object

Raises:
  InvalidUrlError: Raised if the url_string is not a valid cloud URL.
Nr   ?	versionIdr   r   )ro   rv   rp   r   r   )r   r   validate_url_stringrq   r   r   r   r   r	   parseparse_qs)r   rD   rn   r   hostnamer   path_and_paramsr   	containerblob_and_paramsblobparamsparams_dicts                r#   r   AzureUrl.from_url_string$  s    )4F  4 's6<<:J+J'K'LM
 $9#B#B$ H &&s+MGQ %4$=$=%!I/ &//4ODV ,,''/K+% {+A.+/$ Z(+  +/ r"   c                     U[         ;   $ r&   )VALID_HTTP_SCHEMES)r   rn   s     r#   is_valid_schemeAzureUrl.is_valid_schemeX  s    '''r"   c                     [         R                  U R                  5      (       d/  [        R                  " SR                  U R                  5      5      eg )NzInvalid Azure scheme "{}")r   r  rn   r   r   rN   r2   s    r#   r   AzureUrl._validate_scheme\  sD    ##DKK00""#>#E#E
++$   1r"   c                     [         R                  U5        [        U;   a  [         R                  U5      (       d%  [        R                  " SR                  U5      5      eg )NzInvalid Azure URL: "{}")r   r  AZURE_DOMAINr   r   rN   )r   rD   rn   s      r#   r   AzureUrl.validate_url_stringa  sK    V$J&8+C+CF+K+K""#<#C#CJ#OPP ,Lr"   c                 l   [        [        R                  R                  U R                  5      5      n0 nU R
                  (       a  U R
                  US'   U R                  (       a  U R                  US'   [        R                  R                  U5      US'   [        R                  R                  U5      $ )Nr   r      )	listr	   r   urlsplitrG   rp   r   	urlencode
urlunsplit)r3   	url_partsurl_parameterss      r#   rD   AzureUrl.url_stringg  s}    V\\**4+F+FGHIN$(OOn[!}}#'==nZ <<)).9IaL<<""9--r"   c                    U R                  5       (       a:  SR                  U R                  R                  [        U R
                  [        5      $ U R                  5       (       aE  SR                  U R                  R                  [        U R
                  [        U R                  5      $ SR                  U R                  R                  [        U R
                  [        U R                  U R                  5      $ )Nz	{}{}{}.{}z{}{}{}.{}/{}z{}{}{}.{}/{}/{})
r   rN   rn   r   r   r   r  r   ro   rv   r2   s    r#   rG   AzureUrl.versionless_url_strings  s     1 13C $l< <			""4;;#4#46F#'<<t?O?OQ Q##DKK$5$57G$(LL,$($4$4d6H6HJ Jr"   )r   r   )NNNNN)r   r   r   r   r   rm   r   r   r  r   r   rg   rD   rG   r!   r   r   s   @r#   r   r     s    
 $ 1 1f ( (
 Q Q
 	. 	. 	J 	Jr"   r   c                     U R                  [        5      nUS:X  a  [        R                  $ U SU R	                  5       nU[
        ;  a%  [        R                  " SR                  U5      5      e[        U5      $ )z)Returns scheme component of a URL string.r   zUnrecognized scheme "{}")	findr   r   r   lowerVALID_SCHEMESr   r   rN   )rD   end_scheme_idxprefix_strings      r#   r   r     sn    ??#34.rq0668MM)""
$
+
+M
:< <-((r"   c                 v   [        U 5      nU[        R                  :X  a  [        U 5      $ U[        R                  :X  a  [        U 5      $ U[        R                  :X  a  [        U 5      $ U[        ;   a  [        R                  U 5      $ U[        ;   a  [        R                  XS9$ [        R                  " S5      e)a6  Static factory function for creating a StorageUrl from a string.

Args:
  url_string (str): Cloud url or local filepath.
  is_bucket_gen_parsing_allowed (bool): If true, bucket generation parsing
      is allowed in the url.

Returns:
   StorageUrl object.

Raises:
  InvalidUrlError: Unrecognized URL scheme.
)r   zUnrecognized URL scheme.)r   r   r   ri   r   r   r   r   r  r   r   r   r   r   r   )rD   r   rn   s      r#   rO   rO     s     'z2&~""":~###j))~""":!!##J//""## $   	9::r"   c                 P    U R                  U5      (       a  U S[        U5      *  $ U $ )zStrip one delimiter char from the end.

Args:
  string (str): String on which the action needs to be performed.
  delimiter (str): A delimiter char.

Returns:
  str: String with trailing delimiter removed.
N)endswithrq   )stringr4   s     r#   rL   rL     s,     __Y"C	N?##	-r"   c                 p   U R                   R                  [        5      u  p#[        SR	                  UR
                  [        U5      5      nU R                  UR                  :X  a  U$ UR                  U R                  UR                  5      n[        SR	                  UR
                  [        U5      5      $ )a  Returns best-effort new StorageUrl based on original with new scheme.

This relies strongly on "storage_url_from_string" and will probably fail
for unusual formats like Azure URL. However, delimiter replacement is
handled for cases like converting Windows to cloud URLs.

Ignores versioning info embedded in URLs because each URL type tends to have
non-translatable syntax for its versions.

Args:
  original_url (StorageUrl): URL to convert.
  new_scheme (ProviderPrefix): Scheme to update URL with. probably fail or
    have unexpected results because URL formats tend to have non-translatable
    versioning syntax.

Returns:
  StorageUrl with updated scheme and best-effort transformation.
rK   )rG   r~   r   rO   rN   r   r4   rt   )original_url
new_schemer   old_url_string_no_schemeunprocessed_new_url*old_url_string_no_scheme_correct_delimiters         r#   switch_schemer+    s    & !- C C I I!!/(*B1D E 2<<</G/O/O1;;0=,	 (0"2 
3 3r"   c                 N    [         U ;  a  U $ U R                  [         5      u    pU$ )z7Removes ProviderPrefix or other scheme from URL string.)r   r   )rD   r   schemeless_urls      r#   remove_schemer.    s,    Z'#--.>?!Q	r"   c                 b    [         U ;   a  U $ [        R                  R                  [         -   U -   $ )z;Returns a string with gs:// prefixed, if URL has no scheme.)r   r   r   r   rb   s    r#   add_gcs_scheme_if_missingr0    s-    #				!	!$4	4z	AAr"   c                    U(       d  gU [         R                  :X  a	  [        nSnO!U [         R                  :X  a	  [        nSnOUS4$ UR                  U5      nUb%  UR                  S5      nUR                  U5      nXV4$ US4$ )ag  Parses a cloud storage resource name (bucket or object) into its components.

Args:
    scheme (str): Scheme of URL such as gs and s3.
    resource_name (str): Name of the resource (bucket or object) in the format
      'name' or 'name#generation'.

Returns:
    A tuple containing the parsed resource name and generation number (or None
    if not present).
)NNrp   
version_idNr   )r   r   GS_GENERATION_REGEXr    S3_VERSION_REGEXr   r   )rn   rv   pattern_to_match
group_namegeneration_matchr   rp   s          r#   r   r     s      
~!!!*J"""'J$%++M:!!!&)D!''
3J		r"   r   )9r   
__future__r   r   r   re   enumr'   rer*   "googlecloudsdk.command_lib.storager   googlecloudsdk.corer   googlecloudsdk.core.utilr   six	six.movesr	   r   TEMPORARY_FILE_SUFFIXEnumr   	frozensetr   r    r   r   r   r  r   r  r   r  compiler3  r4  r   r   r-   with_metaclassABCMetar/   ri   r   r   r   r   r   r   rO   r   rL   r+  r.  r0  r   )rn   s   0r#   <module>rF     s    1 &  ' 
  	 	  5 # . 
   ! TYY   !3!3^5F5F GH  3 3^5I5IJK nEnF<<nEF & jj!HI ::AB  #%**B# 
 $9: G?##CKK0 ?D_j _D1* 1hC! C&O, OBk6z k6\xJx xJv);> ,4+C+C 3DB"s Fs    F