/* Ċ Ġ* ĠUnless Ġexplicitly Ġstated Ġotherwise Ġall Ġfiles Ġin Ġthis Ġrepository Ġare Ġlicensed Ġunder Ġthe ĠApache ĠLicense ĠVersion Ġ 2 . 0 . Ċ Ġ* ĠThis Ġproduct Ġincludes Ġsoftware Ġdeveloped Ġat ĠDat adog Ġ( https :// www . datadog hq . com /). Ċ Ġ* ĠCopyright Ġ 2 0 1 6 - Present ĠDat adog , ĠInc . Ċ Ġ*/ Ċ Ċ package Ġcom . datadog . android . core . internal . constraints Ċ Ċ import Ġcom . datadog . android . core . internal . utils . dev Logger Ċ import Ġcom . datadog . android . rum . model . View Event Ċ import Ġjava . util . Locale Ċ Ċ internal Ġtype alias ĠString Transform Ġ= Ġ( String ) Ġ-> ĠString ? Ċ Ċ internal Ġclass ĠDat adog Data Constraints Ġ: ĠData Constraints Ġ{ ĊĊĠĠĠ Ġ// Ġregion ĠData Constraints ĊĊĠĠĠ Ġoverride Ġfun Ġvalidate Tags ( tags : ĠList < String >): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconverted Tags Ġ= Ġtags . map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtag Ġ= Ġconvert Tag ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( tag Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdev Logger . e ("\" $ it \" Ġis Ġan Ġinvalid Ġtag , Ġand Ġwas Ġignored .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( tag Ġ!= Ġit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdev Logger . w (" tag Ġ\"$ it \" Ġwas Ġmodified Ġto Ġ\"$ tag \" Ġto Ġmatch Ġour Ġconstraints .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtag ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdiscarded Count Ġ= Ġconverted Tags . size Ġ- ĠMAX _ TAG _ COUNT ĊĠĠĠĠĠĠĠ Ġif Ġ( dis carded Count Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdev Logger . w (" too Ġmany Ġtags Ġwere Ġadded , Ġ$ dis carded Count Ġhad Ġto Ġbe Ġdiscarded .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġconverted Tags . take ( MAX _ TAG _ COUNT ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvalidate Attributes ( ĊĠĠĠĠĠĠĠ Ġattributes : ĠMap < String , ĠAny ? >, ĊĠĠĠĠĠĠĠ Ġkey Prefix : ĠString ?, ĊĠĠĠĠĠĠĠ Ġattributes GroupName : ĠString ? ĊĠĠĠ Ġ): ĠMap < String , ĠAny ?> Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// Ġprefix Ġ= Ġ" a . b " Ġ=> Ġdot Count Ġ= Ġ 1 + 1 Ġ(" a . b ." Ġ+ Ġkey ) ĊĠĠĠĠĠĠĠ Ġval Ġprefix Dot Count Ġ= Ġkey Prefix ?. let Ġ{ Ġit . count Ġ{ Ġcharacter Ġ-> Ġcharacter Ġ== Ġ'.' Ġ} Ġ+ Ġ 1 Ġ} Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġconverted Attributes Ġ= Ġattributes . map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġneed Ġthis Ġin Ġcase Ġthe Ġattributes Ġare Ġadded Ġfrom ĠJAVA Ġcode Ġand Ġa Ġnull Ġkey Ġmay Ġbe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġpassed . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" S ENSE LESS _ COMP AR IS ON ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . key Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdev Logger . e ("\" $ it \" Ġis Ġan Ġinvalid Ġattribute , Ġand Ġwas Ġignored .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġconvert Attribute Key ( it . key , Ġprefix Dot Count ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( key Ġ!= Ġit . key ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdev Logger . w ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Key Ġ\" ${ it . key }\" Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" was Ġmodified Ġto Ġ\"$ key \" Ġto Ġmatch Ġour Ġconstraints ." ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Ġto Ġit . value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdiscarded Count Ġ= Ġconverted Attributes . size Ġ- ĠMAX _ ATTR _ COUNT ĊĠĠĠĠĠĠĠ Ġif Ġ( dis carded Count Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwarning Message Ġ= Ġresolve Dis carded Attrs Warning ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġattributes GroupName , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdiscarded Count ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdev Logger . w ( warning Message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġconverted Attributes . take ( MAX _ ATTR _ COUNT ). toMap () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvalidate Event ( rum Event : ĠAny ): ĠAny Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( rum Event Ġis ĠView Event ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcustom Tim ings Ġ= Ġr um Event . view . custom Tim ings ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadditional Properties Ġ= Ġit . additional Properties . map Keys Ġ{ Ġentry Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsanitized Key Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . key . replace ( Regex ("[ ^ a - zA - Z 0 - 9 \\ - _. @ $ ] "), Ġ"_ ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sanit ized Key Ġ!= Ġentry . key ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdev Logger . w ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCUSTOM _ TIM ING _ KEY _ REPL AC ED _ WARNING . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLocale . US , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . key , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsanitized Key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsanitized Key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġr um Event . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġview Ġ= Ġr um Event . view . copy ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcustom Tim ings Ġ= Ġcustom Tim ings ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġr um Event ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġresolve Dis carded Attrs Warning ( ĊĠĠĠĠĠĠĠ Ġattributes GroupName : ĠString ?, ĊĠĠĠĠĠĠĠ Ġdiscarded Count : ĠInt ĊĠĠĠ Ġ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( attributes GroupName Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Too Ġmany Ġattributes Ġwere Ġadded Ġfor Ġ[$ attributes GroupName ], Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ dis carded Count Ġhad Ġto Ġbe Ġdiscarded ." ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Too Ġmany Ġattributes Ġwere Ġadded , Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ dis carded Count Ġhad Ġto Ġbe Ġdiscarded ." ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġend region ĊĊĠĠĠ Ġ// Ġregion ĠInternal / Tag ĊĊĠĠĠ Ġprivate Ġval Ġtag Transforms Ġ= ĠlistOf < String Transform >( ĊĠĠĠĠĠĠĠ Ġ// ĠTags Ġmust Ġbe Ġlowercase ĊĠĠĠĠĠĠĠ Ġ{ Ġit . toLowerCase ( Locale . US ) Ġ}, ĊĠĠĠĠĠĠĠ Ġ// ĠTags Ġmust Ġstart Ġwith Ġa Ġletter ĊĠĠĠĠĠĠĠ Ġ{ Ġif Ġ( it . get ( 0 ) Ġ! in Ġ' a ' .. ' z ') Ġnull Ġelse Ġit Ġ}, ĊĠĠĠĠĠĠĠ Ġ// ĠTags Ġconvert Ġillegal Ġcharacters Ġto Ġunders code ĊĠĠĠĠĠĠĠ Ġ{ Ġit . replace ( Regex ("[ ^ a - z 0 - 9 _: ./ - ] "), Ġ"_ ") Ġ}, ĊĠĠĠĠĠĠĠ Ġ// ĠTags Ġcannot Ġend Ġwith Ġa Ġcolon ĊĠĠĠĠĠĠĠ Ġ{ Ġif Ġ( it . endsWith (': ')) Ġit . substring ( 0 , Ġit . last Index ) Ġelse Ġit Ġ}, ĊĠĠĠĠĠĠĠ Ġ// ĠTags Ġcan Ġbe Ġup Ġto Ġ 2 0 0 Ġcharacters Ġlong ĊĠĠĠĠĠĠĠ Ġ{ Ġif Ġ( it . length Ġ> ĠMAX _ TAG _ LENGTH ) Ġit . substring ( 0 , ĠMAX _ TAG _ LENGTH ) Ġelse Ġit Ġ}, ĊĠĠĠĠĠĠĠ Ġ// ĠDis miss Ġtags Ġwith Ġreserved Ġkeys ĊĠĠĠĠĠĠĠ Ġ{ Ġif Ġ( is Key Reserved ( it )) Ġnull Ġelse Ġit Ġ} ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun Ġconvert Tag ( raw Tag : ĠString ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtag Transforms . fold ( raw Tag ) Ġ{ Ġtag , Ġtransform Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( tag Ġ== Ġnull ) Ġnull Ġelse Ġtransform . invoke ( tag ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Key Reserved ( tag : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfirst Colon Ġ= Ġtag . indexOf (': ') ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( first Colon Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġtag . substring ( 0 , Ġfirst Colon ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Ġin Ġreserved Tag Keys ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġend region ĊĊĠĠĠ Ġ// Ġregion ĠInternal / Attribute ĊĊĠĠĠ Ġprivate Ġfun Ġconvert Attribute Key ( raw Key : ĠString , Ġprefix Dot Count : ĠInt ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġdot Count Ġ= Ġprefix Dot Count ĊĠĠĠĠĠĠĠ Ġval Ġmapped Ġ= Ġraw Key . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== Ġ'.') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdot Count ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( dot Count Ġ> ĠMAX _ DEPTH _ LEVEL ) Ġ'_' Ġelse Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġit ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠString ( mapped . toCharArray ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġend region ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ TAG _ LENGTH Ġ= Ġ 2 0 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ TAG _ COUNT Ġ= Ġ 1 0 0 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ ATTR _ COUNT Ġ= Ġ 1 2 8 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ DEPTH _ LEVEL Ġ= Ġ 9 ĊĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠCUSTOM _ TIM ING _ KEY _ REPL AC ED _ WARNING Ġ= Ġ" Invalid Ġtiming Ġname : Ġ% s ," Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġsanitized Ġto : Ġ% s " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġreserved Tag Keys Ġ= Ġset Of ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" host ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" device ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" source ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" service " ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ } Ċ