descriptor_unittest.cc 293 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // This file makes extensive use of RFC 3092. :)
  35. #include <limits>
  36. #include <memory>
  37. #include <vector>
  38. #include <google/protobuf/compiler/importer.h>
  39. #include <google/protobuf/compiler/parser.h>
  40. #include <google/protobuf/unittest.pb.h>
  41. #include <google/protobuf/unittest_custom_options.pb.h>
  42. #include <google/protobuf/stubs/common.h>
  43. #include <google/protobuf/stubs/logging.h>
  44. #include <google/protobuf/stubs/logging.h>
  45. #include <google/protobuf/stubs/stringprintf.h>
  46. #include <google/protobuf/unittest_lazy_dependencies.pb.h>
  47. #include <google/protobuf/unittest_proto3_arena.pb.h>
  48. #include <google/protobuf/io/tokenizer.h>
  49. #include <google/protobuf/io/zero_copy_stream_impl.h>
  50. #include <google/protobuf/descriptor.pb.h>
  51. #include <google/protobuf/descriptor.h>
  52. #include <google/protobuf/descriptor_database.h>
  53. #include <google/protobuf/dynamic_message.h>
  54. #include <google/protobuf/text_format.h>
  55. #include <google/protobuf/stubs/strutil.h>
  56. #include <google/protobuf/testing/googletest.h>
  57. #include <gtest/gtest.h>
  58. #include <google/protobuf/stubs/substitute.h>
  59. #include <google/protobuf/port_def.inc>
  60. namespace google {
  61. namespace protobuf {
  62. // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
  63. namespace descriptor_unittest {
  64. // Some helpers to make assembling descriptors faster.
  65. DescriptorProto* AddMessage(FileDescriptorProto* file,
  66. const std::string& name) {
  67. DescriptorProto* result = file->add_message_type();
  68. result->set_name(name);
  69. return result;
  70. }
  71. DescriptorProto* AddNestedMessage(DescriptorProto* parent,
  72. const std::string& name) {
  73. DescriptorProto* result = parent->add_nested_type();
  74. result->set_name(name);
  75. return result;
  76. }
  77. EnumDescriptorProto* AddEnum(FileDescriptorProto* file,
  78. const std::string& name) {
  79. EnumDescriptorProto* result = file->add_enum_type();
  80. result->set_name(name);
  81. return result;
  82. }
  83. EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
  84. const std::string& name) {
  85. EnumDescriptorProto* result = parent->add_enum_type();
  86. result->set_name(name);
  87. return result;
  88. }
  89. ServiceDescriptorProto* AddService(FileDescriptorProto* file,
  90. const std::string& name) {
  91. ServiceDescriptorProto* result = file->add_service();
  92. result->set_name(name);
  93. return result;
  94. }
  95. FieldDescriptorProto* AddField(DescriptorProto* parent, const std::string& name,
  96. int number, FieldDescriptorProto::Label label,
  97. FieldDescriptorProto::Type type) {
  98. FieldDescriptorProto* result = parent->add_field();
  99. result->set_name(name);
  100. result->set_number(number);
  101. result->set_label(label);
  102. result->set_type(type);
  103. return result;
  104. }
  105. FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
  106. const std::string& extendee,
  107. const std::string& name, int number,
  108. FieldDescriptorProto::Label label,
  109. FieldDescriptorProto::Type type) {
  110. FieldDescriptorProto* result = file->add_extension();
  111. result->set_name(name);
  112. result->set_number(number);
  113. result->set_label(label);
  114. result->set_type(type);
  115. result->set_extendee(extendee);
  116. return result;
  117. }
  118. FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
  119. const std::string& extendee,
  120. const std::string& name, int number,
  121. FieldDescriptorProto::Label label,
  122. FieldDescriptorProto::Type type) {
  123. FieldDescriptorProto* result = parent->add_extension();
  124. result->set_name(name);
  125. result->set_number(number);
  126. result->set_label(label);
  127. result->set_type(type);
  128. result->set_extendee(extendee);
  129. return result;
  130. }
  131. DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
  132. int start, int end) {
  133. DescriptorProto::ExtensionRange* result = parent->add_extension_range();
  134. result->set_start(start);
  135. result->set_end(end);
  136. return result;
  137. }
  138. DescriptorProto::ReservedRange* AddReservedRange(DescriptorProto* parent,
  139. int start, int end) {
  140. DescriptorProto::ReservedRange* result = parent->add_reserved_range();
  141. result->set_start(start);
  142. result->set_end(end);
  143. return result;
  144. }
  145. EnumDescriptorProto::EnumReservedRange* AddReservedRange(
  146. EnumDescriptorProto* parent, int start, int end) {
  147. EnumDescriptorProto::EnumReservedRange* result = parent->add_reserved_range();
  148. result->set_start(start);
  149. result->set_end(end);
  150. return result;
  151. }
  152. EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
  153. const std::string& name, int number) {
  154. EnumValueDescriptorProto* result = enum_proto->add_value();
  155. result->set_name(name);
  156. result->set_number(number);
  157. return result;
  158. }
  159. MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
  160. const std::string& name,
  161. const std::string& input_type,
  162. const std::string& output_type) {
  163. MethodDescriptorProto* result = service->add_method();
  164. result->set_name(name);
  165. result->set_input_type(input_type);
  166. result->set_output_type(output_type);
  167. return result;
  168. }
  169. // Empty enums technically aren't allowed. We need to insert a dummy value
  170. // into them.
  171. void AddEmptyEnum(FileDescriptorProto* file, const std::string& name) {
  172. AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
  173. }
  174. class MockErrorCollector : public DescriptorPool::ErrorCollector {
  175. public:
  176. MockErrorCollector() {}
  177. ~MockErrorCollector() {}
  178. std::string text_;
  179. std::string warning_text_;
  180. // implements ErrorCollector ---------------------------------------
  181. void AddError(const std::string& filename, const std::string& element_name,
  182. const Message* descriptor, ErrorLocation location,
  183. const std::string& message) {
  184. const char* location_name = nullptr;
  185. switch (location) {
  186. case NAME:
  187. location_name = "NAME";
  188. break;
  189. case NUMBER:
  190. location_name = "NUMBER";
  191. break;
  192. case TYPE:
  193. location_name = "TYPE";
  194. break;
  195. case EXTENDEE:
  196. location_name = "EXTENDEE";
  197. break;
  198. case DEFAULT_VALUE:
  199. location_name = "DEFAULT_VALUE";
  200. break;
  201. case OPTION_NAME:
  202. location_name = "OPTION_NAME";
  203. break;
  204. case OPTION_VALUE:
  205. location_name = "OPTION_VALUE";
  206. break;
  207. case INPUT_TYPE:
  208. location_name = "INPUT_TYPE";
  209. break;
  210. case OUTPUT_TYPE:
  211. location_name = "OUTPUT_TYPE";
  212. break;
  213. case IMPORT:
  214. location_name = "IMPORT";
  215. break;
  216. case OTHER:
  217. location_name = "OTHER";
  218. break;
  219. }
  220. strings::SubstituteAndAppend(&text_, "$0: $1: $2: $3\n", filename,
  221. element_name, location_name, message);
  222. }
  223. // implements ErrorCollector ---------------------------------------
  224. void AddWarning(const std::string& filename, const std::string& element_name,
  225. const Message* descriptor, ErrorLocation location,
  226. const std::string& message) {
  227. const char* location_name = nullptr;
  228. switch (location) {
  229. case NAME:
  230. location_name = "NAME";
  231. break;
  232. case NUMBER:
  233. location_name = "NUMBER";
  234. break;
  235. case TYPE:
  236. location_name = "TYPE";
  237. break;
  238. case EXTENDEE:
  239. location_name = "EXTENDEE";
  240. break;
  241. case DEFAULT_VALUE:
  242. location_name = "DEFAULT_VALUE";
  243. break;
  244. case OPTION_NAME:
  245. location_name = "OPTION_NAME";
  246. break;
  247. case OPTION_VALUE:
  248. location_name = "OPTION_VALUE";
  249. break;
  250. case INPUT_TYPE:
  251. location_name = "INPUT_TYPE";
  252. break;
  253. case OUTPUT_TYPE:
  254. location_name = "OUTPUT_TYPE";
  255. break;
  256. case IMPORT:
  257. location_name = "IMPORT";
  258. break;
  259. case OTHER:
  260. location_name = "OTHER";
  261. break;
  262. }
  263. strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n",
  264. filename, element_name, location_name,
  265. message);
  266. }
  267. };
  268. // ===================================================================
  269. // Test simple files.
  270. class FileDescriptorTest : public testing::Test {
  271. protected:
  272. virtual void SetUp() {
  273. // Build descriptors for the following definitions:
  274. //
  275. // // in "foo.proto"
  276. // message FooMessage { extensions 1; }
  277. // enum FooEnum {FOO_ENUM_VALUE = 1;}
  278. // service FooService {}
  279. // extend FooMessage { optional int32 foo_extension = 1; }
  280. //
  281. // // in "bar.proto"
  282. // package bar_package;
  283. // message BarMessage { extensions 1; }
  284. // enum BarEnum {BAR_ENUM_VALUE = 1;}
  285. // service BarService {}
  286. // extend BarMessage { optional int32 bar_extension = 1; }
  287. //
  288. // Also, we have an empty file "baz.proto". This file's purpose is to
  289. // make sure that even though it has the same package as foo.proto,
  290. // searching it for members of foo.proto won't work.
  291. FileDescriptorProto foo_file;
  292. foo_file.set_name("foo.proto");
  293. AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
  294. AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
  295. AddService(&foo_file, "FooService");
  296. AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
  297. FieldDescriptorProto::LABEL_OPTIONAL,
  298. FieldDescriptorProto::TYPE_INT32);
  299. FileDescriptorProto bar_file;
  300. bar_file.set_name("bar.proto");
  301. bar_file.set_package("bar_package");
  302. bar_file.add_dependency("foo.proto");
  303. AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
  304. AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
  305. AddService(&bar_file, "BarService");
  306. AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
  307. FieldDescriptorProto::LABEL_OPTIONAL,
  308. FieldDescriptorProto::TYPE_INT32);
  309. FileDescriptorProto baz_file;
  310. baz_file.set_name("baz.proto");
  311. // Build the descriptors and get the pointers.
  312. foo_file_ = pool_.BuildFile(foo_file);
  313. ASSERT_TRUE(foo_file_ != nullptr);
  314. bar_file_ = pool_.BuildFile(bar_file);
  315. ASSERT_TRUE(bar_file_ != nullptr);
  316. baz_file_ = pool_.BuildFile(baz_file);
  317. ASSERT_TRUE(baz_file_ != nullptr);
  318. ASSERT_EQ(1, foo_file_->message_type_count());
  319. foo_message_ = foo_file_->message_type(0);
  320. ASSERT_EQ(1, foo_file_->enum_type_count());
  321. foo_enum_ = foo_file_->enum_type(0);
  322. ASSERT_EQ(1, foo_enum_->value_count());
  323. foo_enum_value_ = foo_enum_->value(0);
  324. ASSERT_EQ(1, foo_file_->service_count());
  325. foo_service_ = foo_file_->service(0);
  326. ASSERT_EQ(1, foo_file_->extension_count());
  327. foo_extension_ = foo_file_->extension(0);
  328. ASSERT_EQ(1, bar_file_->message_type_count());
  329. bar_message_ = bar_file_->message_type(0);
  330. ASSERT_EQ(1, bar_file_->enum_type_count());
  331. bar_enum_ = bar_file_->enum_type(0);
  332. ASSERT_EQ(1, bar_enum_->value_count());
  333. bar_enum_value_ = bar_enum_->value(0);
  334. ASSERT_EQ(1, bar_file_->service_count());
  335. bar_service_ = bar_file_->service(0);
  336. ASSERT_EQ(1, bar_file_->extension_count());
  337. bar_extension_ = bar_file_->extension(0);
  338. }
  339. DescriptorPool pool_;
  340. const FileDescriptor* foo_file_;
  341. const FileDescriptor* bar_file_;
  342. const FileDescriptor* baz_file_;
  343. const Descriptor* foo_message_;
  344. const EnumDescriptor* foo_enum_;
  345. const EnumValueDescriptor* foo_enum_value_;
  346. const ServiceDescriptor* foo_service_;
  347. const FieldDescriptor* foo_extension_;
  348. const Descriptor* bar_message_;
  349. const EnumDescriptor* bar_enum_;
  350. const EnumValueDescriptor* bar_enum_value_;
  351. const ServiceDescriptor* bar_service_;
  352. const FieldDescriptor* bar_extension_;
  353. };
  354. TEST_F(FileDescriptorTest, Name) {
  355. EXPECT_EQ("foo.proto", foo_file_->name());
  356. EXPECT_EQ("bar.proto", bar_file_->name());
  357. EXPECT_EQ("baz.proto", baz_file_->name());
  358. }
  359. TEST_F(FileDescriptorTest, Package) {
  360. EXPECT_EQ("", foo_file_->package());
  361. EXPECT_EQ("bar_package", bar_file_->package());
  362. }
  363. TEST_F(FileDescriptorTest, Dependencies) {
  364. EXPECT_EQ(0, foo_file_->dependency_count());
  365. EXPECT_EQ(1, bar_file_->dependency_count());
  366. EXPECT_EQ(foo_file_, bar_file_->dependency(0));
  367. }
  368. TEST_F(FileDescriptorTest, FindMessageTypeByName) {
  369. EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
  370. EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
  371. EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == nullptr);
  372. EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == nullptr);
  373. EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == nullptr);
  374. EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == nullptr);
  375. EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == nullptr);
  376. }
  377. TEST_F(FileDescriptorTest, FindEnumTypeByName) {
  378. EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
  379. EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
  380. EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == nullptr);
  381. EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == nullptr);
  382. EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == nullptr);
  383. EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == nullptr);
  384. EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == nullptr);
  385. }
  386. TEST_F(FileDescriptorTest, FindEnumValueByName) {
  387. EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
  388. EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
  389. EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == nullptr);
  390. EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == nullptr);
  391. EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == nullptr);
  392. EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
  393. EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == nullptr);
  394. }
  395. TEST_F(FileDescriptorTest, FindServiceByName) {
  396. EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
  397. EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
  398. EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == nullptr);
  399. EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == nullptr);
  400. EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == nullptr);
  401. EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == nullptr);
  402. EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == nullptr);
  403. }
  404. TEST_F(FileDescriptorTest, FindExtensionByName) {
  405. EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
  406. EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
  407. EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == nullptr);
  408. EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == nullptr);
  409. EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == nullptr);
  410. EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == nullptr);
  411. EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == nullptr);
  412. }
  413. TEST_F(FileDescriptorTest, FindExtensionByNumber) {
  414. EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
  415. EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
  416. EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == nullptr);
  417. }
  418. TEST_F(FileDescriptorTest, BuildAgain) {
  419. // Test that if we call BuildFile again on the same input we get the same
  420. // FileDescriptor back.
  421. FileDescriptorProto file;
  422. foo_file_->CopyTo(&file);
  423. EXPECT_EQ(foo_file_, pool_.BuildFile(file));
  424. // But if we change the file then it won't work.
  425. file.set_package("some.other.package");
  426. EXPECT_TRUE(pool_.BuildFile(file) == nullptr);
  427. }
  428. TEST_F(FileDescriptorTest, BuildAgainWithSyntax) {
  429. // Test that if we call BuildFile again on the same input we get the same
  430. // FileDescriptor back even if syntax param is specified.
  431. FileDescriptorProto proto_syntax2;
  432. proto_syntax2.set_name("foo_syntax2");
  433. proto_syntax2.set_syntax("proto2");
  434. const FileDescriptor* proto2_descriptor = pool_.BuildFile(proto_syntax2);
  435. EXPECT_TRUE(proto2_descriptor != nullptr);
  436. EXPECT_EQ(proto2_descriptor, pool_.BuildFile(proto_syntax2));
  437. FileDescriptorProto implicit_proto2;
  438. implicit_proto2.set_name("foo_implicit_syntax2");
  439. const FileDescriptor* implicit_proto2_descriptor =
  440. pool_.BuildFile(implicit_proto2);
  441. EXPECT_TRUE(implicit_proto2_descriptor != nullptr);
  442. // We get the same FileDescriptor back if syntax param is explicitly
  443. // specified.
  444. implicit_proto2.set_syntax("proto2");
  445. EXPECT_EQ(implicit_proto2_descriptor, pool_.BuildFile(implicit_proto2));
  446. FileDescriptorProto proto_syntax3;
  447. proto_syntax3.set_name("foo_syntax3");
  448. proto_syntax3.set_syntax("proto3");
  449. const FileDescriptor* proto3_descriptor = pool_.BuildFile(proto_syntax3);
  450. EXPECT_TRUE(proto3_descriptor != nullptr);
  451. EXPECT_EQ(proto3_descriptor, pool_.BuildFile(proto_syntax3));
  452. }
  453. TEST_F(FileDescriptorTest, Syntax) {
  454. FileDescriptorProto proto;
  455. proto.set_name("foo");
  456. // Enable the test when we also populate the syntax for proto2.
  457. #if 0
  458. {
  459. proto.set_syntax("proto2");
  460. DescriptorPool pool;
  461. const FileDescriptor* file = pool.BuildFile(proto);
  462. EXPECT_TRUE(file != nullptr);
  463. EXPECT_EQ(FileDescriptor::SYNTAX_PROTO2, file->syntax());
  464. FileDescriptorProto other;
  465. file->CopyTo(&other);
  466. EXPECT_EQ("proto2", other.syntax());
  467. }
  468. #endif
  469. {
  470. proto.set_syntax("proto3");
  471. DescriptorPool pool;
  472. const FileDescriptor* file = pool.BuildFile(proto);
  473. EXPECT_TRUE(file != nullptr);
  474. EXPECT_EQ(FileDescriptor::SYNTAX_PROTO3, file->syntax());
  475. FileDescriptorProto other;
  476. file->CopyTo(&other);
  477. EXPECT_EQ("proto3", other.syntax());
  478. }
  479. }
  480. void ExtractDebugString(
  481. const FileDescriptor* file, std::set<std::string>* visited,
  482. std::vector<std::pair<std::string, std::string>>* debug_strings) {
  483. if (!visited->insert(file->name()).second) {
  484. return;
  485. }
  486. for (int i = 0; i < file->dependency_count(); ++i) {
  487. ExtractDebugString(file->dependency(i), visited, debug_strings);
  488. }
  489. debug_strings->push_back(std::make_pair(file->name(), file->DebugString()));
  490. }
  491. class SimpleErrorCollector : public io::ErrorCollector {
  492. public:
  493. // implements ErrorCollector ---------------------------------------
  494. void AddError(int line, int column, const std::string& message) {
  495. last_error_ = StringPrintf("%d:%d:", line, column) + message;
  496. }
  497. const std::string& last_error() { return last_error_; }
  498. private:
  499. std::string last_error_;
  500. };
  501. // Test that the result of FileDescriptor::DebugString() can be used to create
  502. // the original descriptors.
  503. TEST_F(FileDescriptorTest, DebugStringRoundTrip) {
  504. std::set<std::string> visited;
  505. std::vector<std::pair<std::string, std::string>> debug_strings;
  506. ExtractDebugString(protobuf_unittest::TestAllTypes::descriptor()->file(),
  507. &visited, &debug_strings);
  508. ExtractDebugString(
  509. protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file(),
  510. &visited, &debug_strings);
  511. ExtractDebugString(proto3_arena_unittest::TestAllTypes::descriptor()->file(),
  512. &visited, &debug_strings);
  513. ASSERT_GE(debug_strings.size(), 3);
  514. DescriptorPool pool;
  515. for (int i = 0; i < debug_strings.size(); ++i) {
  516. const std::string& name = debug_strings[i].first;
  517. const std::string& content = debug_strings[i].second;
  518. io::ArrayInputStream input_stream(content.data(), content.size());
  519. SimpleErrorCollector error_collector;
  520. io::Tokenizer tokenizer(&input_stream, &error_collector);
  521. compiler::Parser parser;
  522. parser.RecordErrorsTo(&error_collector);
  523. FileDescriptorProto proto;
  524. ASSERT_TRUE(parser.Parse(&tokenizer, &proto))
  525. << error_collector.last_error() << "\n"
  526. << content;
  527. ASSERT_EQ("", error_collector.last_error());
  528. proto.set_name(name);
  529. const FileDescriptor* descriptor = pool.BuildFile(proto);
  530. ASSERT_TRUE(descriptor != nullptr) << proto.DebugString();
  531. EXPECT_EQ(content, descriptor->DebugString());
  532. }
  533. }
  534. // ===================================================================
  535. // Test simple flat messages and fields.
  536. class DescriptorTest : public testing::Test {
  537. protected:
  538. virtual void SetUp() {
  539. // Build descriptors for the following definitions:
  540. //
  541. // // in "foo.proto"
  542. // message TestForeign {}
  543. // enum TestEnum {}
  544. //
  545. // message TestMessage {
  546. // required string foo = 1;
  547. // optional TestEnum bar = 6;
  548. // repeated TestForeign baz = 500000000;
  549. // optional group qux = 15 {}
  550. // }
  551. //
  552. // // in "bar.proto"
  553. // package corge.grault;
  554. // message TestMessage2 {
  555. // required string foo = 1;
  556. // required string bar = 2;
  557. // required string quux = 6;
  558. // }
  559. //
  560. // // in "map.proto"
  561. // message TestMessage3 {
  562. // map<int32, int32> map_int32_int32 = 1;
  563. // }
  564. //
  565. // // in "json.proto"
  566. // message TestMessage4 {
  567. // optional int32 field_name1 = 1;
  568. // optional int32 fieldName2 = 2;
  569. // optional int32 FieldName3 = 3;
  570. // optional int32 _field_name4 = 4;
  571. // optional int32 FIELD_NAME5 = 5;
  572. // optional int32 field_name6 = 6 [json_name = "@type"];
  573. // }
  574. //
  575. // We cheat and use TestForeign as the type for qux rather than create
  576. // an actual nested type.
  577. //
  578. // Since all primitive types (including string) use the same building
  579. // code, there's no need to test each one individually.
  580. //
  581. // TestMessage2 is primarily here to test FindFieldByName and friends.
  582. // All messages created from the same DescriptorPool share the same lookup
  583. // table, so we need to insure that they don't interfere.
  584. FileDescriptorProto foo_file;
  585. foo_file.set_name("foo.proto");
  586. AddMessage(&foo_file, "TestForeign");
  587. AddEmptyEnum(&foo_file, "TestEnum");
  588. DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
  589. AddField(message, "foo", 1, FieldDescriptorProto::LABEL_REQUIRED,
  590. FieldDescriptorProto::TYPE_STRING);
  591. AddField(message, "bar", 6, FieldDescriptorProto::LABEL_OPTIONAL,
  592. FieldDescriptorProto::TYPE_ENUM)
  593. ->set_type_name("TestEnum");
  594. AddField(message, "baz", 500000000, FieldDescriptorProto::LABEL_REPEATED,
  595. FieldDescriptorProto::TYPE_MESSAGE)
  596. ->set_type_name("TestForeign");
  597. AddField(message, "qux", 15, FieldDescriptorProto::LABEL_OPTIONAL,
  598. FieldDescriptorProto::TYPE_GROUP)
  599. ->set_type_name("TestForeign");
  600. FileDescriptorProto bar_file;
  601. bar_file.set_name("bar.proto");
  602. bar_file.set_package("corge.grault");
  603. DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
  604. AddField(message2, "foo", 1, FieldDescriptorProto::LABEL_REQUIRED,
  605. FieldDescriptorProto::TYPE_STRING);
  606. AddField(message2, "bar", 2, FieldDescriptorProto::LABEL_REQUIRED,
  607. FieldDescriptorProto::TYPE_STRING);
  608. AddField(message2, "quux", 6, FieldDescriptorProto::LABEL_REQUIRED,
  609. FieldDescriptorProto::TYPE_STRING);
  610. FileDescriptorProto map_file;
  611. map_file.set_name("map.proto");
  612. DescriptorProto* message3 = AddMessage(&map_file, "TestMessage3");
  613. DescriptorProto* entry = AddNestedMessage(message3, "MapInt32Int32Entry");
  614. AddField(entry, "key", 1, FieldDescriptorProto::LABEL_OPTIONAL,
  615. FieldDescriptorProto::TYPE_INT32);
  616. AddField(entry, "value", 2, FieldDescriptorProto::LABEL_OPTIONAL,
  617. FieldDescriptorProto::TYPE_INT32);
  618. entry->mutable_options()->set_map_entry(true);
  619. AddField(message3, "map_int32_int32", 1,
  620. FieldDescriptorProto::LABEL_REPEATED,
  621. FieldDescriptorProto::TYPE_MESSAGE)
  622. ->set_type_name("MapInt32Int32Entry");
  623. FileDescriptorProto json_file;
  624. json_file.set_name("json.proto");
  625. json_file.set_syntax("proto3");
  626. DescriptorProto* message4 = AddMessage(&json_file, "TestMessage4");
  627. AddField(message4, "field_name1", 1, FieldDescriptorProto::LABEL_OPTIONAL,
  628. FieldDescriptorProto::TYPE_INT32);
  629. AddField(message4, "fieldName2", 2, FieldDescriptorProto::LABEL_OPTIONAL,
  630. FieldDescriptorProto::TYPE_INT32);
  631. AddField(message4, "FieldName3", 3, FieldDescriptorProto::LABEL_OPTIONAL,
  632. FieldDescriptorProto::TYPE_INT32);
  633. AddField(message4, "_field_name4", 4, FieldDescriptorProto::LABEL_OPTIONAL,
  634. FieldDescriptorProto::TYPE_INT32);
  635. AddField(message4, "FIELD_NAME5", 5, FieldDescriptorProto::LABEL_OPTIONAL,
  636. FieldDescriptorProto::TYPE_INT32);
  637. AddField(message4, "field_name6", 6, FieldDescriptorProto::LABEL_OPTIONAL,
  638. FieldDescriptorProto::TYPE_INT32)
  639. ->set_json_name("@type");
  640. // Build the descriptors and get the pointers.
  641. foo_file_ = pool_.BuildFile(foo_file);
  642. ASSERT_TRUE(foo_file_ != nullptr);
  643. bar_file_ = pool_.BuildFile(bar_file);
  644. ASSERT_TRUE(bar_file_ != nullptr);
  645. map_file_ = pool_.BuildFile(map_file);
  646. ASSERT_TRUE(map_file_ != nullptr);
  647. json_file_ = pool_.BuildFile(json_file);
  648. ASSERT_TRUE(json_file_ != nullptr);
  649. ASSERT_EQ(1, foo_file_->enum_type_count());
  650. enum_ = foo_file_->enum_type(0);
  651. ASSERT_EQ(2, foo_file_->message_type_count());
  652. foreign_ = foo_file_->message_type(0);
  653. message_ = foo_file_->message_type(1);
  654. ASSERT_EQ(4, message_->field_count());
  655. foo_ = message_->field(0);
  656. bar_ = message_->field(1);
  657. baz_ = message_->field(2);
  658. qux_ = message_->field(3);
  659. ASSERT_EQ(1, bar_file_->message_type_count());
  660. message2_ = bar_file_->message_type(0);
  661. ASSERT_EQ(3, message2_->field_count());
  662. foo2_ = message2_->field(0);
  663. bar2_ = message2_->field(1);
  664. quux2_ = message2_->field(2);
  665. ASSERT_EQ(1, map_file_->message_type_count());
  666. message3_ = map_file_->message_type(0);
  667. ASSERT_EQ(1, message3_->field_count());
  668. map_ = message3_->field(0);
  669. ASSERT_EQ(1, json_file_->message_type_count());
  670. message4_ = json_file_->message_type(0);
  671. }
  672. void CopyWithJsonName(const Descriptor* message, DescriptorProto* proto) {
  673. message->CopyTo(proto);
  674. message->CopyJsonNameTo(proto);
  675. }
  676. DescriptorPool pool_;
  677. const FileDescriptor* foo_file_;
  678. const FileDescriptor* bar_file_;
  679. const FileDescriptor* map_file_;
  680. const FileDescriptor* json_file_;
  681. const Descriptor* message_;
  682. const Descriptor* message2_;
  683. const Descriptor* message3_;
  684. const Descriptor* message4_;
  685. const Descriptor* foreign_;
  686. const EnumDescriptor* enum_;
  687. const FieldDescriptor* foo_;
  688. const FieldDescriptor* bar_;
  689. const FieldDescriptor* baz_;
  690. const FieldDescriptor* qux_;
  691. const FieldDescriptor* foo2_;
  692. const FieldDescriptor* bar2_;
  693. const FieldDescriptor* quux2_;
  694. const FieldDescriptor* map_;
  695. };
  696. TEST_F(DescriptorTest, Name) {
  697. EXPECT_EQ("TestMessage", message_->name());
  698. EXPECT_EQ("TestMessage", message_->full_name());
  699. EXPECT_EQ(foo_file_, message_->file());
  700. EXPECT_EQ("TestMessage2", message2_->name());
  701. EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
  702. EXPECT_EQ(bar_file_, message2_->file());
  703. }
  704. TEST_F(DescriptorTest, ContainingType) {
  705. EXPECT_TRUE(message_->containing_type() == nullptr);
  706. EXPECT_TRUE(message2_->containing_type() == nullptr);
  707. }
  708. TEST_F(DescriptorTest, FieldsByIndex) {
  709. ASSERT_EQ(4, message_->field_count());
  710. EXPECT_EQ(foo_, message_->field(0));
  711. EXPECT_EQ(bar_, message_->field(1));
  712. EXPECT_EQ(baz_, message_->field(2));
  713. EXPECT_EQ(qux_, message_->field(3));
  714. }
  715. TEST_F(DescriptorTest, FindFieldByName) {
  716. // All messages in the same DescriptorPool share a single lookup table for
  717. // fields. So, in addition to testing that FindFieldByName finds the fields
  718. // of the message, we need to test that it does *not* find the fields of
  719. // *other* messages.
  720. EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
  721. EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
  722. EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
  723. EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
  724. EXPECT_TRUE(message_->FindFieldByName("no_such_field") == nullptr);
  725. EXPECT_TRUE(message_->FindFieldByName("quux") == nullptr);
  726. EXPECT_EQ(foo2_, message2_->FindFieldByName("foo"));
  727. EXPECT_EQ(bar2_, message2_->FindFieldByName("bar"));
  728. EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
  729. EXPECT_TRUE(message2_->FindFieldByName("baz") == nullptr);
  730. EXPECT_TRUE(message2_->FindFieldByName("qux") == nullptr);
  731. }
  732. TEST_F(DescriptorTest, FindFieldByNumber) {
  733. EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
  734. EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
  735. EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
  736. EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
  737. EXPECT_TRUE(message_->FindFieldByNumber(837592) == nullptr);
  738. EXPECT_TRUE(message_->FindFieldByNumber(2) == nullptr);
  739. EXPECT_EQ(foo2_, message2_->FindFieldByNumber(1));
  740. EXPECT_EQ(bar2_, message2_->FindFieldByNumber(2));
  741. EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
  742. EXPECT_TRUE(message2_->FindFieldByNumber(15) == nullptr);
  743. EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == nullptr);
  744. }
  745. TEST_F(DescriptorTest, FieldName) {
  746. EXPECT_EQ("foo", foo_->name());
  747. EXPECT_EQ("bar", bar_->name());
  748. EXPECT_EQ("baz", baz_->name());
  749. EXPECT_EQ("qux", qux_->name());
  750. }
  751. TEST_F(DescriptorTest, FieldFullName) {
  752. EXPECT_EQ("TestMessage.foo", foo_->full_name());
  753. EXPECT_EQ("TestMessage.bar", bar_->full_name());
  754. EXPECT_EQ("TestMessage.baz", baz_->full_name());
  755. EXPECT_EQ("TestMessage.qux", qux_->full_name());
  756. EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
  757. EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
  758. EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
  759. }
  760. TEST_F(DescriptorTest, PrintableNameIsFullNameForNonExtensionFields) {
  761. EXPECT_EQ("TestMessage.foo", foo_->PrintableNameForExtension());
  762. EXPECT_EQ("TestMessage.bar", bar_->PrintableNameForExtension());
  763. EXPECT_EQ("TestMessage.baz", baz_->PrintableNameForExtension());
  764. EXPECT_EQ("TestMessage.qux", qux_->PrintableNameForExtension());
  765. EXPECT_EQ("corge.grault.TestMessage2.foo",
  766. foo2_->PrintableNameForExtension());
  767. EXPECT_EQ("corge.grault.TestMessage2.bar",
  768. bar2_->PrintableNameForExtension());
  769. EXPECT_EQ("corge.grault.TestMessage2.quux",
  770. quux2_->PrintableNameForExtension());
  771. }
  772. TEST_F(DescriptorTest, PrintableNameIsFullNameForNonMessageSetExtension) {
  773. EXPECT_EQ("protobuf_unittest.Aggregate.nested",
  774. protobuf_unittest::Aggregate::descriptor()
  775. ->FindExtensionByName("nested")
  776. ->PrintableNameForExtension());
  777. }
  778. TEST_F(DescriptorTest, PrintableNameIsExtendingTypeForMessageSetExtension) {
  779. EXPECT_EQ("protobuf_unittest.AggregateMessageSetElement",
  780. protobuf_unittest::AggregateMessageSetElement::descriptor()
  781. ->FindExtensionByName("message_set_extension")
  782. ->PrintableNameForExtension());
  783. }
  784. TEST_F(DescriptorTest, FieldJsonName) {
  785. EXPECT_EQ("fieldName1", message4_->field(0)->json_name());
  786. EXPECT_EQ("fieldName2", message4_->field(1)->json_name());
  787. EXPECT_EQ("FieldName3", message4_->field(2)->json_name());
  788. EXPECT_EQ("FieldName4", message4_->field(3)->json_name());
  789. EXPECT_EQ("FIELDNAME5", message4_->field(4)->json_name());
  790. EXPECT_EQ("@type", message4_->field(5)->json_name());
  791. DescriptorProto proto;
  792. message4_->CopyTo(&proto);
  793. ASSERT_EQ(6, proto.field_size());
  794. EXPECT_FALSE(proto.field(0).has_json_name());
  795. EXPECT_FALSE(proto.field(1).has_json_name());
  796. EXPECT_FALSE(proto.field(2).has_json_name());
  797. EXPECT_FALSE(proto.field(3).has_json_name());
  798. EXPECT_FALSE(proto.field(4).has_json_name());
  799. EXPECT_EQ("@type", proto.field(5).json_name());
  800. proto.Clear();
  801. CopyWithJsonName(message4_, &proto);
  802. ASSERT_EQ(6, proto.field_size());
  803. EXPECT_EQ("fieldName1", proto.field(0).json_name());
  804. EXPECT_EQ("fieldName2", proto.field(1).json_name());
  805. EXPECT_EQ("FieldName3", proto.field(2).json_name());
  806. EXPECT_EQ("FieldName4", proto.field(3).json_name());
  807. EXPECT_EQ("FIELDNAME5", proto.field(4).json_name());
  808. EXPECT_EQ("@type", proto.field(5).json_name());
  809. // Test generated descriptor.
  810. const Descriptor* generated = protobuf_unittest::TestJsonName::descriptor();
  811. ASSERT_EQ(6, generated->field_count());
  812. EXPECT_EQ("fieldName1", generated->field(0)->json_name());
  813. EXPECT_EQ("fieldName2", generated->field(1)->json_name());
  814. EXPECT_EQ("FieldName3", generated->field(2)->json_name());
  815. EXPECT_EQ("FieldName4", generated->field(3)->json_name());
  816. EXPECT_EQ("FIELDNAME5", generated->field(4)->json_name());
  817. EXPECT_EQ("@type", generated->field(5)->json_name());
  818. }
  819. TEST_F(DescriptorTest, FieldFile) {
  820. EXPECT_EQ(foo_file_, foo_->file());
  821. EXPECT_EQ(foo_file_, bar_->file());
  822. EXPECT_EQ(foo_file_, baz_->file());
  823. EXPECT_EQ(foo_file_, qux_->file());
  824. EXPECT_EQ(bar_file_, foo2_->file());
  825. EXPECT_EQ(bar_file_, bar2_->file());
  826. EXPECT_EQ(bar_file_, quux2_->file());
  827. }
  828. TEST_F(DescriptorTest, FieldIndex) {
  829. EXPECT_EQ(0, foo_->index());
  830. EXPECT_EQ(1, bar_->index());
  831. EXPECT_EQ(2, baz_->index());
  832. EXPECT_EQ(3, qux_->index());
  833. }
  834. TEST_F(DescriptorTest, FieldNumber) {
  835. EXPECT_EQ(1, foo_->number());
  836. EXPECT_EQ(6, bar_->number());
  837. EXPECT_EQ(500000000, baz_->number());
  838. EXPECT_EQ(15, qux_->number());
  839. }
  840. TEST_F(DescriptorTest, FieldType) {
  841. EXPECT_EQ(FieldDescriptor::TYPE_STRING, foo_->type());
  842. EXPECT_EQ(FieldDescriptor::TYPE_ENUM, bar_->type());
  843. EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
  844. EXPECT_EQ(FieldDescriptor::TYPE_GROUP, qux_->type());
  845. }
  846. TEST_F(DescriptorTest, FieldLabel) {
  847. EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
  848. EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
  849. EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
  850. EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
  851. EXPECT_TRUE(foo_->is_required());
  852. EXPECT_FALSE(foo_->is_optional());
  853. EXPECT_FALSE(foo_->is_repeated());
  854. EXPECT_FALSE(bar_->is_required());
  855. EXPECT_TRUE(bar_->is_optional());
  856. EXPECT_FALSE(bar_->is_repeated());
  857. EXPECT_FALSE(baz_->is_required());
  858. EXPECT_FALSE(baz_->is_optional());
  859. EXPECT_TRUE(baz_->is_repeated());
  860. }
  861. TEST_F(DescriptorTest, IsMap) {
  862. EXPECT_TRUE(map_->is_map());
  863. EXPECT_FALSE(baz_->is_map());
  864. EXPECT_TRUE(map_->message_type()->options().map_entry());
  865. }
  866. TEST_F(DescriptorTest, GetMap) {
  867. const Descriptor* map_desc = map_->message_type();
  868. const FieldDescriptor* map_key = map_desc->map_key();
  869. ASSERT_TRUE(map_key != nullptr);
  870. EXPECT_EQ(map_key->name(), "key");
  871. EXPECT_EQ(map_key->number(), 1);
  872. const FieldDescriptor* map_value = map_desc->map_value();
  873. ASSERT_TRUE(map_value != nullptr);
  874. EXPECT_EQ(map_value->name(), "value");
  875. EXPECT_EQ(map_value->number(), 2);
  876. EXPECT_EQ(message_->map_key(), nullptr);
  877. EXPECT_EQ(message_->map_value(), nullptr);
  878. }
  879. TEST_F(DescriptorTest, FieldHasDefault) {
  880. EXPECT_FALSE(foo_->has_default_value());
  881. EXPECT_FALSE(bar_->has_default_value());
  882. EXPECT_FALSE(baz_->has_default_value());
  883. EXPECT_FALSE(qux_->has_default_value());
  884. }
  885. TEST_F(DescriptorTest, FieldContainingType) {
  886. EXPECT_EQ(message_, foo_->containing_type());
  887. EXPECT_EQ(message_, bar_->containing_type());
  888. EXPECT_EQ(message_, baz_->containing_type());
  889. EXPECT_EQ(message_, qux_->containing_type());
  890. EXPECT_EQ(message2_, foo2_->containing_type());
  891. EXPECT_EQ(message2_, bar2_->containing_type());
  892. EXPECT_EQ(message2_, quux2_->containing_type());
  893. }
  894. TEST_F(DescriptorTest, FieldMessageType) {
  895. EXPECT_TRUE(foo_->message_type() == nullptr);
  896. EXPECT_TRUE(bar_->message_type() == nullptr);
  897. EXPECT_EQ(foreign_, baz_->message_type());
  898. EXPECT_EQ(foreign_, qux_->message_type());
  899. }
  900. TEST_F(DescriptorTest, FieldEnumType) {
  901. EXPECT_TRUE(foo_->enum_type() == nullptr);
  902. EXPECT_TRUE(baz_->enum_type() == nullptr);
  903. EXPECT_TRUE(qux_->enum_type() == nullptr);
  904. EXPECT_EQ(enum_, bar_->enum_type());
  905. }
  906. // ===================================================================
  907. // Test simple flat messages and fields.
  908. class OneofDescriptorTest : public testing::Test {
  909. protected:
  910. virtual void SetUp() {
  911. // Build descriptors for the following definitions:
  912. //
  913. // package garply;
  914. // message TestOneof {
  915. // optional int32 a = 1;
  916. // oneof foo {
  917. // string b = 2;
  918. // TestOneof c = 3;
  919. // }
  920. // oneof bar {
  921. // float d = 4;
  922. // }
  923. // }
  924. FileDescriptorProto baz_file;
  925. baz_file.set_name("baz.proto");
  926. baz_file.set_package("garply");
  927. DescriptorProto* oneof_message = AddMessage(&baz_file, "TestOneof");
  928. oneof_message->add_oneof_decl()->set_name("foo");
  929. oneof_message->add_oneof_decl()->set_name("bar");
  930. AddField(oneof_message, "a", 1, FieldDescriptorProto::LABEL_OPTIONAL,
  931. FieldDescriptorProto::TYPE_INT32);
  932. AddField(oneof_message, "b", 2, FieldDescriptorProto::LABEL_OPTIONAL,
  933. FieldDescriptorProto::TYPE_STRING);
  934. oneof_message->mutable_field(1)->set_oneof_index(0);
  935. AddField(oneof_message, "c", 3, FieldDescriptorProto::LABEL_OPTIONAL,
  936. FieldDescriptorProto::TYPE_MESSAGE);
  937. oneof_message->mutable_field(2)->set_oneof_index(0);
  938. oneof_message->mutable_field(2)->set_type_name("TestOneof");
  939. AddField(oneof_message, "d", 4, FieldDescriptorProto::LABEL_OPTIONAL,
  940. FieldDescriptorProto::TYPE_FLOAT);
  941. oneof_message->mutable_field(3)->set_oneof_index(1);
  942. // Build the descriptors and get the pointers.
  943. baz_file_ = pool_.BuildFile(baz_file);
  944. ASSERT_TRUE(baz_file_ != nullptr);
  945. ASSERT_EQ(1, baz_file_->message_type_count());
  946. oneof_message_ = baz_file_->message_type(0);
  947. ASSERT_EQ(2, oneof_message_->oneof_decl_count());
  948. oneof_ = oneof_message_->oneof_decl(0);
  949. oneof2_ = oneof_message_->oneof_decl(1);
  950. ASSERT_EQ(4, oneof_message_->field_count());
  951. a_ = oneof_message_->field(0);
  952. b_ = oneof_message_->field(1);
  953. c_ = oneof_message_->field(2);
  954. d_ = oneof_message_->field(3);
  955. }
  956. DescriptorPool pool_;
  957. const FileDescriptor* baz_file_;
  958. const Descriptor* oneof_message_;
  959. const OneofDescriptor* oneof_;
  960. const OneofDescriptor* oneof2_;
  961. const FieldDescriptor* a_;
  962. const FieldDescriptor* b_;
  963. const FieldDescriptor* c_;
  964. const FieldDescriptor* d_;
  965. };
  966. TEST_F(OneofDescriptorTest, Normal) {
  967. EXPECT_EQ("foo", oneof_->name());
  968. EXPECT_EQ("garply.TestOneof.foo", oneof_->full_name());
  969. EXPECT_EQ(0, oneof_->index());
  970. ASSERT_EQ(2, oneof_->field_count());
  971. EXPECT_EQ(b_, oneof_->field(0));
  972. EXPECT_EQ(c_, oneof_->field(1));
  973. EXPECT_TRUE(a_->containing_oneof() == nullptr);
  974. EXPECT_EQ(oneof_, b_->containing_oneof());
  975. EXPECT_EQ(oneof_, c_->containing_oneof());
  976. }
  977. TEST_F(OneofDescriptorTest, FindByName) {
  978. EXPECT_EQ(oneof_, oneof_message_->FindOneofByName("foo"));
  979. EXPECT_EQ(oneof2_, oneof_message_->FindOneofByName("bar"));
  980. EXPECT_TRUE(oneof_message_->FindOneofByName("no_such_oneof") == nullptr);
  981. }
  982. // ===================================================================
  983. class StylizedFieldNamesTest : public testing::Test {
  984. protected:
  985. void SetUp() {
  986. FileDescriptorProto file;
  987. file.set_name("foo.proto");
  988. AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
  989. DescriptorProto* message = AddMessage(&file, "TestMessage");
  990. AddField(message, "foo_foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
  991. FieldDescriptorProto::TYPE_INT32);
  992. AddField(message, "FooBar", 2, FieldDescriptorProto::LABEL_OPTIONAL,
  993. FieldDescriptorProto::TYPE_INT32);
  994. AddField(message, "fooBaz", 3, FieldDescriptorProto::LABEL_OPTIONAL,
  995. FieldDescriptorProto::TYPE_INT32);
  996. AddField(message, "fooFoo", 4, // Camel-case conflict with foo_foo.
  997. FieldDescriptorProto::LABEL_OPTIONAL,
  998. FieldDescriptorProto::TYPE_INT32);
  999. AddField(message, "foobar", 5, // Lower-case conflict with FooBar.
  1000. FieldDescriptorProto::LABEL_OPTIONAL,
  1001. FieldDescriptorProto::TYPE_INT32);
  1002. AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
  1003. FieldDescriptorProto::LABEL_OPTIONAL,
  1004. FieldDescriptorProto::TYPE_INT32);
  1005. AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
  1006. FieldDescriptorProto::LABEL_OPTIONAL,
  1007. FieldDescriptorProto::TYPE_INT32);
  1008. AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
  1009. FieldDescriptorProto::LABEL_OPTIONAL,
  1010. FieldDescriptorProto::TYPE_INT32);
  1011. AddNestedExtension(message, "ExtendableMessage", "barFoo", 4, // Conflict
  1012. FieldDescriptorProto::LABEL_OPTIONAL,
  1013. FieldDescriptorProto::TYPE_INT32);
  1014. AddNestedExtension(message, "ExtendableMessage", "barbar", 5, // Conflict
  1015. FieldDescriptorProto::LABEL_OPTIONAL,
  1016. FieldDescriptorProto::TYPE_INT32);
  1017. AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
  1018. FieldDescriptorProto::LABEL_OPTIONAL,
  1019. FieldDescriptorProto::TYPE_INT32);
  1020. AddExtension(&file, "ExtendableMessage", "BazBar", 12,
  1021. FieldDescriptorProto::LABEL_OPTIONAL,
  1022. FieldDescriptorProto::TYPE_INT32);
  1023. AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
  1024. FieldDescriptorProto::LABEL_OPTIONAL,
  1025. FieldDescriptorProto::TYPE_INT32);
  1026. AddExtension(&file, "ExtendableMessage", "bazFoo", 14, // Conflict
  1027. FieldDescriptorProto::LABEL_OPTIONAL,
  1028. FieldDescriptorProto::TYPE_INT32);
  1029. AddExtension(&file, "ExtendableMessage", "bazbar", 15, // Conflict
  1030. FieldDescriptorProto::LABEL_OPTIONAL,
  1031. FieldDescriptorProto::TYPE_INT32);
  1032. file_ = pool_.BuildFile(file);
  1033. ASSERT_TRUE(file_ != nullptr);
  1034. ASSERT_EQ(2, file_->message_type_count());
  1035. message_ = file_->message_type(1);
  1036. ASSERT_EQ("TestMessage", message_->name());
  1037. ASSERT_EQ(5, message_->field_count());
  1038. ASSERT_EQ(5, message_->extension_count());
  1039. ASSERT_EQ(5, file_->extension_count());
  1040. }
  1041. DescriptorPool pool_;
  1042. const FileDescriptor* file_;
  1043. const Descriptor* message_;
  1044. };
  1045. TEST_F(StylizedFieldNamesTest, LowercaseName) {
  1046. EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
  1047. EXPECT_EQ("foobar", message_->field(1)->lowercase_name());
  1048. EXPECT_EQ("foobaz", message_->field(2)->lowercase_name());
  1049. EXPECT_EQ("foofoo", message_->field(3)->lowercase_name());
  1050. EXPECT_EQ("foobar", message_->field(4)->lowercase_name());
  1051. EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
  1052. EXPECT_EQ("barbar", message_->extension(1)->lowercase_name());
  1053. EXPECT_EQ("barbaz", message_->extension(2)->lowercase_name());
  1054. EXPECT_EQ("barfoo", message_->extension(3)->lowercase_name());
  1055. EXPECT_EQ("barbar", message_->extension(4)->lowercase_name());
  1056. EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
  1057. EXPECT_EQ("bazbar", file_->extension(1)->lowercase_name());
  1058. EXPECT_EQ("bazbaz", file_->extension(2)->lowercase_name());
  1059. EXPECT_EQ("bazfoo", file_->extension(3)->lowercase_name());
  1060. EXPECT_EQ("bazbar", file_->extension(4)->lowercase_name());
  1061. }
  1062. TEST_F(StylizedFieldNamesTest, CamelcaseName) {
  1063. EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
  1064. EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
  1065. EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
  1066. EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
  1067. EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
  1068. EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
  1069. EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
  1070. EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
  1071. EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
  1072. EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
  1073. EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
  1074. EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
  1075. EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
  1076. EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
  1077. EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
  1078. }
  1079. TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
  1080. EXPECT_EQ(message_->field(0), message_->FindFieldByLowercaseName("foo_foo"));
  1081. EXPECT_EQ(message_->field(1), message_->FindFieldByLowercaseName("foobar"));
  1082. EXPECT_EQ(message_->field(2), message_->FindFieldByLowercaseName("foobaz"));
  1083. EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == nullptr);
  1084. EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == nullptr);
  1085. EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == nullptr);
  1086. EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == nullptr);
  1087. EXPECT_EQ(message_->extension(0),
  1088. message_->FindExtensionByLowercaseName("bar_foo"));
  1089. EXPECT_EQ(message_->extension(1),
  1090. message_->FindExtensionByLowercaseName("barbar"));
  1091. EXPECT_EQ(message_->extension(2),
  1092. message_->FindExtensionByLowercaseName("barbaz"));
  1093. EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == nullptr);
  1094. EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == nullptr);
  1095. EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == nullptr);
  1096. EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == nullptr);
  1097. EXPECT_EQ(file_->extension(0),
  1098. file_->FindExtensionByLowercaseName("baz_foo"));
  1099. EXPECT_EQ(file_->extension(1), file_->FindExtensionByLowercaseName("bazbar"));
  1100. EXPECT_EQ(file_->extension(2), file_->FindExtensionByLowercaseName("bazbaz"));
  1101. EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == nullptr);
  1102. EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == nullptr);
  1103. EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == nullptr);
  1104. }
  1105. TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
  1106. EXPECT_EQ(message_->field(0), message_->FindFieldByCamelcaseName("fooFoo"));
  1107. EXPECT_EQ(message_->field(1), message_->FindFieldByCamelcaseName("fooBar"));
  1108. EXPECT_EQ(message_->field(2), message_->FindFieldByCamelcaseName("fooBaz"));
  1109. EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == nullptr);
  1110. EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == nullptr);
  1111. EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == nullptr);
  1112. EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == nullptr);
  1113. EXPECT_EQ(message_->extension(0),
  1114. message_->FindExtensionByCamelcaseName("barFoo"));
  1115. EXPECT_EQ(message_->extension(1),
  1116. message_->FindExtensionByCamelcaseName("barBar"));
  1117. EXPECT_EQ(message_->extension(2),
  1118. message_->FindExtensionByCamelcaseName("barBaz"));
  1119. EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == nullptr);
  1120. EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == nullptr);
  1121. EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == nullptr);
  1122. EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == nullptr);
  1123. EXPECT_EQ(file_->extension(0), file_->FindExtensionByCamelcaseName("bazFoo"));
  1124. EXPECT_EQ(file_->extension(1), file_->FindExtensionByCamelcaseName("bazBar"));
  1125. EXPECT_EQ(file_->extension(2), file_->FindExtensionByCamelcaseName("bazBaz"));
  1126. EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == nullptr);
  1127. EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == nullptr);
  1128. EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == nullptr);
  1129. }
  1130. // ===================================================================
  1131. // Test enum descriptors.
  1132. class EnumDescriptorTest : public testing::Test {
  1133. protected:
  1134. virtual void SetUp() {
  1135. // Build descriptors for the following definitions:
  1136. //
  1137. // // in "foo.proto"
  1138. // enum TestEnum {
  1139. // FOO = 1;
  1140. // BAR = 2;
  1141. // }
  1142. //
  1143. // // in "bar.proto"
  1144. // package corge.grault;
  1145. // enum TestEnum2 {
  1146. // FOO = 1;
  1147. // BAZ = 3;
  1148. // }
  1149. //
  1150. // TestEnum2 is primarily here to test FindValueByName and friends.
  1151. // All enums created from the same DescriptorPool share the same lookup
  1152. // table, so we need to insure that they don't interfere.
  1153. // TestEnum
  1154. FileDescriptorProto foo_file;
  1155. foo_file.set_name("foo.proto");
  1156. EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
  1157. AddEnumValue(enum_proto, "FOO", 1);
  1158. AddEnumValue(enum_proto, "BAR", 2);
  1159. // TestEnum2
  1160. FileDescriptorProto bar_file;
  1161. bar_file.set_name("bar.proto");
  1162. bar_file.set_package("corge.grault");
  1163. EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
  1164. AddEnumValue(enum2_proto, "FOO", 1);
  1165. AddEnumValue(enum2_proto, "BAZ", 3);
  1166. // Build the descriptors and get the pointers.
  1167. foo_file_ = pool_.BuildFile(foo_file);
  1168. ASSERT_TRUE(foo_file_ != nullptr);
  1169. bar_file_ = pool_.BuildFile(bar_file);
  1170. ASSERT_TRUE(bar_file_ != nullptr);
  1171. ASSERT_EQ(1, foo_file_->enum_type_count());
  1172. enum_ = foo_file_->enum_type(0);
  1173. ASSERT_EQ(2, enum_->value_count());
  1174. foo_ = enum_->value(0);
  1175. bar_ = enum_->value(1);
  1176. ASSERT_EQ(1, bar_file_->enum_type_count());
  1177. enum2_ = bar_file_->enum_type(0);
  1178. ASSERT_EQ(2, enum2_->value_count());
  1179. foo2_ = enum2_->value(0);
  1180. baz2_ = enum2_->value(1);
  1181. }
  1182. DescriptorPool pool_;
  1183. const FileDescriptor* foo_file_;
  1184. const FileDescriptor* bar_file_;
  1185. const EnumDescriptor* enum_;
  1186. const EnumDescriptor* enum2_;
  1187. const EnumValueDescriptor* foo_;
  1188. const EnumValueDescriptor* bar_;
  1189. const EnumValueDescriptor* foo2_;
  1190. const EnumValueDescriptor* baz2_;
  1191. };
  1192. TEST_F(EnumDescriptorTest, Name) {
  1193. EXPECT_EQ("TestEnum", enum_->name());
  1194. EXPECT_EQ("TestEnum", enum_->full_name());
  1195. EXPECT_EQ(foo_file_, enum_->file());
  1196. EXPECT_EQ("TestEnum2", enum2_->name());
  1197. EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
  1198. EXPECT_EQ(bar_file_, enum2_->file());
  1199. }
  1200. TEST_F(EnumDescriptorTest, ContainingType) {
  1201. EXPECT_TRUE(enum_->containing_type() == nullptr);
  1202. EXPECT_TRUE(enum2_->containing_type() == nullptr);
  1203. }
  1204. TEST_F(EnumDescriptorTest, ValuesByIndex) {
  1205. ASSERT_EQ(2, enum_->value_count());
  1206. EXPECT_EQ(foo_, enum_->value(0));
  1207. EXPECT_EQ(bar_, enum_->value(1));
  1208. }
  1209. TEST_F(EnumDescriptorTest, FindValueByName) {
  1210. EXPECT_EQ(foo_, enum_->FindValueByName("FOO"));
  1211. EXPECT_EQ(bar_, enum_->FindValueByName("BAR"));
  1212. EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
  1213. EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
  1214. EXPECT_TRUE(enum_->FindValueByName("NO_SUCH_VALUE") == nullptr);
  1215. EXPECT_TRUE(enum_->FindValueByName("BAZ") == nullptr);
  1216. EXPECT_TRUE(enum2_->FindValueByName("BAR") == nullptr);
  1217. }
  1218. TEST_F(EnumDescriptorTest, FindValueByNumber) {
  1219. EXPECT_EQ(foo_, enum_->FindValueByNumber(1));
  1220. EXPECT_EQ(bar_, enum_->FindValueByNumber(2));
  1221. EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
  1222. EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
  1223. EXPECT_TRUE(enum_->FindValueByNumber(416) == nullptr);
  1224. EXPECT_TRUE(enum_->FindValueByNumber(3) == nullptr);
  1225. EXPECT_TRUE(enum2_->FindValueByNumber(2) == nullptr);
  1226. }
  1227. TEST_F(EnumDescriptorTest, ValueName) {
  1228. EXPECT_EQ("FOO", foo_->name());
  1229. EXPECT_EQ("BAR", bar_->name());
  1230. }
  1231. TEST_F(EnumDescriptorTest, ValueFullName) {
  1232. EXPECT_EQ("FOO", foo_->full_name());
  1233. EXPECT_EQ("BAR", bar_->full_name());
  1234. EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
  1235. EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
  1236. }
  1237. TEST_F(EnumDescriptorTest, ValueIndex) {
  1238. EXPECT_EQ(0, foo_->index());
  1239. EXPECT_EQ(1, bar_->index());
  1240. }
  1241. TEST_F(EnumDescriptorTest, ValueNumber) {
  1242. EXPECT_EQ(1, foo_->number());
  1243. EXPECT_EQ(2, bar_->number());
  1244. }
  1245. TEST_F(EnumDescriptorTest, ValueType) {
  1246. EXPECT_EQ(enum_, foo_->type());
  1247. EXPECT_EQ(enum_, bar_->type());
  1248. EXPECT_EQ(enum2_, foo2_->type());
  1249. EXPECT_EQ(enum2_, baz2_->type());
  1250. }
  1251. // ===================================================================
  1252. // Test service descriptors.
  1253. class ServiceDescriptorTest : public testing::Test {
  1254. protected:
  1255. virtual void SetUp() {
  1256. // Build descriptors for the following messages and service:
  1257. // // in "foo.proto"
  1258. // message FooRequest {}
  1259. // message FooResponse {}
  1260. // message BarRequest {}
  1261. // message BarResponse {}
  1262. // message BazRequest {}
  1263. // message BazResponse {}
  1264. //
  1265. // service TestService {
  1266. // rpc Foo(FooRequest) returns (FooResponse);
  1267. // rpc Bar(BarRequest) returns (BarResponse);
  1268. // }
  1269. //
  1270. // // in "bar.proto"
  1271. // package corge.grault
  1272. // service TestService2 {
  1273. // rpc Foo(FooRequest) returns (FooResponse);
  1274. // rpc Baz(BazRequest) returns (BazResponse);
  1275. // }
  1276. FileDescriptorProto foo_file;
  1277. foo_file.set_name("foo.proto");
  1278. AddMessage(&foo_file, "FooRequest");
  1279. AddMessage(&foo_file, "FooResponse");
  1280. AddMessage(&foo_file, "BarRequest");
  1281. AddMessage(&foo_file, "BarResponse");
  1282. AddMessage(&foo_file, "BazRequest");
  1283. AddMessage(&foo_file, "BazResponse");
  1284. ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
  1285. AddMethod(service, "Foo", "FooRequest", "FooResponse");
  1286. AddMethod(service, "Bar", "BarRequest", "BarResponse");
  1287. FileDescriptorProto bar_file;
  1288. bar_file.set_name("bar.proto");
  1289. bar_file.set_package("corge.grault");
  1290. bar_file.add_dependency("foo.proto");
  1291. ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
  1292. AddMethod(service2, "Foo", "FooRequest", "FooResponse");
  1293. AddMethod(service2, "Baz", "BazRequest", "BazResponse");
  1294. // Build the descriptors and get the pointers.
  1295. foo_file_ = pool_.BuildFile(foo_file);
  1296. ASSERT_TRUE(foo_file_ != nullptr);
  1297. bar_file_ = pool_.BuildFile(bar_file);
  1298. ASSERT_TRUE(bar_file_ != nullptr);
  1299. ASSERT_EQ(6, foo_file_->message_type_count());
  1300. foo_request_ = foo_file_->message_type(0);
  1301. foo_response_ = foo_file_->message_type(1);
  1302. bar_request_ = foo_file_->message_type(2);
  1303. bar_response_ = foo_file_->message_type(3);
  1304. baz_request_ = foo_file_->message_type(4);
  1305. baz_response_ = foo_file_->message_type(5);
  1306. ASSERT_EQ(1, foo_file_->service_count());
  1307. service_ = foo_file_->service(0);
  1308. ASSERT_EQ(2, service_->method_count());
  1309. foo_ = service_->method(0);
  1310. bar_ = service_->method(1);
  1311. ASSERT_EQ(1, bar_file_->service_count());
  1312. service2_ = bar_file_->service(0);
  1313. ASSERT_EQ(2, service2_->method_count());
  1314. foo2_ = service2_->method(0);
  1315. baz2_ = service2_->method(1);
  1316. }
  1317. DescriptorPool pool_;
  1318. const FileDescriptor* foo_file_;
  1319. const FileDescriptor* bar_file_;
  1320. const Descriptor* foo_request_;
  1321. const Descriptor* foo_response_;
  1322. const Descriptor* bar_request_;
  1323. const Descriptor* bar_response_;
  1324. const Descriptor* baz_request_;
  1325. const Descriptor* baz_response_;
  1326. const ServiceDescriptor* service_;
  1327. const ServiceDescriptor* service2_;
  1328. const MethodDescriptor* foo_;
  1329. const MethodDescriptor* bar_;
  1330. const MethodDescriptor* foo2_;
  1331. const MethodDescriptor* baz2_;
  1332. };
  1333. TEST_F(ServiceDescriptorTest, Name) {
  1334. EXPECT_EQ("TestService", service_->name());
  1335. EXPECT_EQ("TestService", service_->full_name());
  1336. EXPECT_EQ(foo_file_, service_->file());
  1337. EXPECT_EQ("TestService2", service2_->name());
  1338. EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
  1339. EXPECT_EQ(bar_file_, service2_->file());
  1340. }
  1341. TEST_F(ServiceDescriptorTest, MethodsByIndex) {
  1342. ASSERT_EQ(2, service_->method_count());
  1343. EXPECT_EQ(foo_, service_->method(0));
  1344. EXPECT_EQ(bar_, service_->method(1));
  1345. }
  1346. TEST_F(ServiceDescriptorTest, FindMethodByName) {
  1347. EXPECT_EQ(foo_, service_->FindMethodByName("Foo"));
  1348. EXPECT_EQ(bar_, service_->FindMethodByName("Bar"));
  1349. EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
  1350. EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
  1351. EXPECT_TRUE(service_->FindMethodByName("NoSuchMethod") == nullptr);
  1352. EXPECT_TRUE(service_->FindMethodByName("Baz") == nullptr);
  1353. EXPECT_TRUE(service2_->FindMethodByName("Bar") == nullptr);
  1354. }
  1355. TEST_F(ServiceDescriptorTest, MethodName) {
  1356. EXPECT_EQ("Foo", foo_->name());
  1357. EXPECT_EQ("Bar", bar_->name());
  1358. }
  1359. TEST_F(ServiceDescriptorTest, MethodFullName) {
  1360. EXPECT_EQ("TestService.Foo", foo_->full_name());
  1361. EXPECT_EQ("TestService.Bar", bar_->full_name());
  1362. EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
  1363. EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
  1364. }
  1365. TEST_F(ServiceDescriptorTest, MethodIndex) {
  1366. EXPECT_EQ(0, foo_->index());
  1367. EXPECT_EQ(1, bar_->index());
  1368. }
  1369. TEST_F(ServiceDescriptorTest, MethodParent) {
  1370. EXPECT_EQ(service_, foo_->service());
  1371. EXPECT_EQ(service_, bar_->service());
  1372. }
  1373. TEST_F(ServiceDescriptorTest, MethodInputType) {
  1374. EXPECT_EQ(foo_request_, foo_->input_type());
  1375. EXPECT_EQ(bar_request_, bar_->input_type());
  1376. }
  1377. TEST_F(ServiceDescriptorTest, MethodOutputType) {
  1378. EXPECT_EQ(foo_response_, foo_->output_type());
  1379. EXPECT_EQ(bar_response_, bar_->output_type());
  1380. }
  1381. // ===================================================================
  1382. // Test nested types.
  1383. class NestedDescriptorTest : public testing::Test {
  1384. protected:
  1385. virtual void SetUp() {
  1386. // Build descriptors for the following definitions:
  1387. //
  1388. // // in "foo.proto"
  1389. // message TestMessage {
  1390. // message Foo {}
  1391. // message Bar {}
  1392. // enum Baz { A = 1; }
  1393. // enum Qux { B = 1; }
  1394. // }
  1395. //
  1396. // // in "bar.proto"
  1397. // package corge.grault;
  1398. // message TestMessage2 {
  1399. // message Foo {}
  1400. // message Baz {}
  1401. // enum Qux { A = 1; }
  1402. // enum Quux { C = 1; }
  1403. // }
  1404. //
  1405. // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
  1406. // All messages created from the same DescriptorPool share the same lookup
  1407. // table, so we need to insure that they don't interfere.
  1408. //
  1409. // We add enum values to the enums in order to test searching for enum
  1410. // values across a message's scope.
  1411. FileDescriptorProto foo_file;
  1412. foo_file.set_name("foo.proto");
  1413. DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
  1414. AddNestedMessage(message, "Foo");
  1415. AddNestedMessage(message, "Bar");
  1416. EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
  1417. AddEnumValue(baz, "A", 1);
  1418. EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
  1419. AddEnumValue(qux, "B", 1);
  1420. FileDescriptorProto bar_file;
  1421. bar_file.set_name("bar.proto");
  1422. bar_file.set_package("corge.grault");
  1423. DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
  1424. AddNestedMessage(message2, "Foo");
  1425. AddNestedMessage(message2, "Baz");
  1426. EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
  1427. AddEnumValue(qux2, "A", 1);
  1428. EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
  1429. AddEnumValue(quux2, "C", 1);
  1430. // Build the descriptors and get the pointers.
  1431. foo_file_ = pool_.BuildFile(foo_file);
  1432. ASSERT_TRUE(foo_file_ != nullptr);
  1433. bar_file_ = pool_.BuildFile(bar_file);
  1434. ASSERT_TRUE(bar_file_ != nullptr);
  1435. ASSERT_EQ(1, foo_file_->message_type_count());
  1436. message_ = foo_file_->message_type(0);
  1437. ASSERT_EQ(2, message_->nested_type_count());
  1438. foo_ = message_->nested_type(0);
  1439. bar_ = message_->nested_type(1);
  1440. ASSERT_EQ(2, message_->enum_type_count());
  1441. baz_ = message_->enum_type(0);
  1442. qux_ = message_->enum_type(1);
  1443. ASSERT_EQ(1, baz_->value_count());
  1444. a_ = baz_->value(0);
  1445. ASSERT_EQ(1, qux_->value_count());
  1446. b_ = qux_->value(0);
  1447. ASSERT_EQ(1, bar_file_->message_type_count());
  1448. message2_ = bar_file_->message_type(0);
  1449. ASSERT_EQ(2, message2_->nested_type_count());
  1450. foo2_ = message2_->nested_type(0);
  1451. baz2_ = message2_->nested_type(1);
  1452. ASSERT_EQ(2, message2_->enum_type_count());
  1453. qux2_ = message2_->enum_type(0);
  1454. quux2_ = message2_->enum_type(1);
  1455. ASSERT_EQ(1, qux2_->value_count());
  1456. a2_ = qux2_->value(0);
  1457. ASSERT_EQ(1, quux2_->value_count());
  1458. c2_ = quux2_->value(0);
  1459. }
  1460. DescriptorPool pool_;
  1461. const FileDescriptor* foo_file_;
  1462. const FileDescriptor* bar_file_;
  1463. const Descriptor* message_;
  1464. const Descriptor* message2_;
  1465. const Descriptor* foo_;
  1466. const Descriptor* bar_;
  1467. const EnumDescriptor* baz_;
  1468. const EnumDescriptor* qux_;
  1469. const EnumValueDescriptor* a_;
  1470. const EnumValueDescriptor* b_;
  1471. const Descriptor* foo2_;
  1472. const Descriptor* baz2_;
  1473. const EnumDescriptor* qux2_;
  1474. const EnumDescriptor* quux2_;
  1475. const EnumValueDescriptor* a2_;
  1476. const EnumValueDescriptor* c2_;
  1477. };
  1478. TEST_F(NestedDescriptorTest, MessageName) {
  1479. EXPECT_EQ("Foo", foo_->name());
  1480. EXPECT_EQ("Bar", bar_->name());
  1481. EXPECT_EQ("Foo", foo2_->name());
  1482. EXPECT_EQ("Baz", baz2_->name());
  1483. EXPECT_EQ("TestMessage.Foo", foo_->full_name());
  1484. EXPECT_EQ("TestMessage.Bar", bar_->full_name());
  1485. EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
  1486. EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
  1487. }
  1488. TEST_F(NestedDescriptorTest, MessageContainingType) {
  1489. EXPECT_EQ(message_, foo_->containing_type());
  1490. EXPECT_EQ(message_, bar_->containing_type());
  1491. EXPECT_EQ(message2_, foo2_->containing_type());
  1492. EXPECT_EQ(message2_, baz2_->containing_type());
  1493. }
  1494. TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
  1495. ASSERT_EQ(2, message_->nested_type_count());
  1496. EXPECT_EQ(foo_, message_->nested_type(0));
  1497. EXPECT_EQ(bar_, message_->nested_type(1));
  1498. }
  1499. TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
  1500. EXPECT_TRUE(message_->FindFieldByName("Foo") == nullptr);
  1501. EXPECT_TRUE(message_->FindFieldByName("Qux") == nullptr);
  1502. EXPECT_TRUE(message_->FindExtensionByName("Foo") == nullptr);
  1503. EXPECT_TRUE(message_->FindExtensionByName("Qux") == nullptr);
  1504. }
  1505. TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
  1506. EXPECT_EQ(foo_, message_->FindNestedTypeByName("Foo"));
  1507. EXPECT_EQ(bar_, message_->FindNestedTypeByName("Bar"));
  1508. EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
  1509. EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
  1510. EXPECT_TRUE(message_->FindNestedTypeByName("NoSuchType") == nullptr);
  1511. EXPECT_TRUE(message_->FindNestedTypeByName("Baz") == nullptr);
  1512. EXPECT_TRUE(message2_->FindNestedTypeByName("Bar") == nullptr);
  1513. EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == nullptr);
  1514. }
  1515. TEST_F(NestedDescriptorTest, EnumName) {
  1516. EXPECT_EQ("Baz", baz_->name());
  1517. EXPECT_EQ("Qux", qux_->name());
  1518. EXPECT_EQ("Qux", qux2_->name());
  1519. EXPECT_EQ("Quux", quux2_->name());
  1520. EXPECT_EQ("TestMessage.Baz", baz_->full_name());
  1521. EXPECT_EQ("TestMessage.Qux", qux_->full_name());
  1522. EXPECT_EQ("corge.grault.TestMessage2.Qux", qux2_->full_name());
  1523. EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
  1524. }
  1525. TEST_F(NestedDescriptorTest, EnumContainingType) {
  1526. EXPECT_EQ(message_, baz_->containing_type());
  1527. EXPECT_EQ(message_, qux_->containing_type());
  1528. EXPECT_EQ(message2_, qux2_->containing_type());
  1529. EXPECT_EQ(message2_, quux2_->containing_type());
  1530. }
  1531. TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
  1532. ASSERT_EQ(2, message_->nested_type_count());
  1533. EXPECT_EQ(foo_, message_->nested_type(0));
  1534. EXPECT_EQ(bar_, message_->nested_type(1));
  1535. }
  1536. TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
  1537. EXPECT_EQ(baz_, message_->FindEnumTypeByName("Baz"));
  1538. EXPECT_EQ(qux_, message_->FindEnumTypeByName("Qux"));
  1539. EXPECT_EQ(qux2_, message2_->FindEnumTypeByName("Qux"));
  1540. EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
  1541. EXPECT_TRUE(message_->FindEnumTypeByName("NoSuchType") == nullptr);
  1542. EXPECT_TRUE(message_->FindEnumTypeByName("Quux") == nullptr);
  1543. EXPECT_TRUE(message2_->FindEnumTypeByName("Baz") == nullptr);
  1544. EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == nullptr);
  1545. }
  1546. TEST_F(NestedDescriptorTest, FindEnumValueByName) {
  1547. EXPECT_EQ(a_, message_->FindEnumValueByName("A"));
  1548. EXPECT_EQ(b_, message_->FindEnumValueByName("B"));
  1549. EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
  1550. EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
  1551. EXPECT_TRUE(message_->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
  1552. EXPECT_TRUE(message_->FindEnumValueByName("C") == nullptr);
  1553. EXPECT_TRUE(message2_->FindEnumValueByName("B") == nullptr);
  1554. EXPECT_TRUE(message_->FindEnumValueByName("Foo") == nullptr);
  1555. }
  1556. // ===================================================================
  1557. // Test extensions.
  1558. class ExtensionDescriptorTest : public testing::Test {
  1559. protected:
  1560. virtual void SetUp() {
  1561. // Build descriptors for the following definitions:
  1562. //
  1563. // enum Baz {}
  1564. // message Qux {}
  1565. //
  1566. // message Foo {
  1567. // extensions 10 to 19;
  1568. // extensions 30 to 39;
  1569. // }
  1570. // extends Foo with optional int32 foo_int32 = 10;
  1571. // extends Foo with repeated TestEnum foo_enum = 19;
  1572. // message Bar {
  1573. // extends Foo with optional Qux foo_message = 30;
  1574. // // (using Qux as the group type)
  1575. // extends Foo with repeated group foo_group = 39;
  1576. // }
  1577. FileDescriptorProto foo_file;
  1578. foo_file.set_name("foo.proto");
  1579. AddEmptyEnum(&foo_file, "Baz");
  1580. AddMessage(&foo_file, "Qux");
  1581. DescriptorProto* foo = AddMessage(&foo_file, "Foo");
  1582. AddExtensionRange(foo, 10, 20);
  1583. AddExtensionRange(foo, 30, 40);
  1584. AddExtension(&foo_file, "Foo", "foo_int32", 10,
  1585. FieldDescriptorProto::LABEL_OPTIONAL,
  1586. FieldDescriptorProto::TYPE_INT32);
  1587. AddExtension(&foo_file, "Foo", "foo_enum", 19,
  1588. FieldDescriptorProto::LABEL_REPEATED,
  1589. FieldDescriptorProto::TYPE_ENUM)
  1590. ->set_type_name("Baz");
  1591. DescriptorProto* bar = AddMessage(&foo_file, "Bar");
  1592. AddNestedExtension(bar, "Foo", "foo_message", 30,
  1593. FieldDescriptorProto::LABEL_OPTIONAL,
  1594. FieldDescriptorProto::TYPE_MESSAGE)
  1595. ->set_type_name("Qux");
  1596. AddNestedExtension(bar, "Foo", "foo_group", 39,
  1597. FieldDescriptorProto::LABEL_REPEATED,
  1598. FieldDescriptorProto::TYPE_GROUP)
  1599. ->set_type_name("Qux");
  1600. // Build the descriptors and get the pointers.
  1601. foo_file_ = pool_.BuildFile(foo_file);
  1602. ASSERT_TRUE(foo_file_ != nullptr);
  1603. ASSERT_EQ(1, foo_file_->enum_type_count());
  1604. baz_ = foo_file_->enum_type(0);
  1605. ASSERT_EQ(3, foo_file_->message_type_count());
  1606. qux_ = foo_file_->message_type(0);
  1607. foo_ = foo_file_->message_type(1);
  1608. bar_ = foo_file_->message_type(2);
  1609. }
  1610. DescriptorPool pool_;
  1611. const FileDescriptor* foo_file_;
  1612. const Descriptor* foo_;
  1613. const Descriptor* bar_;
  1614. const EnumDescriptor* baz_;
  1615. const Descriptor* qux_;
  1616. };
  1617. TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
  1618. EXPECT_EQ(0, bar_->extension_range_count());
  1619. ASSERT_EQ(2, foo_->extension_range_count());
  1620. EXPECT_EQ(10, foo_->extension_range(0)->start);
  1621. EXPECT_EQ(30, foo_->extension_range(1)->start);
  1622. EXPECT_EQ(20, foo_->extension_range(0)->end);
  1623. EXPECT_EQ(40, foo_->extension_range(1)->end);
  1624. }
  1625. TEST_F(ExtensionDescriptorTest, Extensions) {
  1626. EXPECT_EQ(0, foo_->extension_count());
  1627. ASSERT_EQ(2, foo_file_->extension_count());
  1628. ASSERT_EQ(2, bar_->extension_count());
  1629. EXPECT_TRUE(foo_file_->extension(0)->is_extension());
  1630. EXPECT_TRUE(foo_file_->extension(1)->is_extension());
  1631. EXPECT_TRUE(bar_->extension(0)->is_extension());
  1632. EXPECT_TRUE(bar_->extension(1)->is_extension());
  1633. EXPECT_EQ("foo_int32", foo_file_->extension(0)->name());
  1634. EXPECT_EQ("foo_enum", foo_file_->extension(1)->name());
  1635. EXPECT_EQ("foo_message", bar_->extension(0)->name());
  1636. EXPECT_EQ("foo_group", bar_->extension(1)->name());
  1637. EXPECT_EQ(10, foo_file_->extension(0)->number());
  1638. EXPECT_EQ(19, foo_file_->extension(1)->number());
  1639. EXPECT_EQ(30, bar_->extension(0)->number());
  1640. EXPECT_EQ(39, bar_->extension(1)->number());
  1641. EXPECT_EQ(FieldDescriptor::TYPE_INT32, foo_file_->extension(0)->type());
  1642. EXPECT_EQ(FieldDescriptor::TYPE_ENUM, foo_file_->extension(1)->type());
  1643. EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
  1644. EXPECT_EQ(FieldDescriptor::TYPE_GROUP, bar_->extension(1)->type());
  1645. EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
  1646. EXPECT_EQ(qux_, bar_->extension(0)->message_type());
  1647. EXPECT_EQ(qux_, bar_->extension(1)->message_type());
  1648. EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
  1649. EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
  1650. EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
  1651. EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
  1652. EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
  1653. EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
  1654. EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
  1655. EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
  1656. EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == nullptr);
  1657. EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == nullptr);
  1658. EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
  1659. EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
  1660. }
  1661. TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
  1662. EXPECT_FALSE(foo_->IsExtensionNumber(9));
  1663. EXPECT_TRUE(foo_->IsExtensionNumber(10));
  1664. EXPECT_TRUE(foo_->IsExtensionNumber(19));
  1665. EXPECT_FALSE(foo_->IsExtensionNumber(20));
  1666. EXPECT_FALSE(foo_->IsExtensionNumber(29));
  1667. EXPECT_TRUE(foo_->IsExtensionNumber(30));
  1668. EXPECT_TRUE(foo_->IsExtensionNumber(39));
  1669. EXPECT_FALSE(foo_->IsExtensionNumber(40));
  1670. }
  1671. TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
  1672. // Note that FileDescriptor::FindExtensionByName() is tested by
  1673. // FileDescriptorTest.
  1674. ASSERT_EQ(2, bar_->extension_count());
  1675. EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
  1676. EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group"));
  1677. EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == nullptr);
  1678. EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == nullptr);
  1679. EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == nullptr);
  1680. }
  1681. TEST_F(ExtensionDescriptorTest, FindExtensionByPrintableName) {
  1682. EXPECT_TRUE(pool_.FindExtensionByPrintableName(foo_, "no_such_extension") ==
  1683. nullptr);
  1684. EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "no_such_extension") ==
  1685. nullptr);
  1686. ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "Bar.foo_message") ==
  1687. nullptr);
  1688. ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "Bar.foo_group") ==
  1689. nullptr);
  1690. EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_message") ==
  1691. nullptr);
  1692. EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_group") == nullptr);
  1693. EXPECT_EQ(bar_->FindExtensionByName("foo_message"),
  1694. pool_.FindExtensionByPrintableName(foo_, "Bar.foo_message"));
  1695. EXPECT_EQ(bar_->FindExtensionByName("foo_group"),
  1696. pool_.FindExtensionByPrintableName(foo_, "Bar.foo_group"));
  1697. ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "foo_int32") ==
  1698. nullptr);
  1699. ASSERT_FALSE(pool_.FindExtensionByPrintableName(foo_, "foo_enum") == nullptr);
  1700. EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_int32") == nullptr);
  1701. EXPECT_TRUE(pool_.FindExtensionByPrintableName(bar_, "foo_enum") == nullptr);
  1702. EXPECT_EQ(foo_file_->FindExtensionByName("foo_int32"),
  1703. pool_.FindExtensionByPrintableName(foo_, "foo_int32"));
  1704. EXPECT_EQ(foo_file_->FindExtensionByName("foo_enum"),
  1705. pool_.FindExtensionByPrintableName(foo_, "foo_enum"));
  1706. }
  1707. TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
  1708. std::vector<const FieldDescriptor*> extensions;
  1709. pool_.FindAllExtensions(foo_, &extensions);
  1710. ASSERT_EQ(4, extensions.size());
  1711. EXPECT_EQ(10, extensions[0]->number());
  1712. EXPECT_EQ(19, extensions[1]->number());
  1713. EXPECT_EQ(30, extensions[2]->number());
  1714. EXPECT_EQ(39, extensions[3]->number());
  1715. }
  1716. TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) {
  1717. DescriptorPool pool;
  1718. FileDescriptorProto file_proto;
  1719. // Add "google/protobuf/descriptor.proto".
  1720. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
  1721. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  1722. // Add "foo.proto":
  1723. // import "google/protobuf/descriptor.proto";
  1724. // extend google.protobuf.FieldOptions {
  1725. // optional int32 option1 = 1000;
  1726. // }
  1727. file_proto.Clear();
  1728. file_proto.set_name("foo.proto");
  1729. file_proto.add_dependency("google/protobuf/descriptor.proto");
  1730. AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
  1731. FieldDescriptorProto::LABEL_OPTIONAL,
  1732. FieldDescriptorProto::TYPE_INT32);
  1733. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  1734. // Add "bar.proto":
  1735. // import "google/protobuf/descriptor.proto";
  1736. // extend google.protobuf.FieldOptions {
  1737. // optional int32 option2 = 1000;
  1738. // }
  1739. file_proto.Clear();
  1740. file_proto.set_name("bar.proto");
  1741. file_proto.add_dependency("google/protobuf/descriptor.proto");
  1742. AddExtension(&file_proto, "google.protobuf.FieldOptions", "option2", 1000,
  1743. FieldDescriptorProto::LABEL_OPTIONAL,
  1744. FieldDescriptorProto::TYPE_INT32);
  1745. // Currently we only generate a warning for conflicting extension numbers.
  1746. // TODO(xiaofeng): Change it to an error.
  1747. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  1748. }
  1749. // ===================================================================
  1750. // Test reserved fields.
  1751. class ReservedDescriptorTest : public testing::Test {
  1752. protected:
  1753. virtual void SetUp() {
  1754. // Build descriptors for the following definitions:
  1755. //
  1756. // message Foo {
  1757. // reserved 2, 9 to 11, 15;
  1758. // reserved "foo", "bar";
  1759. // }
  1760. FileDescriptorProto foo_file;
  1761. foo_file.set_name("foo.proto");
  1762. DescriptorProto* foo = AddMessage(&foo_file, "Foo");
  1763. AddReservedRange(foo, 2, 3);
  1764. AddReservedRange(foo, 9, 12);
  1765. AddReservedRange(foo, 15, 16);
  1766. foo->add_reserved_name("foo");
  1767. foo->add_reserved_name("bar");
  1768. // Build the descriptors and get the pointers.
  1769. foo_file_ = pool_.BuildFile(foo_file);
  1770. ASSERT_TRUE(foo_file_ != nullptr);
  1771. ASSERT_EQ(1, foo_file_->message_type_count());
  1772. foo_ = foo_file_->message_type(0);
  1773. }
  1774. DescriptorPool pool_;
  1775. const FileDescriptor* foo_file_;
  1776. const Descriptor* foo_;
  1777. };
  1778. TEST_F(ReservedDescriptorTest, ReservedRanges) {
  1779. ASSERT_EQ(3, foo_->reserved_range_count());
  1780. EXPECT_EQ(2, foo_->reserved_range(0)->start);
  1781. EXPECT_EQ(3, foo_->reserved_range(0)->end);
  1782. EXPECT_EQ(9, foo_->reserved_range(1)->start);
  1783. EXPECT_EQ(12, foo_->reserved_range(1)->end);
  1784. EXPECT_EQ(15, foo_->reserved_range(2)->start);
  1785. EXPECT_EQ(16, foo_->reserved_range(2)->end);
  1786. }
  1787. TEST_F(ReservedDescriptorTest, IsReservedNumber) {
  1788. EXPECT_FALSE(foo_->IsReservedNumber(1));
  1789. EXPECT_TRUE(foo_->IsReservedNumber(2));
  1790. EXPECT_FALSE(foo_->IsReservedNumber(3));
  1791. EXPECT_FALSE(foo_->IsReservedNumber(8));
  1792. EXPECT_TRUE(foo_->IsReservedNumber(9));
  1793. EXPECT_TRUE(foo_->IsReservedNumber(10));
  1794. EXPECT_TRUE(foo_->IsReservedNumber(11));
  1795. EXPECT_FALSE(foo_->IsReservedNumber(12));
  1796. EXPECT_FALSE(foo_->IsReservedNumber(13));
  1797. EXPECT_FALSE(foo_->IsReservedNumber(14));
  1798. EXPECT_TRUE(foo_->IsReservedNumber(15));
  1799. EXPECT_FALSE(foo_->IsReservedNumber(16));
  1800. }
  1801. TEST_F(ReservedDescriptorTest, ReservedNames) {
  1802. ASSERT_EQ(2, foo_->reserved_name_count());
  1803. EXPECT_EQ("foo", foo_->reserved_name(0));
  1804. EXPECT_EQ("bar", foo_->reserved_name(1));
  1805. }
  1806. TEST_F(ReservedDescriptorTest, IsReservedName) {
  1807. EXPECT_TRUE(foo_->IsReservedName("foo"));
  1808. EXPECT_TRUE(foo_->IsReservedName("bar"));
  1809. EXPECT_FALSE(foo_->IsReservedName("baz"));
  1810. }
  1811. // ===================================================================
  1812. // Test reserved enum fields.
  1813. class ReservedEnumDescriptorTest : public testing::Test {
  1814. protected:
  1815. virtual void SetUp() {
  1816. // Build descriptors for the following definitions:
  1817. //
  1818. // enum Foo {
  1819. // BAR = 1;
  1820. // reserved 2, 9 to 11, 15;
  1821. // reserved "foo", "bar";
  1822. // }
  1823. FileDescriptorProto foo_file;
  1824. foo_file.set_name("foo.proto");
  1825. EnumDescriptorProto* foo = AddEnum(&foo_file, "Foo");
  1826. EnumDescriptorProto* edge1 = AddEnum(&foo_file, "Edge1");
  1827. EnumDescriptorProto* edge2 = AddEnum(&foo_file, "Edge2");
  1828. AddEnumValue(foo, "BAR", 4);
  1829. AddReservedRange(foo, -5, -3);
  1830. AddReservedRange(foo, -2, 1);
  1831. AddReservedRange(foo, 2, 3);
  1832. AddReservedRange(foo, 9, 12);
  1833. AddReservedRange(foo, 15, 16);
  1834. foo->add_reserved_name("foo");
  1835. foo->add_reserved_name("bar");
  1836. // Some additional edge cases that cover most or all of the range of enum
  1837. // values
  1838. // Note: We use INT_MAX as the maximum reserved range upper bound,
  1839. // inclusive.
  1840. AddEnumValue(edge1, "EDGE1", 1);
  1841. AddReservedRange(edge1, 10, INT_MAX);
  1842. AddEnumValue(edge2, "EDGE2", 15);
  1843. AddReservedRange(edge2, INT_MIN, 10);
  1844. // Build the descriptors and get the pointers.
  1845. foo_file_ = pool_.BuildFile(foo_file);
  1846. ASSERT_TRUE(foo_file_ != nullptr);
  1847. ASSERT_EQ(3, foo_file_->enum_type_count());
  1848. foo_ = foo_file_->enum_type(0);
  1849. edge1_ = foo_file_->enum_type(1);
  1850. edge2_ = foo_file_->enum_type(2);
  1851. }
  1852. DescriptorPool pool_;
  1853. const FileDescriptor* foo_file_;
  1854. const EnumDescriptor* foo_;
  1855. const EnumDescriptor* edge1_;
  1856. const EnumDescriptor* edge2_;
  1857. };
  1858. TEST_F(ReservedEnumDescriptorTest, ReservedRanges) {
  1859. ASSERT_EQ(5, foo_->reserved_range_count());
  1860. EXPECT_EQ(-5, foo_->reserved_range(0)->start);
  1861. EXPECT_EQ(-3, foo_->reserved_range(0)->end);
  1862. EXPECT_EQ(-2, foo_->reserved_range(1)->start);
  1863. EXPECT_EQ(1, foo_->reserved_range(1)->end);
  1864. EXPECT_EQ(2, foo_->reserved_range(2)->start);
  1865. EXPECT_EQ(3, foo_->reserved_range(2)->end);
  1866. EXPECT_EQ(9, foo_->reserved_range(3)->start);
  1867. EXPECT_EQ(12, foo_->reserved_range(3)->end);
  1868. EXPECT_EQ(15, foo_->reserved_range(4)->start);
  1869. EXPECT_EQ(16, foo_->reserved_range(4)->end);
  1870. ASSERT_EQ(1, edge1_->reserved_range_count());
  1871. EXPECT_EQ(10, edge1_->reserved_range(0)->start);
  1872. EXPECT_EQ(INT_MAX, edge1_->reserved_range(0)->end);
  1873. ASSERT_EQ(1, edge2_->reserved_range_count());
  1874. EXPECT_EQ(INT_MIN, edge2_->reserved_range(0)->start);
  1875. EXPECT_EQ(10, edge2_->reserved_range(0)->end);
  1876. }
  1877. TEST_F(ReservedEnumDescriptorTest, IsReservedNumber) {
  1878. EXPECT_TRUE(foo_->IsReservedNumber(-5));
  1879. EXPECT_TRUE(foo_->IsReservedNumber(-4));
  1880. EXPECT_TRUE(foo_->IsReservedNumber(-3));
  1881. EXPECT_TRUE(foo_->IsReservedNumber(-2));
  1882. EXPECT_TRUE(foo_->IsReservedNumber(-1));
  1883. EXPECT_TRUE(foo_->IsReservedNumber(0));
  1884. EXPECT_TRUE(foo_->IsReservedNumber(1));
  1885. EXPECT_TRUE(foo_->IsReservedNumber(2));
  1886. EXPECT_TRUE(foo_->IsReservedNumber(3));
  1887. EXPECT_FALSE(foo_->IsReservedNumber(8));
  1888. EXPECT_TRUE(foo_->IsReservedNumber(9));
  1889. EXPECT_TRUE(foo_->IsReservedNumber(10));
  1890. EXPECT_TRUE(foo_->IsReservedNumber(11));
  1891. EXPECT_TRUE(foo_->IsReservedNumber(12));
  1892. EXPECT_FALSE(foo_->IsReservedNumber(13));
  1893. EXPECT_FALSE(foo_->IsReservedNumber(13));
  1894. EXPECT_FALSE(foo_->IsReservedNumber(14));
  1895. EXPECT_TRUE(foo_->IsReservedNumber(15));
  1896. EXPECT_TRUE(foo_->IsReservedNumber(16));
  1897. EXPECT_FALSE(foo_->IsReservedNumber(17));
  1898. EXPECT_FALSE(edge1_->IsReservedNumber(9));
  1899. EXPECT_TRUE(edge1_->IsReservedNumber(10));
  1900. EXPECT_TRUE(edge1_->IsReservedNumber(INT_MAX - 1));
  1901. EXPECT_TRUE(edge1_->IsReservedNumber(INT_MAX));
  1902. EXPECT_TRUE(edge2_->IsReservedNumber(INT_MIN));
  1903. EXPECT_TRUE(edge2_->IsReservedNumber(9));
  1904. EXPECT_TRUE(edge2_->IsReservedNumber(10));
  1905. EXPECT_FALSE(edge2_->IsReservedNumber(11));
  1906. }
  1907. TEST_F(ReservedEnumDescriptorTest, ReservedNames) {
  1908. ASSERT_EQ(2, foo_->reserved_name_count());
  1909. EXPECT_EQ("foo", foo_->reserved_name(0));
  1910. EXPECT_EQ("bar", foo_->reserved_name(1));
  1911. }
  1912. TEST_F(ReservedEnumDescriptorTest, IsReservedName) {
  1913. EXPECT_TRUE(foo_->IsReservedName("foo"));
  1914. EXPECT_TRUE(foo_->IsReservedName("bar"));
  1915. EXPECT_FALSE(foo_->IsReservedName("baz"));
  1916. }
  1917. // ===================================================================
  1918. class MiscTest : public testing::Test {
  1919. protected:
  1920. // Function which makes a field descriptor of the given type.
  1921. const FieldDescriptor* GetFieldDescriptorOfType(FieldDescriptor::Type type) {
  1922. FileDescriptorProto file_proto;
  1923. file_proto.set_name("foo.proto");
  1924. AddEmptyEnum(&file_proto, "DummyEnum");
  1925. DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
  1926. FieldDescriptorProto* field = AddField(
  1927. message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
  1928. static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
  1929. if (type == FieldDescriptor::TYPE_MESSAGE ||
  1930. type == FieldDescriptor::TYPE_GROUP) {
  1931. field->set_type_name("TestMessage");
  1932. } else if (type == FieldDescriptor::TYPE_ENUM) {
  1933. field->set_type_name("DummyEnum");
  1934. }
  1935. // Build the descriptors and get the pointers.
  1936. pool_.reset(new DescriptorPool());
  1937. const FileDescriptor* file = pool_->BuildFile(file_proto);
  1938. if (file != nullptr && file->message_type_count() == 1 &&
  1939. file->message_type(0)->field_count() == 1) {
  1940. return file->message_type(0)->field(0);
  1941. } else {
  1942. return nullptr;
  1943. }
  1944. }
  1945. const char* GetTypeNameForFieldType(FieldDescriptor::Type type) {
  1946. const FieldDescriptor* field = GetFieldDescriptorOfType(type);
  1947. return field != nullptr ? field->type_name() : "";
  1948. }
  1949. FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
  1950. const FieldDescriptor* field = GetFieldDescriptorOfType(type);
  1951. return field != nullptr ? field->cpp_type()
  1952. : static_cast<FieldDescriptor::CppType>(0);
  1953. }
  1954. const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) {
  1955. const FieldDescriptor* field = GetFieldDescriptorOfType(type);
  1956. return field != nullptr ? field->cpp_type_name() : "";
  1957. }
  1958. const Descriptor* GetMessageDescriptorForFieldType(
  1959. FieldDescriptor::Type type) {
  1960. const FieldDescriptor* field = GetFieldDescriptorOfType(type);
  1961. return field != nullptr ? field->message_type() : nullptr;
  1962. }
  1963. const EnumDescriptor* GetEnumDescriptorForFieldType(
  1964. FieldDescriptor::Type type) {
  1965. const FieldDescriptor* field = GetFieldDescriptorOfType(type);
  1966. return field != nullptr ? field->enum_type() : nullptr;
  1967. }
  1968. std::unique_ptr<DescriptorPool> pool_;
  1969. };
  1970. TEST_F(MiscTest, TypeNames) {
  1971. // Test that correct type names are returned.
  1972. typedef FieldDescriptor FD; // avoid ugly line wrapping
  1973. EXPECT_STREQ("double", GetTypeNameForFieldType(FD::TYPE_DOUBLE));
  1974. EXPECT_STREQ("float", GetTypeNameForFieldType(FD::TYPE_FLOAT));
  1975. EXPECT_STREQ("int64", GetTypeNameForFieldType(FD::TYPE_INT64));
  1976. EXPECT_STREQ("uint64", GetTypeNameForFieldType(FD::TYPE_UINT64));
  1977. EXPECT_STREQ("int32", GetTypeNameForFieldType(FD::TYPE_INT32));
  1978. EXPECT_STREQ("fixed64", GetTypeNameForFieldType(FD::TYPE_FIXED64));
  1979. EXPECT_STREQ("fixed32", GetTypeNameForFieldType(FD::TYPE_FIXED32));
  1980. EXPECT_STREQ("bool", GetTypeNameForFieldType(FD::TYPE_BOOL));
  1981. EXPECT_STREQ("string", GetTypeNameForFieldType(FD::TYPE_STRING));
  1982. EXPECT_STREQ("group", GetTypeNameForFieldType(FD::TYPE_GROUP));
  1983. EXPECT_STREQ("message", GetTypeNameForFieldType(FD::TYPE_MESSAGE));
  1984. EXPECT_STREQ("bytes", GetTypeNameForFieldType(FD::TYPE_BYTES));
  1985. EXPECT_STREQ("uint32", GetTypeNameForFieldType(FD::TYPE_UINT32));
  1986. EXPECT_STREQ("enum", GetTypeNameForFieldType(FD::TYPE_ENUM));
  1987. EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
  1988. EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
  1989. EXPECT_STREQ("sint32", GetTypeNameForFieldType(FD::TYPE_SINT32));
  1990. EXPECT_STREQ("sint64", GetTypeNameForFieldType(FD::TYPE_SINT64));
  1991. }
  1992. TEST_F(MiscTest, StaticTypeNames) {
  1993. // Test that correct type names are returned.
  1994. typedef FieldDescriptor FD; // avoid ugly line wrapping
  1995. EXPECT_STREQ("double", FD::TypeName(FD::TYPE_DOUBLE));
  1996. EXPECT_STREQ("float", FD::TypeName(FD::TYPE_FLOAT));
  1997. EXPECT_STREQ("int64", FD::TypeName(FD::TYPE_INT64));
  1998. EXPECT_STREQ("uint64", FD::TypeName(FD::TYPE_UINT64));
  1999. EXPECT_STREQ("int32", FD::TypeName(FD::TYPE_INT32));
  2000. EXPECT_STREQ("fixed64", FD::TypeName(FD::TYPE_FIXED64));
  2001. EXPECT_STREQ("fixed32", FD::TypeName(FD::TYPE_FIXED32));
  2002. EXPECT_STREQ("bool", FD::TypeName(FD::TYPE_BOOL));
  2003. EXPECT_STREQ("string", FD::TypeName(FD::TYPE_STRING));
  2004. EXPECT_STREQ("group", FD::TypeName(FD::TYPE_GROUP));
  2005. EXPECT_STREQ("message", FD::TypeName(FD::TYPE_MESSAGE));
  2006. EXPECT_STREQ("bytes", FD::TypeName(FD::TYPE_BYTES));
  2007. EXPECT_STREQ("uint32", FD::TypeName(FD::TYPE_UINT32));
  2008. EXPECT_STREQ("enum", FD::TypeName(FD::TYPE_ENUM));
  2009. EXPECT_STREQ("sfixed32", FD::TypeName(FD::TYPE_SFIXED32));
  2010. EXPECT_STREQ("sfixed64", FD::TypeName(FD::TYPE_SFIXED64));
  2011. EXPECT_STREQ("sint32", FD::TypeName(FD::TYPE_SINT32));
  2012. EXPECT_STREQ("sint64", FD::TypeName(FD::TYPE_SINT64));
  2013. }
  2014. TEST_F(MiscTest, CppTypes) {
  2015. // Test that CPP types are assigned correctly.
  2016. typedef FieldDescriptor FD; // avoid ugly line wrapping
  2017. EXPECT_EQ(FD::CPPTYPE_DOUBLE, GetCppTypeForFieldType(FD::TYPE_DOUBLE));
  2018. EXPECT_EQ(FD::CPPTYPE_FLOAT, GetCppTypeForFieldType(FD::TYPE_FLOAT));
  2019. EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_INT64));
  2020. EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_UINT64));
  2021. EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_INT32));
  2022. EXPECT_EQ(FD::CPPTYPE_UINT64, GetCppTypeForFieldType(FD::TYPE_FIXED64));
  2023. EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_FIXED32));
  2024. EXPECT_EQ(FD::CPPTYPE_BOOL, GetCppTypeForFieldType(FD::TYPE_BOOL));
  2025. EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_STRING));
  2026. EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP));
  2027. EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE));
  2028. EXPECT_EQ(FD::CPPTYPE_STRING, GetCppTypeForFieldType(FD::TYPE_BYTES));
  2029. EXPECT_EQ(FD::CPPTYPE_UINT32, GetCppTypeForFieldType(FD::TYPE_UINT32));
  2030. EXPECT_EQ(FD::CPPTYPE_ENUM, GetCppTypeForFieldType(FD::TYPE_ENUM));
  2031. EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SFIXED32));
  2032. EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SFIXED64));
  2033. EXPECT_EQ(FD::CPPTYPE_INT32, GetCppTypeForFieldType(FD::TYPE_SINT32));
  2034. EXPECT_EQ(FD::CPPTYPE_INT64, GetCppTypeForFieldType(FD::TYPE_SINT64));
  2035. }
  2036. TEST_F(MiscTest, CppTypeNames) {
  2037. // Test that correct CPP type names are returned.
  2038. typedef FieldDescriptor FD; // avoid ugly line wrapping
  2039. EXPECT_STREQ("double", GetCppTypeNameForFieldType(FD::TYPE_DOUBLE));
  2040. EXPECT_STREQ("float", GetCppTypeNameForFieldType(FD::TYPE_FLOAT));
  2041. EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_INT64));
  2042. EXPECT_STREQ("uint64", GetCppTypeNameForFieldType(FD::TYPE_UINT64));
  2043. EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_INT32));
  2044. EXPECT_STREQ("uint64", GetCppTypeNameForFieldType(FD::TYPE_FIXED64));
  2045. EXPECT_STREQ("uint32", GetCppTypeNameForFieldType(FD::TYPE_FIXED32));
  2046. EXPECT_STREQ("bool", GetCppTypeNameForFieldType(FD::TYPE_BOOL));
  2047. EXPECT_STREQ("string", GetCppTypeNameForFieldType(FD::TYPE_STRING));
  2048. EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP));
  2049. EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE));
  2050. EXPECT_STREQ("string", GetCppTypeNameForFieldType(FD::TYPE_BYTES));
  2051. EXPECT_STREQ("uint32", GetCppTypeNameForFieldType(FD::TYPE_UINT32));
  2052. EXPECT_STREQ("enum", GetCppTypeNameForFieldType(FD::TYPE_ENUM));
  2053. EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
  2054. EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
  2055. EXPECT_STREQ("int32", GetCppTypeNameForFieldType(FD::TYPE_SINT32));
  2056. EXPECT_STREQ("int64", GetCppTypeNameForFieldType(FD::TYPE_SINT64));
  2057. }
  2058. TEST_F(MiscTest, StaticCppTypeNames) {
  2059. // Test that correct CPP type names are returned.
  2060. typedef FieldDescriptor FD; // avoid ugly line wrapping
  2061. EXPECT_STREQ("int32", FD::CppTypeName(FD::CPPTYPE_INT32));
  2062. EXPECT_STREQ("int64", FD::CppTypeName(FD::CPPTYPE_INT64));
  2063. EXPECT_STREQ("uint32", FD::CppTypeName(FD::CPPTYPE_UINT32));
  2064. EXPECT_STREQ("uint64", FD::CppTypeName(FD::CPPTYPE_UINT64));
  2065. EXPECT_STREQ("double", FD::CppTypeName(FD::CPPTYPE_DOUBLE));
  2066. EXPECT_STREQ("float", FD::CppTypeName(FD::CPPTYPE_FLOAT));
  2067. EXPECT_STREQ("bool", FD::CppTypeName(FD::CPPTYPE_BOOL));
  2068. EXPECT_STREQ("enum", FD::CppTypeName(FD::CPPTYPE_ENUM));
  2069. EXPECT_STREQ("string", FD::CppTypeName(FD::CPPTYPE_STRING));
  2070. EXPECT_STREQ("message", FD::CppTypeName(FD::CPPTYPE_MESSAGE));
  2071. }
  2072. TEST_F(MiscTest, MessageType) {
  2073. // Test that message_type() is nullptr for non-aggregate fields
  2074. typedef FieldDescriptor FD; // avoid ugly line wrapping
  2075. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_DOUBLE));
  2076. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FLOAT));
  2077. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT64));
  2078. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT64));
  2079. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_INT32));
  2080. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED64));
  2081. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_FIXED32));
  2082. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BOOL));
  2083. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_STRING));
  2084. EXPECT_TRUE(nullptr != GetMessageDescriptorForFieldType(FD::TYPE_GROUP));
  2085. EXPECT_TRUE(nullptr != GetMessageDescriptorForFieldType(FD::TYPE_MESSAGE));
  2086. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_BYTES));
  2087. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_UINT32));
  2088. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_ENUM));
  2089. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED32));
  2090. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED64));
  2091. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT32));
  2092. EXPECT_TRUE(nullptr == GetMessageDescriptorForFieldType(FD::TYPE_SINT64));
  2093. }
  2094. TEST_F(MiscTest, EnumType) {
  2095. // Test that enum_type() is nullptr for non-enum fields
  2096. typedef FieldDescriptor FD; // avoid ugly line wrapping
  2097. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_DOUBLE));
  2098. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FLOAT));
  2099. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT64));
  2100. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT64));
  2101. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_INT32));
  2102. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED64));
  2103. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_FIXED32));
  2104. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BOOL));
  2105. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_STRING));
  2106. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_GROUP));
  2107. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_MESSAGE));
  2108. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_BYTES));
  2109. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_UINT32));
  2110. EXPECT_TRUE(nullptr != GetEnumDescriptorForFieldType(FD::TYPE_ENUM));
  2111. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED32));
  2112. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED64));
  2113. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT32));
  2114. EXPECT_TRUE(nullptr == GetEnumDescriptorForFieldType(FD::TYPE_SINT64));
  2115. }
  2116. TEST_F(MiscTest, DefaultValues) {
  2117. // Test that setting default values works.
  2118. FileDescriptorProto file_proto;
  2119. file_proto.set_name("foo.proto");
  2120. EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
  2121. AddEnumValue(enum_type_proto, "A", 1);
  2122. AddEnumValue(enum_type_proto, "B", 2);
  2123. DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
  2124. typedef FieldDescriptorProto FD; // avoid ugly line wrapping
  2125. const FD::Label label = FD::LABEL_OPTIONAL;
  2126. // Create fields of every CPP type with default values.
  2127. AddField(message_proto, "int32", 1, label, FD::TYPE_INT32)
  2128. ->set_default_value("-1");
  2129. AddField(message_proto, "int64", 2, label, FD::TYPE_INT64)
  2130. ->set_default_value("-1000000000000");
  2131. AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
  2132. ->set_default_value("42");
  2133. AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
  2134. ->set_default_value("2000000000000");
  2135. AddField(message_proto, "float", 5, label, FD::TYPE_FLOAT)
  2136. ->set_default_value("4.5");
  2137. AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
  2138. ->set_default_value("10e100");
  2139. AddField(message_proto, "bool", 7, label, FD::TYPE_BOOL)
  2140. ->set_default_value("true");
  2141. AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
  2142. ->set_default_value("hello");
  2143. AddField(message_proto, "data", 9, label, FD::TYPE_BYTES)
  2144. ->set_default_value("\\001\\002\\003");
  2145. FieldDescriptorProto* enum_field =
  2146. AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
  2147. enum_field->set_type_name("DummyEnum");
  2148. enum_field->set_default_value("B");
  2149. // Strings are allowed to have empty defaults. (At one point, due to
  2150. // a bug, empty defaults for strings were rejected. Oops.)
  2151. AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
  2152. ->set_default_value("");
  2153. // Add a second set of fields with implicit default values.
  2154. AddField(message_proto, "implicit_int32", 21, label, FD::TYPE_INT32);
  2155. AddField(message_proto, "implicit_int64", 22, label, FD::TYPE_INT64);
  2156. AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
  2157. AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
  2158. AddField(message_proto, "implicit_float", 25, label, FD::TYPE_FLOAT);
  2159. AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
  2160. AddField(message_proto, "implicit_bool", 27, label, FD::TYPE_BOOL);
  2161. AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
  2162. AddField(message_proto, "implicit_data", 29, label, FD::TYPE_BYTES);
  2163. AddField(message_proto, "implicit_enum", 30, label, FD::TYPE_ENUM)
  2164. ->set_type_name("DummyEnum");
  2165. // Build it.
  2166. DescriptorPool pool;
  2167. const FileDescriptor* file = pool.BuildFile(file_proto);
  2168. ASSERT_TRUE(file != nullptr);
  2169. ASSERT_EQ(1, file->enum_type_count());
  2170. const EnumDescriptor* enum_type = file->enum_type(0);
  2171. ASSERT_EQ(2, enum_type->value_count());
  2172. const EnumValueDescriptor* enum_value_a = enum_type->value(0);
  2173. const EnumValueDescriptor* enum_value_b = enum_type->value(1);
  2174. ASSERT_EQ(1, file->message_type_count());
  2175. const Descriptor* message = file->message_type(0);
  2176. ASSERT_EQ(21, message->field_count());
  2177. // Check the default values.
  2178. ASSERT_TRUE(message->field(0)->has_default_value());
  2179. ASSERT_TRUE(message->field(1)->has_default_value());
  2180. ASSERT_TRUE(message->field(2)->has_default_value());
  2181. ASSERT_TRUE(message->field(3)->has_default_value());
  2182. ASSERT_TRUE(message->field(4)->has_default_value());
  2183. ASSERT_TRUE(message->field(5)->has_default_value());
  2184. ASSERT_TRUE(message->field(6)->has_default_value());
  2185. ASSERT_TRUE(message->field(7)->has_default_value());
  2186. ASSERT_TRUE(message->field(8)->has_default_value());
  2187. ASSERT_TRUE(message->field(9)->has_default_value());
  2188. ASSERT_TRUE(message->field(10)->has_default_value());
  2189. EXPECT_EQ(-1, message->field(0)->default_value_int32());
  2190. EXPECT_EQ(int64{-1000000000000}, message->field(1)->default_value_int64());
  2191. EXPECT_EQ(42, message->field(2)->default_value_uint32());
  2192. EXPECT_EQ(uint64{2000000000000}, message->field(3)->default_value_uint64());
  2193. EXPECT_EQ(4.5, message->field(4)->default_value_float());
  2194. EXPECT_EQ(10e100, message->field(5)->default_value_double());
  2195. EXPECT_TRUE(message->field(6)->default_value_bool());
  2196. EXPECT_EQ("hello", message->field(7)->default_value_string());
  2197. EXPECT_EQ("\001\002\003", message->field(8)->default_value_string());
  2198. EXPECT_EQ(enum_value_b, message->field(9)->default_value_enum());
  2199. EXPECT_EQ("", message->field(10)->default_value_string());
  2200. ASSERT_FALSE(message->field(11)->has_default_value());
  2201. ASSERT_FALSE(message->field(12)->has_default_value());
  2202. ASSERT_FALSE(message->field(13)->has_default_value());
  2203. ASSERT_FALSE(message->field(14)->has_default_value());
  2204. ASSERT_FALSE(message->field(15)->has_default_value());
  2205. ASSERT_FALSE(message->field(16)->has_default_value());
  2206. ASSERT_FALSE(message->field(17)->has_default_value());
  2207. ASSERT_FALSE(message->field(18)->has_default_value());
  2208. ASSERT_FALSE(message->field(19)->has_default_value());
  2209. ASSERT_FALSE(message->field(20)->has_default_value());
  2210. EXPECT_EQ(0, message->field(11)->default_value_int32());
  2211. EXPECT_EQ(0, message->field(12)->default_value_int64());
  2212. EXPECT_EQ(0, message->field(13)->default_value_uint32());
  2213. EXPECT_EQ(0, message->field(14)->default_value_uint64());
  2214. EXPECT_EQ(0.0f, message->field(15)->default_value_float());
  2215. EXPECT_EQ(0.0, message->field(16)->default_value_double());
  2216. EXPECT_FALSE(message->field(17)->default_value_bool());
  2217. EXPECT_EQ("", message->field(18)->default_value_string());
  2218. EXPECT_EQ("", message->field(19)->default_value_string());
  2219. EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
  2220. }
  2221. TEST_F(MiscTest, FieldOptions) {
  2222. // Try setting field options.
  2223. FileDescriptorProto file_proto;
  2224. file_proto.set_name("foo.proto");
  2225. DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
  2226. AddField(message_proto, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
  2227. FieldDescriptorProto::TYPE_INT32);
  2228. FieldDescriptorProto* bar_proto =
  2229. AddField(message_proto, "bar", 2, FieldDescriptorProto::LABEL_OPTIONAL,
  2230. FieldDescriptorProto::TYPE_INT32);
  2231. FieldOptions* options = bar_proto->mutable_options();
  2232. options->set_ctype(FieldOptions::CORD);
  2233. // Build the descriptors and get the pointers.
  2234. DescriptorPool pool;
  2235. const FileDescriptor* file = pool.BuildFile(file_proto);
  2236. ASSERT_TRUE(file != nullptr);
  2237. ASSERT_EQ(1, file->message_type_count());
  2238. const Descriptor* message = file->message_type(0);
  2239. ASSERT_EQ(2, message->field_count());
  2240. const FieldDescriptor* foo = message->field(0);
  2241. const FieldDescriptor* bar = message->field(1);
  2242. // "foo" had no options set, so it should return the default options.
  2243. EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
  2244. // "bar" had options set.
  2245. EXPECT_NE(&FieldOptions::default_instance(), options);
  2246. EXPECT_TRUE(bar->options().has_ctype());
  2247. EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
  2248. }
  2249. // ===================================================================
  2250. enum DescriptorPoolMode { NO_DATABASE, FALLBACK_DATABASE };
  2251. class AllowUnknownDependenciesTest
  2252. : public testing::TestWithParam<
  2253. std::tuple<DescriptorPoolMode, const char*>> {
  2254. protected:
  2255. DescriptorPoolMode mode() { return std::get<0>(GetParam()); }
  2256. const char* syntax() { return std::get<1>(GetParam()); }
  2257. virtual void SetUp() {
  2258. FileDescriptorProto foo_proto, bar_proto;
  2259. switch (mode()) {
  2260. case NO_DATABASE:
  2261. pool_.reset(new DescriptorPool);
  2262. break;
  2263. case FALLBACK_DATABASE:
  2264. pool_.reset(new DescriptorPool(&db_));
  2265. break;
  2266. }
  2267. pool_->AllowUnknownDependencies();
  2268. ASSERT_TRUE(TextFormat::ParseFromString(
  2269. "name: 'foo.proto'"
  2270. "dependency: 'bar.proto'"
  2271. "dependency: 'baz.proto'"
  2272. "message_type {"
  2273. " name: 'Foo'"
  2274. " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
  2275. " field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
  2276. " field { name:'qux' number:3 label:LABEL_OPTIONAL"
  2277. " type_name: '.corge.Qux'"
  2278. " type: TYPE_ENUM"
  2279. " options {"
  2280. " uninterpreted_option {"
  2281. " name {"
  2282. " name_part: 'grault'"
  2283. " is_extension: true"
  2284. " }"
  2285. " positive_int_value: 1234"
  2286. " }"
  2287. " }"
  2288. " }"
  2289. "}",
  2290. &foo_proto));
  2291. foo_proto.set_syntax(syntax());
  2292. ASSERT_TRUE(
  2293. TextFormat::ParseFromString("name: 'bar.proto'"
  2294. "message_type { name: 'Bar' }",
  2295. &bar_proto));
  2296. bar_proto.set_syntax(syntax());
  2297. // Collect pointers to stuff.
  2298. bar_file_ = BuildFile(bar_proto);
  2299. ASSERT_TRUE(bar_file_ != nullptr);
  2300. ASSERT_EQ(1, bar_file_->message_type_count());
  2301. bar_type_ = bar_file_->message_type(0);
  2302. foo_file_ = BuildFile(foo_proto);
  2303. ASSERT_TRUE(foo_file_ != nullptr);
  2304. ASSERT_EQ(1, foo_file_->message_type_count());
  2305. foo_type_ = foo_file_->message_type(0);
  2306. ASSERT_EQ(3, foo_type_->field_count());
  2307. bar_field_ = foo_type_->field(0);
  2308. baz_field_ = foo_type_->field(1);
  2309. qux_field_ = foo_type_->field(2);
  2310. }
  2311. const FileDescriptor* BuildFile(const FileDescriptorProto& proto) {
  2312. switch (mode()) {
  2313. case NO_DATABASE:
  2314. return pool_->BuildFile(proto);
  2315. break;
  2316. case FALLBACK_DATABASE: {
  2317. EXPECT_TRUE(db_.Add(proto));
  2318. return pool_->FindFileByName(proto.name());
  2319. }
  2320. }
  2321. GOOGLE_LOG(FATAL) << "Can't get here.";
  2322. return nullptr;
  2323. }
  2324. const FileDescriptor* bar_file_;
  2325. const Descriptor* bar_type_;
  2326. const FileDescriptor* foo_file_;
  2327. const Descriptor* foo_type_;
  2328. const FieldDescriptor* bar_field_;
  2329. const FieldDescriptor* baz_field_;
  2330. const FieldDescriptor* qux_field_;
  2331. SimpleDescriptorDatabase db_; // used if in FALLBACK_DATABASE mode.
  2332. std::unique_ptr<DescriptorPool> pool_;
  2333. };
  2334. TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
  2335. ASSERT_EQ(2, foo_file_->dependency_count());
  2336. EXPECT_EQ(bar_file_, foo_file_->dependency(0));
  2337. EXPECT_FALSE(bar_file_->is_placeholder());
  2338. const FileDescriptor* baz_file = foo_file_->dependency(1);
  2339. EXPECT_EQ("baz.proto", baz_file->name());
  2340. EXPECT_EQ(0, baz_file->message_type_count());
  2341. EXPECT_TRUE(baz_file->is_placeholder());
  2342. // Placeholder files should not be findable.
  2343. EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
  2344. EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == nullptr);
  2345. // Copy*To should not crash for placeholder files.
  2346. FileDescriptorProto baz_file_proto;
  2347. baz_file->CopyTo(&baz_file_proto);
  2348. baz_file->CopySourceCodeInfoTo(&baz_file_proto);
  2349. EXPECT_FALSE(baz_file_proto.has_source_code_info());
  2350. }
  2351. TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
  2352. ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
  2353. EXPECT_EQ(bar_type_, bar_field_->message_type());
  2354. EXPECT_FALSE(bar_type_->is_placeholder());
  2355. ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
  2356. const Descriptor* baz_type = baz_field_->message_type();
  2357. EXPECT_EQ("Baz", baz_type->name());
  2358. EXPECT_EQ("Baz", baz_type->full_name());
  2359. EXPECT_EQ(0, baz_type->extension_range_count());
  2360. EXPECT_TRUE(baz_type->is_placeholder());
  2361. ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
  2362. const EnumDescriptor* qux_type = qux_field_->enum_type();
  2363. EXPECT_EQ("Qux", qux_type->name());
  2364. EXPECT_EQ("corge.Qux", qux_type->full_name());
  2365. EXPECT_TRUE(qux_type->is_placeholder());
  2366. // Placeholder types should not be findable.
  2367. EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
  2368. EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == nullptr);
  2369. EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == nullptr);
  2370. }
  2371. TEST_P(AllowUnknownDependenciesTest, CopyTo) {
  2372. // FieldDescriptor::CopyTo() should write non-fully-qualified type names
  2373. // for placeholder types which were not originally fully-qualified.
  2374. FieldDescriptorProto proto;
  2375. // Bar is not a placeholder, so it is fully-qualified.
  2376. bar_field_->CopyTo(&proto);
  2377. EXPECT_EQ(".Bar", proto.type_name());
  2378. EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
  2379. // Baz is an unqualified placeholder.
  2380. proto.Clear();
  2381. baz_field_->CopyTo(&proto);
  2382. EXPECT_EQ("Baz", proto.type_name());
  2383. EXPECT_FALSE(proto.has_type());
  2384. // Qux is a fully-qualified placeholder.
  2385. proto.Clear();
  2386. qux_field_->CopyTo(&proto);
  2387. EXPECT_EQ(".corge.Qux", proto.type_name());
  2388. EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
  2389. }
  2390. TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
  2391. // Qux should still have the uninterpreted option attached.
  2392. ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
  2393. const UninterpretedOption& option =
  2394. qux_field_->options().uninterpreted_option(0);
  2395. ASSERT_EQ(1, option.name_size());
  2396. EXPECT_EQ("grault", option.name(0).name_part());
  2397. }
  2398. TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
  2399. // Test that we can extend an unknown type. This is slightly tricky because
  2400. // it means that the placeholder type must have an extension range.
  2401. FileDescriptorProto extension_proto;
  2402. ASSERT_TRUE(TextFormat::ParseFromString(
  2403. "name: 'extension.proto'"
  2404. "extension { extendee: 'UnknownType' name:'some_extension' number:123"
  2405. " label:LABEL_OPTIONAL type:TYPE_INT32 }",
  2406. &extension_proto));
  2407. const FileDescriptor* file = BuildFile(extension_proto);
  2408. ASSERT_TRUE(file != nullptr);
  2409. ASSERT_EQ(1, file->extension_count());
  2410. const Descriptor* extendee = file->extension(0)->containing_type();
  2411. EXPECT_EQ("UnknownType", extendee->name());
  2412. EXPECT_TRUE(extendee->is_placeholder());
  2413. ASSERT_EQ(1, extendee->extension_range_count());
  2414. EXPECT_EQ(1, extendee->extension_range(0)->start);
  2415. EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
  2416. }
  2417. TEST_P(AllowUnknownDependenciesTest, CustomOption) {
  2418. // Test that we can use a custom option without having parsed
  2419. // descriptor.proto.
  2420. FileDescriptorProto option_proto;
  2421. ASSERT_TRUE(TextFormat::ParseFromString(
  2422. "name: \"unknown_custom_options.proto\" "
  2423. "dependency: \"google/protobuf/descriptor.proto\" "
  2424. "extension { "
  2425. " extendee: \"google.protobuf.FileOptions\" "
  2426. " name: \"some_option\" "
  2427. " number: 123456 "
  2428. " label: LABEL_OPTIONAL "
  2429. " type: TYPE_INT32 "
  2430. "} "
  2431. "options { "
  2432. " uninterpreted_option { "
  2433. " name { "
  2434. " name_part: \"some_option\" "
  2435. " is_extension: true "
  2436. " } "
  2437. " positive_int_value: 1234 "
  2438. " } "
  2439. " uninterpreted_option { "
  2440. " name { "
  2441. " name_part: \"unknown_option\" "
  2442. " is_extension: true "
  2443. " } "
  2444. " positive_int_value: 1234 "
  2445. " } "
  2446. " uninterpreted_option { "
  2447. " name { "
  2448. " name_part: \"optimize_for\" "
  2449. " is_extension: false "
  2450. " } "
  2451. " identifier_value: \"SPEED\" "
  2452. " } "
  2453. "}",
  2454. &option_proto));
  2455. const FileDescriptor* file = BuildFile(option_proto);
  2456. ASSERT_TRUE(file != nullptr);
  2457. // Verify that no extension options were set, but they were left as
  2458. // uninterpreted_options.
  2459. std::vector<const FieldDescriptor*> fields;
  2460. file->options().GetReflection()->ListFields(file->options(), &fields);
  2461. ASSERT_EQ(2, fields.size());
  2462. EXPECT_TRUE(file->options().has_optimize_for());
  2463. EXPECT_EQ(2, file->options().uninterpreted_option_size());
  2464. }
  2465. TEST_P(AllowUnknownDependenciesTest,
  2466. UndeclaredDependencyTriggersBuildOfDependency) {
  2467. // Crazy case: suppose foo.proto refers to a symbol without declaring the
  2468. // dependency that finds it. In the event that the pool is backed by a
  2469. // DescriptorDatabase, the pool will attempt to find the symbol in the
  2470. // database. If successful, it will build the undeclared dependency to verify
  2471. // that the file does indeed contain the symbol. If that file fails to build,
  2472. // then its descriptors must be rolled back. However, we still want foo.proto
  2473. // to build successfully, since we are allowing unknown dependencies.
  2474. FileDescriptorProto undeclared_dep_proto;
  2475. // We make this file fail to build by giving it two fields with tag 1.
  2476. ASSERT_TRUE(TextFormat::ParseFromString(
  2477. "name: \"invalid_file_as_undeclared_dep.proto\" "
  2478. "package: \"undeclared\" "
  2479. "message_type: { "
  2480. " name: \"Quux\" "
  2481. " field { "
  2482. " name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
  2483. " }"
  2484. " field { "
  2485. " name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
  2486. " }"
  2487. "}",
  2488. &undeclared_dep_proto));
  2489. // We can't use the BuildFile() helper because we don't actually want to build
  2490. // it into the descriptor pool in the fallback database case: it just needs to
  2491. // be sitting in the database so that it gets built during the building of
  2492. // test.proto below.
  2493. switch (mode()) {
  2494. case NO_DATABASE: {
  2495. ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == nullptr);
  2496. break;
  2497. }
  2498. case FALLBACK_DATABASE: {
  2499. ASSERT_TRUE(db_.Add(undeclared_dep_proto));
  2500. }
  2501. }
  2502. FileDescriptorProto test_proto;
  2503. ASSERT_TRUE(TextFormat::ParseFromString(
  2504. "name: \"test.proto\" "
  2505. "message_type: { "
  2506. " name: \"Corge\" "
  2507. " field { "
  2508. " name:'quux' number:1 label: LABEL_OPTIONAL "
  2509. " type_name:'undeclared.Quux' type: TYPE_MESSAGE "
  2510. " }"
  2511. "}",
  2512. &test_proto));
  2513. const FileDescriptor* file = BuildFile(test_proto);
  2514. ASSERT_TRUE(file != nullptr);
  2515. GOOGLE_LOG(INFO) << file->DebugString();
  2516. EXPECT_EQ(0, file->dependency_count());
  2517. ASSERT_EQ(1, file->message_type_count());
  2518. const Descriptor* corge_desc = file->message_type(0);
  2519. ASSERT_EQ("Corge", corge_desc->name());
  2520. ASSERT_EQ(1, corge_desc->field_count());
  2521. EXPECT_FALSE(corge_desc->is_placeholder());
  2522. const FieldDescriptor* quux_field = corge_desc->field(0);
  2523. ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
  2524. ASSERT_EQ("Quux", quux_field->message_type()->name());
  2525. ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
  2526. EXPECT_TRUE(quux_field->message_type()->is_placeholder());
  2527. // The place holder type should not be findable.
  2528. ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == nullptr);
  2529. }
  2530. INSTANTIATE_TEST_SUITE_P(DatabaseSource, AllowUnknownDependenciesTest,
  2531. testing::Combine(testing::Values(NO_DATABASE,
  2532. FALLBACK_DATABASE),
  2533. testing::Values("proto2", "proto3")));
  2534. // ===================================================================
  2535. TEST(CustomOptions, OptionLocations) {
  2536. const Descriptor* message =
  2537. protobuf_unittest::TestMessageWithCustomOptions::descriptor();
  2538. const FileDescriptor* file = message->file();
  2539. const FieldDescriptor* field = message->FindFieldByName("field1");
  2540. const OneofDescriptor* oneof = message->FindOneofByName("AnOneof");
  2541. const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
  2542. // TODO(benjy): Support EnumValue options, once the compiler does.
  2543. const ServiceDescriptor* service =
  2544. file->FindServiceByName("TestServiceWithCustomOptions");
  2545. const MethodDescriptor* method = service->FindMethodByName("Foo");
  2546. EXPECT_EQ(int64{9876543210},
  2547. file->options().GetExtension(protobuf_unittest::file_opt1));
  2548. EXPECT_EQ(-56,
  2549. message->options().GetExtension(protobuf_unittest::message_opt1));
  2550. EXPECT_EQ(int64{8765432109},
  2551. field->options().GetExtension(protobuf_unittest::field_opt1));
  2552. EXPECT_EQ(42, // Check that we get the default for an option we don't set.
  2553. field->options().GetExtension(protobuf_unittest::field_opt2));
  2554. EXPECT_EQ(-99, oneof->options().GetExtension(protobuf_unittest::oneof_opt1));
  2555. EXPECT_EQ(-789, enm->options().GetExtension(protobuf_unittest::enum_opt1));
  2556. EXPECT_EQ(123, enm->value(1)->options().GetExtension(
  2557. protobuf_unittest::enum_value_opt1));
  2558. EXPECT_EQ(int64{-9876543210},
  2559. service->options().GetExtension(protobuf_unittest::service_opt1));
  2560. EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
  2561. method->options().GetExtension(protobuf_unittest::method_opt1));
  2562. // See that the regular options went through unscathed.
  2563. EXPECT_TRUE(message->options().has_message_set_wire_format());
  2564. EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
  2565. }
  2566. TEST(CustomOptions, OptionTypes) {
  2567. const MessageOptions* options = nullptr;
  2568. options =
  2569. &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
  2570. EXPECT_EQ(false, options->GetExtension(protobuf_unittest::bool_opt));
  2571. EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
  2572. EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
  2573. EXPECT_EQ(0, options->GetExtension(protobuf_unittest::uint32_opt));
  2574. EXPECT_EQ(0, options->GetExtension(protobuf_unittest::uint64_opt));
  2575. EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
  2576. EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
  2577. EXPECT_EQ(0, options->GetExtension(protobuf_unittest::fixed32_opt));
  2578. EXPECT_EQ(0, options->GetExtension(protobuf_unittest::fixed64_opt));
  2579. EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
  2580. EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
  2581. options =
  2582. &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
  2583. EXPECT_EQ(true, options->GetExtension(protobuf_unittest::bool_opt));
  2584. EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::int32_opt));
  2585. EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::int64_opt));
  2586. EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
  2587. EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
  2588. EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::sint32_opt));
  2589. EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::sint64_opt));
  2590. EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
  2591. EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
  2592. EXPECT_EQ(kint32max, options->GetExtension(protobuf_unittest::sfixed32_opt));
  2593. EXPECT_EQ(kint64max, options->GetExtension(protobuf_unittest::sfixed64_opt));
  2594. options = &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
  2595. EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
  2596. EXPECT_FLOAT_EQ(12.3456789,
  2597. options->GetExtension(protobuf_unittest::float_opt));
  2598. EXPECT_DOUBLE_EQ(1.234567890123456789,
  2599. options->GetExtension(protobuf_unittest::double_opt));
  2600. EXPECT_EQ("Hello, \"World\"",
  2601. options->GetExtension(protobuf_unittest::string_opt));
  2602. EXPECT_EQ(std::string("Hello\0World", 11),
  2603. options->GetExtension(protobuf_unittest::bytes_opt));
  2604. EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
  2605. options->GetExtension(protobuf_unittest::enum_opt));
  2606. options =
  2607. &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
  2608. EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
  2609. EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
  2610. options =
  2611. &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
  2612. EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
  2613. EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
  2614. }
  2615. TEST(CustomOptions, ComplexExtensionOptions) {
  2616. const MessageOptions* options =
  2617. &protobuf_unittest::VariousComplexOptions::descriptor()->options();
  2618. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
  2619. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1)
  2620. .GetExtension(protobuf_unittest::quux),
  2621. 324);
  2622. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1)
  2623. .GetExtension(protobuf_unittest::corge)
  2624. .qux(),
  2625. 876);
  2626. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
  2627. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
  2628. .GetExtension(protobuf_unittest::grault),
  2629. 654);
  2630. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
  2631. 743);
  2632. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
  2633. .bar()
  2634. .GetExtension(protobuf_unittest::quux),
  2635. 1999);
  2636. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
  2637. .bar()
  2638. .GetExtension(protobuf_unittest::corge)
  2639. .qux(),
  2640. 2008);
  2641. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
  2642. .GetExtension(protobuf_unittest::garply)
  2643. .foo(),
  2644. 741);
  2645. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
  2646. .GetExtension(protobuf_unittest::garply)
  2647. .GetExtension(protobuf_unittest::quux),
  2648. 1998);
  2649. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2)
  2650. .GetExtension(protobuf_unittest::garply)
  2651. .GetExtension(protobuf_unittest::corge)
  2652. .qux(),
  2653. 2121);
  2654. EXPECT_EQ(options
  2655. ->GetExtension(protobuf_unittest::ComplexOptionType2::
  2656. ComplexOptionType4::complex_opt4)
  2657. .waldo(),
  2658. 1971);
  2659. EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).fred().waldo(),
  2660. 321);
  2661. EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
  2662. EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3)
  2663. .complexoptiontype5()
  2664. .plugh());
  2665. EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
  2666. }
  2667. TEST(CustomOptions, OptionsFromOtherFile) {
  2668. // Test that to use a custom option, we only need to import the file
  2669. // defining the option; we do not also have to import descriptor.proto.
  2670. DescriptorPool pool;
  2671. FileDescriptorProto file_proto;
  2672. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
  2673. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2674. protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
  2675. &file_proto);
  2676. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2677. ASSERT_TRUE(TextFormat::ParseFromString(
  2678. "name: \"custom_options_import.proto\" "
  2679. "package: \"protobuf_unittest\" "
  2680. "dependency: \"google/protobuf/unittest_custom_options.proto\" "
  2681. "options { "
  2682. " uninterpreted_option { "
  2683. " name { "
  2684. " name_part: \"file_opt1\" "
  2685. " is_extension: true "
  2686. " } "
  2687. " positive_int_value: 1234 "
  2688. " } "
  2689. // Test a non-extension option too. (At one point this failed due to a
  2690. // bug.)
  2691. " uninterpreted_option { "
  2692. " name { "
  2693. " name_part: \"java_package\" "
  2694. " is_extension: false "
  2695. " } "
  2696. " string_value: \"foo\" "
  2697. " } "
  2698. // Test that enum-typed options still work too. (At one point this also
  2699. // failed due to a bug.)
  2700. " uninterpreted_option { "
  2701. " name { "
  2702. " name_part: \"optimize_for\" "
  2703. " is_extension: false "
  2704. " } "
  2705. " identifier_value: \"SPEED\" "
  2706. " } "
  2707. "}",
  2708. &file_proto));
  2709. const FileDescriptor* file = pool.BuildFile(file_proto);
  2710. ASSERT_TRUE(file != nullptr);
  2711. EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
  2712. EXPECT_TRUE(file->options().has_java_package());
  2713. EXPECT_EQ("foo", file->options().java_package());
  2714. EXPECT_TRUE(file->options().has_optimize_for());
  2715. EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
  2716. }
  2717. TEST(CustomOptions, MessageOptionThreeFieldsSet) {
  2718. // This tests a bug which previously existed in custom options parsing. The
  2719. // bug occurred when you defined a custom option with message type and then
  2720. // set three fields of that option on a single definition (see the example
  2721. // below). The bug is a bit hard to explain, so check the change history if
  2722. // you want to know more.
  2723. DescriptorPool pool;
  2724. FileDescriptorProto file_proto;
  2725. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
  2726. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2727. protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
  2728. &file_proto);
  2729. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2730. // The following represents the definition:
  2731. //
  2732. // import "google/protobuf/unittest_custom_options.proto"
  2733. // package protobuf_unittest;
  2734. // message Foo {
  2735. // option (complex_opt1).foo = 1234;
  2736. // option (complex_opt1).foo2 = 1234;
  2737. // option (complex_opt1).foo3 = 1234;
  2738. // }
  2739. ASSERT_TRUE(TextFormat::ParseFromString(
  2740. "name: \"custom_options_import.proto\" "
  2741. "package: \"protobuf_unittest\" "
  2742. "dependency: \"google/protobuf/unittest_custom_options.proto\" "
  2743. "message_type { "
  2744. " name: \"Foo\" "
  2745. " options { "
  2746. " uninterpreted_option { "
  2747. " name { "
  2748. " name_part: \"complex_opt1\" "
  2749. " is_extension: true "
  2750. " } "
  2751. " name { "
  2752. " name_part: \"foo\" "
  2753. " is_extension: false "
  2754. " } "
  2755. " positive_int_value: 1234 "
  2756. " } "
  2757. " uninterpreted_option { "
  2758. " name { "
  2759. " name_part: \"complex_opt1\" "
  2760. " is_extension: true "
  2761. " } "
  2762. " name { "
  2763. " name_part: \"foo2\" "
  2764. " is_extension: false "
  2765. " } "
  2766. " positive_int_value: 1234 "
  2767. " } "
  2768. " uninterpreted_option { "
  2769. " name { "
  2770. " name_part: \"complex_opt1\" "
  2771. " is_extension: true "
  2772. " } "
  2773. " name { "
  2774. " name_part: \"foo3\" "
  2775. " is_extension: false "
  2776. " } "
  2777. " positive_int_value: 1234 "
  2778. " } "
  2779. " } "
  2780. "}",
  2781. &file_proto));
  2782. const FileDescriptor* file = pool.BuildFile(file_proto);
  2783. ASSERT_TRUE(file != nullptr);
  2784. ASSERT_EQ(1, file->message_type_count());
  2785. const MessageOptions& options = file->message_type(0)->options();
  2786. EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
  2787. }
  2788. TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
  2789. // This test verifies that repeated fields in custom options can be
  2790. // given multiple values by repeating the option with a different value.
  2791. // This test checks repeated leaf values. Each repeated custom value
  2792. // appears in a different uninterpreted_option, which will be concatenated
  2793. // when they are merged into the final option value.
  2794. DescriptorPool pool;
  2795. FileDescriptorProto file_proto;
  2796. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
  2797. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2798. protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
  2799. &file_proto);
  2800. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2801. // The following represents the definition:
  2802. //
  2803. // import "google/protobuf/unittest_custom_options.proto"
  2804. // package protobuf_unittest;
  2805. // message Foo {
  2806. // option (complex_opt1).foo4 = 12;
  2807. // option (complex_opt1).foo4 = 34;
  2808. // option (complex_opt1).foo4 = 56;
  2809. // }
  2810. ASSERT_TRUE(TextFormat::ParseFromString(
  2811. "name: \"custom_options_import.proto\" "
  2812. "package: \"protobuf_unittest\" "
  2813. "dependency: \"google/protobuf/unittest_custom_options.proto\" "
  2814. "message_type { "
  2815. " name: \"Foo\" "
  2816. " options { "
  2817. " uninterpreted_option { "
  2818. " name { "
  2819. " name_part: \"complex_opt1\" "
  2820. " is_extension: true "
  2821. " } "
  2822. " name { "
  2823. " name_part: \"foo4\" "
  2824. " is_extension: false "
  2825. " } "
  2826. " positive_int_value: 12 "
  2827. " } "
  2828. " uninterpreted_option { "
  2829. " name { "
  2830. " name_part: \"complex_opt1\" "
  2831. " is_extension: true "
  2832. " } "
  2833. " name { "
  2834. " name_part: \"foo4\" "
  2835. " is_extension: false "
  2836. " } "
  2837. " positive_int_value: 34 "
  2838. " } "
  2839. " uninterpreted_option { "
  2840. " name { "
  2841. " name_part: \"complex_opt1\" "
  2842. " is_extension: true "
  2843. " } "
  2844. " name { "
  2845. " name_part: \"foo4\" "
  2846. " is_extension: false "
  2847. " } "
  2848. " positive_int_value: 56 "
  2849. " } "
  2850. " } "
  2851. "}",
  2852. &file_proto));
  2853. const FileDescriptor* file = pool.BuildFile(file_proto);
  2854. ASSERT_TRUE(file != nullptr);
  2855. ASSERT_EQ(1, file->message_type_count());
  2856. const MessageOptions& options = file->message_type(0)->options();
  2857. EXPECT_EQ(3, options.GetExtension(protobuf_unittest::complex_opt1).foo4_size());
  2858. EXPECT_EQ(12, options.GetExtension(protobuf_unittest::complex_opt1).foo4(0));
  2859. EXPECT_EQ(34, options.GetExtension(protobuf_unittest::complex_opt1).foo4(1));
  2860. EXPECT_EQ(56, options.GetExtension(protobuf_unittest::complex_opt1).foo4(2));
  2861. }
  2862. TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
  2863. // This test verifies that repeated fields in custom options can be
  2864. // given multiple values by repeating the option with a different value.
  2865. // This test checks repeated message values. Each repeated custom value
  2866. // appears in a different uninterpreted_option, which will be concatenated
  2867. // when they are merged into the final option value.
  2868. DescriptorPool pool;
  2869. FileDescriptorProto file_proto;
  2870. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
  2871. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2872. protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
  2873. &file_proto);
  2874. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2875. // The following represents the definition:
  2876. //
  2877. // import "google/protobuf/unittest_custom_options.proto"
  2878. // package protobuf_unittest;
  2879. // message Foo {
  2880. // option (complex_opt2).barney = {waldo: 1};
  2881. // option (complex_opt2).barney = {waldo: 10};
  2882. // option (complex_opt2).barney = {waldo: 100};
  2883. // }
  2884. ASSERT_TRUE(TextFormat::ParseFromString(
  2885. "name: \"custom_options_import.proto\" "
  2886. "package: \"protobuf_unittest\" "
  2887. "dependency: \"google/protobuf/unittest_custom_options.proto\" "
  2888. "message_type { "
  2889. " name: \"Foo\" "
  2890. " options { "
  2891. " uninterpreted_option { "
  2892. " name { "
  2893. " name_part: \"complex_opt2\" "
  2894. " is_extension: true "
  2895. " } "
  2896. " name { "
  2897. " name_part: \"barney\" "
  2898. " is_extension: false "
  2899. " } "
  2900. " aggregate_value: \"waldo: 1\" "
  2901. " } "
  2902. " uninterpreted_option { "
  2903. " name { "
  2904. " name_part: \"complex_opt2\" "
  2905. " is_extension: true "
  2906. " } "
  2907. " name { "
  2908. " name_part: \"barney\" "
  2909. " is_extension: false "
  2910. " } "
  2911. " aggregate_value: \"waldo: 10\" "
  2912. " } "
  2913. " uninterpreted_option { "
  2914. " name { "
  2915. " name_part: \"complex_opt2\" "
  2916. " is_extension: true "
  2917. " } "
  2918. " name { "
  2919. " name_part: \"barney\" "
  2920. " is_extension: false "
  2921. " } "
  2922. " aggregate_value: \"waldo: 100\" "
  2923. " } "
  2924. " } "
  2925. "}",
  2926. &file_proto));
  2927. const FileDescriptor* file = pool.BuildFile(file_proto);
  2928. ASSERT_TRUE(file != nullptr);
  2929. ASSERT_EQ(1, file->message_type_count());
  2930. const MessageOptions& options = file->message_type(0)->options();
  2931. EXPECT_EQ(3,
  2932. options.GetExtension(protobuf_unittest::complex_opt2).barney_size());
  2933. EXPECT_EQ(
  2934. 1, options.GetExtension(protobuf_unittest::complex_opt2).barney(0).waldo());
  2935. EXPECT_EQ(
  2936. 10,
  2937. options.GetExtension(protobuf_unittest::complex_opt2).barney(1).waldo());
  2938. EXPECT_EQ(
  2939. 100,
  2940. options.GetExtension(protobuf_unittest::complex_opt2).barney(2).waldo());
  2941. }
  2942. // Check that aggregate options were parsed and saved correctly in
  2943. // the appropriate descriptors.
  2944. TEST(CustomOptions, AggregateOptions) {
  2945. const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
  2946. const FileDescriptor* file = msg->file();
  2947. const FieldDescriptor* field = msg->FindFieldByName("fieldname");
  2948. const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
  2949. const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
  2950. const ServiceDescriptor* service =
  2951. file->FindServiceByName("AggregateService");
  2952. const MethodDescriptor* method = service->FindMethodByName("Method");
  2953. // Tests for the different types of data embedded in fileopt
  2954. const protobuf_unittest::Aggregate& file_options =
  2955. file->options().GetExtension(protobuf_unittest::fileopt);
  2956. EXPECT_EQ(100, file_options.i());
  2957. EXPECT_EQ("FileAnnotation", file_options.s());
  2958. EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
  2959. EXPECT_EQ("FileExtensionAnnotation",
  2960. file_options.file().GetExtension(protobuf_unittest::fileopt).s());
  2961. EXPECT_EQ("EmbeddedMessageSetElement",
  2962. file_options.mset()
  2963. .GetExtension(protobuf_unittest::AggregateMessageSetElement ::
  2964. message_set_extension)
  2965. .s());
  2966. // Simple tests for all the other types of annotations
  2967. EXPECT_EQ("MessageAnnotation",
  2968. msg->options().GetExtension(protobuf_unittest::msgopt).s());
  2969. EXPECT_EQ("FieldAnnotation",
  2970. field->options().GetExtension(protobuf_unittest::fieldopt).s());
  2971. EXPECT_EQ("EnumAnnotation",
  2972. enumd->options().GetExtension(protobuf_unittest::enumopt).s());
  2973. EXPECT_EQ("EnumValueAnnotation",
  2974. enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
  2975. EXPECT_EQ("ServiceAnnotation",
  2976. service->options().GetExtension(protobuf_unittest::serviceopt).s());
  2977. EXPECT_EQ("MethodAnnotation",
  2978. method->options().GetExtension(protobuf_unittest::methodopt).s());
  2979. }
  2980. TEST(CustomOptions, UnusedImportError) {
  2981. DescriptorPool pool;
  2982. FileDescriptorProto file_proto;
  2983. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
  2984. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2985. protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo(
  2986. &file_proto);
  2987. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  2988. pool.AddUnusedImportTrackFile("custom_options_import.proto", true);
  2989. ASSERT_TRUE(TextFormat::ParseFromString(
  2990. "name: \"custom_options_import.proto\" "
  2991. "package: \"protobuf_unittest\" "
  2992. "dependency: \"google/protobuf/unittest_custom_options.proto\" ",
  2993. &file_proto));
  2994. MockErrorCollector error_collector;
  2995. EXPECT_FALSE(pool.BuildFileCollectingErrors(file_proto, &error_collector));
  2996. EXPECT_EQ(
  2997. "custom_options_import.proto: "
  2998. "google/protobuf/unittest_custom_options.proto: IMPORT: Import "
  2999. "google/protobuf/unittest_custom_options.proto is unused.\n",
  3000. error_collector.text_);
  3001. }
  3002. // Verifies that proto files can correctly be parsed, even if the
  3003. // custom options defined in the file are incompatible with those
  3004. // compiled in the binary. See http://b/19276250.
  3005. TEST(CustomOptions, OptionsWithIncompatibleDescriptors) {
  3006. DescriptorPool pool;
  3007. FileDescriptorProto file_proto;
  3008. MessageOptions::descriptor()->file()->CopyTo(&file_proto);
  3009. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  3010. // Create a new file descriptor proto containing a subset of the
  3011. // messages defined in google/protobuf/unittest_custom_options.proto.
  3012. file_proto.Clear();
  3013. file_proto.set_name("unittest_custom_options.proto");
  3014. file_proto.set_package("protobuf_unittest");
  3015. file_proto.add_dependency("google/protobuf/descriptor.proto");
  3016. // Add the "required_enum_opt" extension.
  3017. FieldDescriptorProto* extension = file_proto.add_extension();
  3018. protobuf_unittest::OldOptionType::descriptor()
  3019. ->file()
  3020. ->FindExtensionByName("required_enum_opt")
  3021. ->CopyTo(extension);
  3022. // Add a test message that uses the "required_enum_opt" option.
  3023. DescriptorProto* test_message_type = file_proto.add_message_type();
  3024. protobuf_unittest::TestMessageWithRequiredEnumOption::descriptor()->CopyTo(
  3025. test_message_type);
  3026. // Instruct the extension to use NewOptionType instead of
  3027. // OldOptionType, and add the descriptor of NewOptionType.
  3028. extension->set_type_name(".protobuf_unittest.NewOptionType");
  3029. DescriptorProto* new_option_type = file_proto.add_message_type();
  3030. protobuf_unittest::NewOptionType::descriptor()->CopyTo(new_option_type);
  3031. // Replace the value of the "required_enum_opt" option used in the
  3032. // test message with an enum value that only exists in NewOptionType.
  3033. ASSERT_TRUE(
  3034. TextFormat::ParseFromString("uninterpreted_option { "
  3035. " name { "
  3036. " name_part: 'required_enum_opt' "
  3037. " is_extension: true "
  3038. " } "
  3039. " aggregate_value: 'value: NEW_VALUE'"
  3040. "}",
  3041. test_message_type->mutable_options()));
  3042. // Adding the file descriptor to the pool should fail.
  3043. EXPECT_TRUE(pool.BuildFile(file_proto) == nullptr);
  3044. }
  3045. // Test that FileDescriptor::DebugString() formats custom options correctly.
  3046. TEST(CustomOptions, DebugString) {
  3047. DescriptorPool pool;
  3048. FileDescriptorProto file_proto;
  3049. MessageOptions::descriptor()->file()->CopyTo(&file_proto);
  3050. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  3051. // Add "foo.proto":
  3052. // import "google/protobuf/descriptor.proto";
  3053. // package "protobuf_unittest";
  3054. // option (protobuf_unittest.cc_option1) = 1;
  3055. // option (protobuf_unittest.cc_option2) = 2;
  3056. // extend google.protobuf.FieldOptions {
  3057. // optional int32 cc_option1 = 7736974;
  3058. // optional int32 cc_option2 = 7736975;
  3059. // }
  3060. ASSERT_TRUE(TextFormat::ParseFromString(
  3061. "name: \"foo.proto\" "
  3062. "package: \"protobuf_unittest\" "
  3063. "dependency: \"google/protobuf/descriptor.proto\" "
  3064. "options { "
  3065. " uninterpreted_option { "
  3066. " name { "
  3067. " name_part: \"protobuf_unittest.cc_option1\" "
  3068. " is_extension: true "
  3069. " } "
  3070. " positive_int_value: 1 "
  3071. " } "
  3072. " uninterpreted_option { "
  3073. " name { "
  3074. " name_part: \"protobuf_unittest.cc_option2\" "
  3075. " is_extension: true "
  3076. " } "
  3077. " positive_int_value: 2 "
  3078. " } "
  3079. "} "
  3080. "extension { "
  3081. " name: \"cc_option1\" "
  3082. " extendee: \".google.protobuf.FileOptions\" "
  3083. // This field number is intentionally chosen to be the same as
  3084. // (.fileopt1) defined in unittest_custom_options.proto (linked
  3085. // in this test binary). This is to test whether we are messing
  3086. // generated pool with custom descriptor pools when dealing with
  3087. // custom options.
  3088. " number: 7736974 "
  3089. " label: LABEL_OPTIONAL "
  3090. " type: TYPE_INT32 "
  3091. "}"
  3092. "extension { "
  3093. " name: \"cc_option2\" "
  3094. " extendee: \".google.protobuf.FileOptions\" "
  3095. " number: 7736975 "
  3096. " label: LABEL_OPTIONAL "
  3097. " type: TYPE_INT32 "
  3098. "}",
  3099. &file_proto));
  3100. const FileDescriptor* descriptor = pool.BuildFile(file_proto);
  3101. ASSERT_TRUE(descriptor != nullptr);
  3102. EXPECT_EQ(2, descriptor->extension_count());
  3103. ASSERT_EQ(
  3104. "syntax = \"proto2\";\n"
  3105. "\n"
  3106. "import \"google/protobuf/descriptor.proto\";\n"
  3107. "package protobuf_unittest;\n"
  3108. "\n"
  3109. "option (.protobuf_unittest.cc_option1) = 1;\n"
  3110. "option (.protobuf_unittest.cc_option2) = 2;\n"
  3111. "\n"
  3112. "extend .google.protobuf.FileOptions {\n"
  3113. " optional int32 cc_option1 = 7736974;\n"
  3114. " optional int32 cc_option2 = 7736975;\n"
  3115. "}\n"
  3116. "\n",
  3117. descriptor->DebugString());
  3118. }
  3119. // ===================================================================
  3120. class ValidationErrorTest : public testing::Test {
  3121. protected:
  3122. // Parse file_text as a FileDescriptorProto in text format and add it
  3123. // to the DescriptorPool. Expect no errors.
  3124. const FileDescriptor* BuildFile(const std::string& file_text) {
  3125. FileDescriptorProto file_proto;
  3126. EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
  3127. return GOOGLE_CHECK_NOTNULL(pool_.BuildFile(file_proto));
  3128. }
  3129. // Parse file_text as a FileDescriptorProto in text format and add it
  3130. // to the DescriptorPool. Expect errors to be produced which match the
  3131. // given error text.
  3132. void BuildFileWithErrors(const std::string& file_text,
  3133. const std::string& expected_errors) {
  3134. FileDescriptorProto file_proto;
  3135. ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
  3136. MockErrorCollector error_collector;
  3137. EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector) ==
  3138. nullptr);
  3139. EXPECT_EQ(expected_errors, error_collector.text_);
  3140. }
  3141. // Parse file_text as a FileDescriptorProto in text format and add it
  3142. // to the DescriptorPool. Expect errors to be produced which match the
  3143. // given warning text.
  3144. void BuildFileWithWarnings(const std::string& file_text,
  3145. const std::string& expected_warnings) {
  3146. FileDescriptorProto file_proto;
  3147. ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
  3148. MockErrorCollector error_collector;
  3149. EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector));
  3150. EXPECT_EQ(expected_warnings, error_collector.warning_text_);
  3151. }
  3152. // Builds some already-parsed file in our test pool.
  3153. void BuildFileInTestPool(const FileDescriptor* file) {
  3154. FileDescriptorProto file_proto;
  3155. file->CopyTo(&file_proto);
  3156. ASSERT_TRUE(pool_.BuildFile(file_proto) != nullptr);
  3157. }
  3158. // Build descriptor.proto in our test pool. This allows us to extend it in
  3159. // the test pool, so we can test custom options.
  3160. void BuildDescriptorMessagesInTestPool() {
  3161. BuildFileInTestPool(DescriptorProto::descriptor()->file());
  3162. }
  3163. DescriptorPool pool_;
  3164. };
  3165. TEST_F(ValidationErrorTest, AlreadyDefined) {
  3166. BuildFileWithErrors(
  3167. "name: \"foo.proto\" "
  3168. "message_type { name: \"Foo\" }"
  3169. "message_type { name: \"Foo\" }",
  3170. "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
  3171. }
  3172. TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
  3173. BuildFileWithErrors(
  3174. "name: \"foo.proto\" "
  3175. "package: \"foo.bar\" "
  3176. "message_type { name: \"Foo\" }"
  3177. "message_type { name: \"Foo\" }",
  3178. "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
  3179. "\"foo.bar\".\n");
  3180. }
  3181. TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
  3182. BuildFile(
  3183. "name: \"foo.proto\" "
  3184. "message_type { name: \"Foo\" }");
  3185. BuildFileWithErrors(
  3186. "name: \"bar.proto\" "
  3187. "message_type { name: \"Foo\" }",
  3188. "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
  3189. "\"foo.proto\".\n");
  3190. }
  3191. TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
  3192. BuildFile(
  3193. "name: \"foo.proto\" "
  3194. "message_type { name: \"foo\" }");
  3195. BuildFileWithErrors(
  3196. "name: \"bar.proto\" "
  3197. "package: \"foo.bar\"",
  3198. "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
  3199. "than a package) in file \"foo.proto\".\n");
  3200. }
  3201. TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
  3202. BuildFileWithErrors(
  3203. "name: \"foo.proto\" "
  3204. "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
  3205. "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
  3206. "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
  3207. "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
  3208. "meaning that enum values are siblings of their type, not children of "
  3209. "it. Therefore, \"FOO\" must be unique within the global scope, not "
  3210. "just within \"Bar\".\n");
  3211. }
  3212. TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
  3213. BuildFileWithErrors(
  3214. "name: \"foo.proto\" "
  3215. "package: \"pkg\" "
  3216. "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
  3217. "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
  3218. "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
  3219. "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
  3220. "meaning that enum values are siblings of their type, not children of "
  3221. "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within "
  3222. "\"Bar\".\n");
  3223. }
  3224. TEST_F(ValidationErrorTest, MissingName) {
  3225. BuildFileWithErrors(
  3226. "name: \"foo.proto\" "
  3227. "message_type { }",
  3228. "foo.proto: : NAME: Missing name.\n");
  3229. }
  3230. TEST_F(ValidationErrorTest, InvalidName) {
  3231. BuildFileWithErrors(
  3232. "name: \"foo.proto\" "
  3233. "message_type { name: \"$\" }",
  3234. "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
  3235. }
  3236. TEST_F(ValidationErrorTest, InvalidPackageName) {
  3237. BuildFileWithErrors(
  3238. "name: \"foo.proto\" "
  3239. "package: \"foo.$\"",
  3240. "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
  3241. }
  3242. TEST_F(ValidationErrorTest, MissingFileName) {
  3243. BuildFileWithErrors("",
  3244. ": : OTHER: Missing field: FileDescriptorProto.name.\n");
  3245. }
  3246. TEST_F(ValidationErrorTest, DupeDependency) {
  3247. BuildFile("name: \"foo.proto\"");
  3248. BuildFileWithErrors(
  3249. "name: \"bar.proto\" "
  3250. "dependency: \"foo.proto\" "
  3251. "dependency: \"foo.proto\" ",
  3252. "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" was listed twice.\n");
  3253. }
  3254. TEST_F(ValidationErrorTest, UnknownDependency) {
  3255. BuildFileWithErrors(
  3256. "name: \"bar.proto\" "
  3257. "dependency: \"foo.proto\" ",
  3258. "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" has not been "
  3259. "loaded.\n");
  3260. }
  3261. TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) {
  3262. BuildFile("name: \"foo.proto\"");
  3263. BuildFileWithErrors(
  3264. "name: \"bar.proto\" "
  3265. "dependency: \"foo.proto\" "
  3266. "public_dependency: 1",
  3267. "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
  3268. }
  3269. TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
  3270. // Used to crash: If we depend on a non-existent file and then refer to a
  3271. // package defined in a file that we didn't import, and that package is
  3272. // nested within a parent package which this file is also in, and we don't
  3273. // include that parent package in the name (i.e. we do a relative lookup)...
  3274. // Yes, really.
  3275. BuildFile(
  3276. "name: 'foo.proto' "
  3277. "package: 'outer.foo' ");
  3278. BuildFileWithErrors(
  3279. "name: 'bar.proto' "
  3280. "dependency: 'baz.proto' "
  3281. "package: 'outer.bar' "
  3282. "message_type { "
  3283. " name: 'Bar' "
  3284. " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
  3285. "}",
  3286. "bar.proto: baz.proto: IMPORT: Import \"baz.proto\" has not been "
  3287. "loaded.\n"
  3288. "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined "
  3289. "in "
  3290. "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, "
  3291. "please add the necessary import.\n");
  3292. }
  3293. TEST_F(ValidationErrorTest, DupeFile) {
  3294. BuildFile(
  3295. "name: \"foo.proto\" "
  3296. "message_type { name: \"Foo\" }");
  3297. // Note: We should *not* get redundant errors about "Foo" already being
  3298. // defined.
  3299. BuildFileWithErrors(
  3300. "name: \"foo.proto\" "
  3301. "message_type { name: \"Foo\" } "
  3302. // Add another type so that the files aren't identical (in which case
  3303. // there would be no error).
  3304. "enum_type { name: \"Bar\" }",
  3305. "foo.proto: foo.proto: OTHER: A file with this name is already in the "
  3306. "pool.\n");
  3307. }
  3308. TEST_F(ValidationErrorTest, FieldInExtensionRange) {
  3309. BuildFileWithErrors(
  3310. "name: \"foo.proto\" "
  3311. "message_type {"
  3312. " name: \"Foo\""
  3313. " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3314. "}"
  3315. " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3316. "}"
  3317. " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3318. "}"
  3319. " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3320. "}"
  3321. " extension_range { start: 10 end: 20 }"
  3322. "}",
  3323. "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
  3324. "\"bar\" (10).\n"
  3325. "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
  3326. "\"baz\" (19).\n");
  3327. }
  3328. TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
  3329. BuildFileWithErrors(
  3330. "name: \"foo.proto\" "
  3331. "message_type {"
  3332. " name: \"Foo\""
  3333. " extension_range { start: 10 end: 20 }"
  3334. " extension_range { start: 20 end: 30 }"
  3335. " extension_range { start: 19 end: 21 }"
  3336. "}",
  3337. "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
  3338. "already-defined range 10 to 19.\n"
  3339. "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
  3340. "already-defined range 20 to 29.\n");
  3341. }
  3342. TEST_F(ValidationErrorTest, ReservedFieldError) {
  3343. BuildFileWithErrors(
  3344. "name: \"foo.proto\" "
  3345. "message_type {"
  3346. " name: \"Foo\""
  3347. " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3348. "}"
  3349. " reserved_range { start: 10 end: 20 }"
  3350. "}",
  3351. "foo.proto: Foo.foo: NUMBER: Field \"foo\" uses reserved number 15.\n");
  3352. }
  3353. TEST_F(ValidationErrorTest, ReservedExtensionRangeError) {
  3354. BuildFileWithErrors(
  3355. "name: \"foo.proto\" "
  3356. "message_type {"
  3357. " name: \"Foo\""
  3358. " extension_range { start: 10 end: 20 }"
  3359. " reserved_range { start: 5 end: 15 }"
  3360. "}",
  3361. "foo.proto: Foo: NUMBER: Extension range 10 to 19"
  3362. " overlaps with reserved range 5 to 14.\n");
  3363. }
  3364. TEST_F(ValidationErrorTest, ReservedExtensionRangeAdjacent) {
  3365. BuildFile(
  3366. "name: \"foo.proto\" "
  3367. "message_type {"
  3368. " name: \"Foo\""
  3369. " extension_range { start: 10 end: 20 }"
  3370. " reserved_range { start: 5 end: 10 }"
  3371. "}");
  3372. }
  3373. TEST_F(ValidationErrorTest, ReservedRangeOverlap) {
  3374. BuildFileWithErrors(
  3375. "name: \"foo.proto\" "
  3376. "message_type {"
  3377. " name: \"Foo\""
  3378. " reserved_range { start: 10 end: 20 }"
  3379. " reserved_range { start: 5 end: 15 }"
  3380. "}",
  3381. "foo.proto: Foo: NUMBER: Reserved range 5 to 14"
  3382. " overlaps with already-defined range 10 to 19.\n");
  3383. }
  3384. TEST_F(ValidationErrorTest, ReservedNameError) {
  3385. BuildFileWithErrors(
  3386. "name: \"foo.proto\" "
  3387. "message_type {"
  3388. " name: \"Foo\""
  3389. " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3390. "}"
  3391. " field { name: \"bar\" number: 16 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3392. "}"
  3393. " field { name: \"baz\" number: 17 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3394. "}"
  3395. " reserved_name: \"foo\""
  3396. " reserved_name: \"bar\""
  3397. "}",
  3398. "foo.proto: Foo.foo: NAME: Field name \"foo\" is reserved.\n"
  3399. "foo.proto: Foo.bar: NAME: Field name \"bar\" is reserved.\n");
  3400. }
  3401. TEST_F(ValidationErrorTest, ReservedNameRedundant) {
  3402. BuildFileWithErrors(
  3403. "name: \"foo.proto\" "
  3404. "message_type {"
  3405. " name: \"Foo\""
  3406. " reserved_name: \"foo\""
  3407. " reserved_name: \"foo\""
  3408. "}",
  3409. "foo.proto: foo: NAME: Field name \"foo\" is reserved multiple times.\n");
  3410. }
  3411. TEST_F(ValidationErrorTest, ReservedFieldsDebugString) {
  3412. const FileDescriptor* file = BuildFile(
  3413. "name: \"foo.proto\" "
  3414. "message_type {"
  3415. " name: \"Foo\""
  3416. " reserved_name: \"foo\""
  3417. " reserved_name: \"bar\""
  3418. " reserved_range { start: 5 end: 6 }"
  3419. " reserved_range { start: 10 end: 20 }"
  3420. "}");
  3421. ASSERT_EQ(
  3422. "syntax = \"proto2\";\n\n"
  3423. "message Foo {\n"
  3424. " reserved 5, 10 to 19;\n"
  3425. " reserved \"foo\", \"bar\";\n"
  3426. "}\n\n",
  3427. file->DebugString());
  3428. }
  3429. TEST_F(ValidationErrorTest, EnumReservedFieldError) {
  3430. BuildFileWithErrors(
  3431. "name: \"foo.proto\" "
  3432. "enum_type {"
  3433. " name: \"Foo\""
  3434. " value { name:\"BAR\" number:15 }"
  3435. " reserved_range { start: 10 end: 20 }"
  3436. "}",
  3437. "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number 15.\n");
  3438. }
  3439. TEST_F(ValidationErrorTest, EnumNegativeReservedFieldError) {
  3440. BuildFileWithErrors(
  3441. "name: \"foo.proto\" "
  3442. "enum_type {"
  3443. " name: \"Foo\""
  3444. " value { name:\"BAR\" number:-15 }"
  3445. " reserved_range { start: -20 end: -10 }"
  3446. "}",
  3447. "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number -15.\n");
  3448. }
  3449. TEST_F(ValidationErrorTest, EnumReservedRangeOverlap) {
  3450. BuildFileWithErrors(
  3451. "name: \"foo.proto\" "
  3452. "enum_type {"
  3453. " name: \"Foo\""
  3454. " value { name:\"BAR\" number:0 }"
  3455. " reserved_range { start: 10 end: 20 }"
  3456. " reserved_range { start: 5 end: 15 }"
  3457. "}",
  3458. "foo.proto: Foo: NUMBER: Reserved range 5 to 15"
  3459. " overlaps with already-defined range 10 to 20.\n");
  3460. }
  3461. TEST_F(ValidationErrorTest, EnumReservedRangeOverlapByOne) {
  3462. BuildFileWithErrors(
  3463. "name: \"foo.proto\" "
  3464. "enum_type {"
  3465. " name: \"Foo\""
  3466. " value { name:\"BAR\" number:0 }"
  3467. " reserved_range { start: 10 end: 20 }"
  3468. " reserved_range { start: 5 end: 10 }"
  3469. "}",
  3470. "foo.proto: Foo: NUMBER: Reserved range 5 to 10"
  3471. " overlaps with already-defined range 10 to 20.\n");
  3472. }
  3473. TEST_F(ValidationErrorTest, EnumNegativeReservedRangeOverlap) {
  3474. BuildFileWithErrors(
  3475. "name: \"foo.proto\" "
  3476. "enum_type {"
  3477. " name: \"Foo\""
  3478. " value { name:\"BAR\" number:0 }"
  3479. " reserved_range { start: -20 end: -10 }"
  3480. " reserved_range { start: -15 end: -5 }"
  3481. "}",
  3482. "foo.proto: Foo: NUMBER: Reserved range -15 to -5"
  3483. " overlaps with already-defined range -20 to -10.\n");
  3484. }
  3485. TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap) {
  3486. BuildFileWithErrors(
  3487. "name: \"foo.proto\" "
  3488. "enum_type {"
  3489. " name: \"Foo\""
  3490. " value { name:\"BAR\" number:20 }"
  3491. " reserved_range { start: -20 end: 10 }"
  3492. " reserved_range { start: -15 end: 5 }"
  3493. "}",
  3494. "foo.proto: Foo: NUMBER: Reserved range -15 to 5"
  3495. " overlaps with already-defined range -20 to 10.\n");
  3496. }
  3497. TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap2) {
  3498. BuildFileWithErrors(
  3499. "name: \"foo.proto\" "
  3500. "enum_type {"
  3501. " name: \"Foo\""
  3502. " value { name:\"BAR\" number:20 }"
  3503. " reserved_range { start: -20 end: 10 }"
  3504. " reserved_range { start: 10 end: 10 }"
  3505. "}",
  3506. "foo.proto: Foo: NUMBER: Reserved range 10 to 10"
  3507. " overlaps with already-defined range -20 to 10.\n");
  3508. }
  3509. TEST_F(ValidationErrorTest, EnumReservedRangeStartGreaterThanEnd) {
  3510. BuildFileWithErrors(
  3511. "name: \"foo.proto\" "
  3512. "enum_type {"
  3513. " name: \"Foo\""
  3514. " value { name:\"BAR\" number:20 }"
  3515. " reserved_range { start: 11 end: 10 }"
  3516. "}",
  3517. "foo.proto: Foo: NUMBER: Reserved range end number must be greater"
  3518. " than start number.\n");
  3519. }
  3520. TEST_F(ValidationErrorTest, EnumReservedNameError) {
  3521. BuildFileWithErrors(
  3522. "name: \"foo.proto\" "
  3523. "enum_type {"
  3524. " name: \"Foo\""
  3525. " value { name:\"FOO\" number:15 }"
  3526. " value { name:\"BAR\" number:15 }"
  3527. " reserved_name: \"FOO\""
  3528. " reserved_name: \"BAR\""
  3529. "}",
  3530. "foo.proto: FOO: NAME: Enum value \"FOO\" is reserved.\n"
  3531. "foo.proto: BAR: NAME: Enum value \"BAR\" is reserved.\n");
  3532. }
  3533. TEST_F(ValidationErrorTest, EnumReservedNameRedundant) {
  3534. BuildFileWithErrors(
  3535. "name: \"foo.proto\" "
  3536. "enum_type {"
  3537. " name: \"Foo\""
  3538. " value { name:\"FOO\" number:15 }"
  3539. " reserved_name: \"foo\""
  3540. " reserved_name: \"foo\""
  3541. "}",
  3542. "foo.proto: foo: NAME: Enum value \"foo\" is reserved multiple times.\n");
  3543. }
  3544. TEST_F(ValidationErrorTest, EnumReservedFieldsDebugString) {
  3545. const FileDescriptor* file = BuildFile(
  3546. "name: \"foo.proto\" "
  3547. "enum_type {"
  3548. " name: \"Foo\""
  3549. " value { name:\"FOO\" number:3 }"
  3550. " reserved_name: \"foo\""
  3551. " reserved_name: \"bar\""
  3552. " reserved_range { start: -6 end: -6 }"
  3553. " reserved_range { start: -5 end: -4 }"
  3554. " reserved_range { start: -1 end: 1 }"
  3555. " reserved_range { start: 5 end: 5 }"
  3556. " reserved_range { start: 10 end: 19 }"
  3557. "}");
  3558. ASSERT_EQ(
  3559. "syntax = \"proto2\";\n\n"
  3560. "enum Foo {\n"
  3561. " FOO = 3;\n"
  3562. " reserved -6, -5 to -4, -1 to 1, 5, 10 to 19;\n"
  3563. " reserved \"foo\", \"bar\";\n"
  3564. "}\n\n",
  3565. file->DebugString());
  3566. }
  3567. TEST_F(ValidationErrorTest, InvalidDefaults) {
  3568. BuildFileWithErrors(
  3569. "name: \"foo.proto\" "
  3570. "message_type {"
  3571. " name: \"Foo\""
  3572. // Invalid number.
  3573. " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
  3574. " default_value: \"abc\" }"
  3575. // Empty default value.
  3576. " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
  3577. " default_value: \"\" }"
  3578. // Invalid boolean.
  3579. " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
  3580. " default_value: \"abc\" }"
  3581. // Messages can't have defaults.
  3582. " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: "
  3583. "TYPE_MESSAGE"
  3584. " default_value: \"abc\" type_name: \"Foo\" }"
  3585. // Same thing, but we don't know that this field has message type until
  3586. // we look up the type name.
  3587. " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
  3588. " default_value: \"abc\" type_name: \"Foo\" }"
  3589. // Repeateds can't have defaults.
  3590. " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: "
  3591. "TYPE_INT32"
  3592. " default_value: \"1\" }"
  3593. "}",
  3594. "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value "
  3595. "\"abc\".\n"
  3596. "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value \"\".\n"
  3597. "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
  3598. "false.\n"
  3599. "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
  3600. "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
  3601. "values.\n"
  3602. // This ends up being reported later because the error is detected at
  3603. // cross-linking time.
  3604. "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
  3605. "values.\n");
  3606. }
  3607. TEST_F(ValidationErrorTest, NegativeFieldNumber) {
  3608. BuildFileWithErrors(
  3609. "name: \"foo.proto\" "
  3610. "message_type {"
  3611. " name: \"Foo\""
  3612. " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3613. "}"
  3614. "}",
  3615. "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
  3616. }
  3617. TEST_F(ValidationErrorTest, HugeFieldNumber) {
  3618. BuildFileWithErrors(
  3619. "name: \"foo.proto\" "
  3620. "message_type {"
  3621. " name: \"Foo\""
  3622. " field { name: \"foo\" number: 0x70000000 "
  3623. " label:LABEL_OPTIONAL type:TYPE_INT32 }"
  3624. "}",
  3625. "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
  3626. "536870911.\n");
  3627. }
  3628. TEST_F(ValidationErrorTest, ReservedFieldNumber) {
  3629. BuildFileWithErrors(
  3630. "name: \"foo.proto\" "
  3631. "message_type {"
  3632. " name: \"Foo\""
  3633. " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL "
  3634. "type:TYPE_INT32 }"
  3635. " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL "
  3636. "type:TYPE_INT32 }"
  3637. " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL "
  3638. "type:TYPE_INT32 }"
  3639. " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL "
  3640. "type:TYPE_INT32 }"
  3641. "}",
  3642. "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
  3643. "reserved for the protocol buffer library implementation.\n"
  3644. "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
  3645. "reserved for the protocol buffer library implementation.\n");
  3646. }
  3647. TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
  3648. BuildFileWithErrors(
  3649. "name: \"foo.proto\" "
  3650. "message_type {"
  3651. " name: \"Foo\""
  3652. " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
  3653. " type_name: \"Foo\" }"
  3654. "}",
  3655. "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
  3656. "extension field.\n");
  3657. }
  3658. TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
  3659. BuildFileWithErrors(
  3660. "name: \"foo.proto\" "
  3661. "message_type {"
  3662. " name: \"Bar\""
  3663. " extension_range { start: 1 end: 2 }"
  3664. "}"
  3665. "message_type {"
  3666. " name: \"Foo\""
  3667. " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
  3668. " type_name: \"Foo\" extendee: \"Bar\" }"
  3669. "}",
  3670. "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
  3671. "non-extension field.\n");
  3672. }
  3673. TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) {
  3674. BuildFileWithErrors(
  3675. "name: \"foo.proto\" "
  3676. "message_type {"
  3677. " name: \"Foo\""
  3678. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3679. " oneof_index: 1 }"
  3680. " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3681. " oneof_index: 0 }"
  3682. " oneof_decl { name:\"bar\" }"
  3683. "}",
  3684. "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index 1 is out of "
  3685. "range for type \"Foo\".\n");
  3686. }
  3687. TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
  3688. BuildFileWithErrors(
  3689. "name: \"foo.proto\" "
  3690. "message_type {"
  3691. " name: \"Foo\""
  3692. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3693. " oneof_index: -1 }"
  3694. " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3695. " oneof_index: 0 }"
  3696. " oneof_decl { name:\"bar\" }"
  3697. "}",
  3698. "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index -1 is out "
  3699. "of "
  3700. "range for type \"Foo\".\n");
  3701. }
  3702. TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) {
  3703. // Fields belonging to the same oneof must be defined consecutively.
  3704. BuildFileWithErrors(
  3705. "name: \"foo.proto\" "
  3706. "message_type {"
  3707. " name: \"Foo\""
  3708. " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3709. " oneof_index: 0 }"
  3710. " field { name:\"bar\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  3711. " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3712. " oneof_index: 0 }"
  3713. " oneof_decl { name:\"foos\" }"
  3714. "}",
  3715. "foo.proto: Foo.bar: TYPE: Fields in the same oneof must be defined "
  3716. "consecutively. \"bar\" cannot be defined before the completion of the "
  3717. "\"foos\" oneof definition.\n");
  3718. // Prevent interleaved fields, which belong to different oneofs.
  3719. BuildFileWithErrors(
  3720. "name: \"foo2.proto\" "
  3721. "message_type {"
  3722. " name: \"Foo2\""
  3723. " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3724. " oneof_index: 0 }"
  3725. " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3726. " oneof_index: 1 }"
  3727. " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3728. " oneof_index: 0 }"
  3729. " field { name:\"bar2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3730. " oneof_index: 1 }"
  3731. " oneof_decl { name:\"foos\" }"
  3732. " oneof_decl { name:\"bars\" }"
  3733. "}",
  3734. "foo2.proto: Foo2.bar1: TYPE: Fields in the same oneof must be defined "
  3735. "consecutively. \"bar1\" cannot be defined before the completion of the "
  3736. "\"foos\" oneof definition.\n"
  3737. "foo2.proto: Foo2.foo2: TYPE: Fields in the same oneof must be defined "
  3738. "consecutively. \"foo2\" cannot be defined before the completion of the "
  3739. "\"bars\" oneof definition.\n");
  3740. // Another case for normal fields and different oneof fields interleave.
  3741. BuildFileWithErrors(
  3742. "name: \"foo3.proto\" "
  3743. "message_type {"
  3744. " name: \"Foo3\""
  3745. " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3746. " oneof_index: 0 }"
  3747. " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3748. " oneof_index: 1 }"
  3749. " field { name:\"baz\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  3750. " field { name:\"foo2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
  3751. " oneof_index: 0 }"
  3752. " oneof_decl { name:\"foos\" }"
  3753. " oneof_decl { name:\"bars\" }"
  3754. "}",
  3755. "foo3.proto: Foo3.baz: TYPE: Fields in the same oneof must be defined "
  3756. "consecutively. \"baz\" cannot be defined before the completion of the "
  3757. "\"foos\" oneof definition.\n");
  3758. }
  3759. TEST_F(ValidationErrorTest, FieldNumberConflict) {
  3760. BuildFileWithErrors(
  3761. "name: \"foo.proto\" "
  3762. "message_type {"
  3763. " name: \"Foo\""
  3764. " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  3765. " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  3766. "}",
  3767. "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
  3768. "\"Foo\" by field \"foo\".\n");
  3769. }
  3770. TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
  3771. BuildFileWithErrors(
  3772. "name: \"foo.proto\" "
  3773. "message_type {"
  3774. " name: \"MessageSet\""
  3775. " options { message_set_wire_format: true }"
  3776. " extension_range { start: 4 end: 5 }"
  3777. "}"
  3778. "message_type {"
  3779. " name: \"Foo\""
  3780. " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
  3781. " extendee: \"MessageSet\" }"
  3782. "}",
  3783. "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
  3784. "messages.\n");
  3785. }
  3786. TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
  3787. BuildFileWithErrors(
  3788. "name: \"foo.proto\" "
  3789. "message_type {"
  3790. " name: \"MessageSet\""
  3791. " options { message_set_wire_format: true }"
  3792. " extension_range { start: 4 end: 5 }"
  3793. "}"
  3794. "message_type {"
  3795. " name: \"Foo\""
  3796. " extension { name:\"foo\" number:4 label:LABEL_REPEATED "
  3797. "type:TYPE_MESSAGE"
  3798. " type_name: \"Foo\" extendee: \"MessageSet\" }"
  3799. "}",
  3800. "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
  3801. "messages.\n");
  3802. }
  3803. TEST_F(ValidationErrorTest, FieldInMessageSet) {
  3804. BuildFileWithErrors(
  3805. "name: \"foo.proto\" "
  3806. "message_type {"
  3807. " name: \"Foo\""
  3808. " options { message_set_wire_format: true }"
  3809. " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  3810. "}",
  3811. "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
  3812. "extensions.\n");
  3813. }
  3814. TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
  3815. BuildFileWithErrors(
  3816. "name: \"foo.proto\" "
  3817. "message_type {"
  3818. " name: \"Foo\""
  3819. " extension_range { start: -10 end: -1 }"
  3820. "}",
  3821. "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
  3822. }
  3823. TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
  3824. BuildFileWithErrors(
  3825. "name: \"foo.proto\" "
  3826. "message_type {"
  3827. " name: \"Foo\""
  3828. " extension_range { start: 1 end: 0x70000000 }"
  3829. "}",
  3830. "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
  3831. "536870911.\n");
  3832. }
  3833. TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
  3834. BuildFileWithErrors(
  3835. "name: \"foo.proto\" "
  3836. "message_type {"
  3837. " name: \"Foo\""
  3838. " extension_range { start: 10 end: 10 }"
  3839. " extension_range { start: 10 end: 5 }"
  3840. "}",
  3841. "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
  3842. "start number.\n"
  3843. "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
  3844. "start number.\n");
  3845. }
  3846. TEST_F(ValidationErrorTest, EmptyEnum) {
  3847. BuildFileWithErrors(
  3848. "name: \"foo.proto\" "
  3849. "enum_type { name: \"Foo\" }"
  3850. // Also use the empty enum in a message to make sure there are no crashes
  3851. // during validation (possible if the code attempts to derive a default
  3852. // value for the field).
  3853. "message_type {"
  3854. " name: \"Bar\""
  3855. " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL "
  3856. "type_name:\"Foo\" }"
  3857. " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL "
  3858. "type_name:\"Foo\" "
  3859. " default_value: \"NO_SUCH_VALUE\" }"
  3860. "}",
  3861. "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
  3862. "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
  3863. "\"NO_SUCH_VALUE\".\n");
  3864. }
  3865. TEST_F(ValidationErrorTest, UndefinedExtendee) {
  3866. BuildFileWithErrors(
  3867. "name: \"foo.proto\" "
  3868. "message_type {"
  3869. " name: \"Foo\""
  3870. " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
  3871. " extendee: \"Bar\" }"
  3872. "}",
  3873. "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
  3874. }
  3875. TEST_F(ValidationErrorTest, NonMessageExtendee) {
  3876. BuildFileWithErrors(
  3877. "name: \"foo.proto\" "
  3878. "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
  3879. "message_type {"
  3880. " name: \"Foo\""
  3881. " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
  3882. " extendee: \"Bar\" }"
  3883. "}",
  3884. "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
  3885. }
  3886. TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
  3887. BuildFileWithErrors(
  3888. "name: \"foo.proto\" "
  3889. "message_type {"
  3890. " name: \"Bar\""
  3891. "}"
  3892. "message_type {"
  3893. " name: \"Foo\""
  3894. " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
  3895. " extendee: \"Bar\" }"
  3896. "}",
  3897. "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
  3898. "number.\n");
  3899. }
  3900. TEST_F(ValidationErrorTest, RequiredExtension) {
  3901. BuildFileWithErrors(
  3902. "name: \"foo.proto\" "
  3903. "message_type {"
  3904. " name: \"Bar\""
  3905. " extension_range { start: 1000 end: 10000 }"
  3906. "}"
  3907. "message_type {"
  3908. " name: \"Foo\""
  3909. " extension {"
  3910. " name:\"foo\""
  3911. " number:1000"
  3912. " label:LABEL_REQUIRED"
  3913. " type:TYPE_INT32"
  3914. " extendee: \"Bar\""
  3915. " }"
  3916. "}",
  3917. "foo.proto: Foo.foo: TYPE: The extension Foo.foo cannot be required.\n");
  3918. }
  3919. TEST_F(ValidationErrorTest, UndefinedFieldType) {
  3920. BuildFileWithErrors(
  3921. "name: \"foo.proto\" "
  3922. "message_type {"
  3923. " name: \"Foo\""
  3924. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
  3925. "}",
  3926. "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
  3927. }
  3928. TEST_F(ValidationErrorTest, UndefinedFieldTypeWithDefault) {
  3929. // See b/12533582. Previously this failed because the default value was not
  3930. // accepted by the parser, which assumed an enum type, leading to an unclear
  3931. // error message. We want this input to yield a validation error instead,
  3932. // since the unknown type is the primary problem.
  3933. BuildFileWithErrors(
  3934. "name: \"foo.proto\" "
  3935. "message_type {"
  3936. " name: \"Foo\""
  3937. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" "
  3938. " default_value:\"1\" }"
  3939. "}",
  3940. "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n");
  3941. }
  3942. TEST_F(ValidationErrorTest, UndefinedNestedFieldType) {
  3943. BuildFileWithErrors(
  3944. "name: \"foo.proto\" "
  3945. "message_type {"
  3946. " name: \"Foo\""
  3947. " nested_type { name:\"Baz\" }"
  3948. " field { name:\"foo\" number:1"
  3949. " label:LABEL_OPTIONAL"
  3950. " type_name:\"Foo.Baz.Bar\" }"
  3951. "}",
  3952. "foo.proto: Foo.foo: TYPE: \"Foo.Baz.Bar\" is not defined.\n");
  3953. }
  3954. TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
  3955. BuildFile(
  3956. "name: \"bar.proto\" "
  3957. "message_type { name: \"Bar\" } ");
  3958. BuildFileWithErrors(
  3959. "name: \"foo.proto\" "
  3960. "message_type {"
  3961. " name: \"Foo\""
  3962. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
  3963. "}",
  3964. "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
  3965. "which is not imported by \"foo.proto\". To use it here, please add the "
  3966. "necessary import.\n");
  3967. }
  3968. TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) {
  3969. // Test for hidden dependencies.
  3970. //
  3971. // // bar.proto
  3972. // message Bar{}
  3973. //
  3974. // // forward.proto
  3975. // import "bar.proto"
  3976. //
  3977. // // foo.proto
  3978. // import "forward.proto"
  3979. // message Foo {
  3980. // optional Bar foo = 1; // Error, needs to import bar.proto explicitly.
  3981. // }
  3982. //
  3983. BuildFile(
  3984. "name: \"bar.proto\" "
  3985. "message_type { name: \"Bar\" }");
  3986. BuildFile(
  3987. "name: \"forward.proto\""
  3988. "dependency: \"bar.proto\"");
  3989. BuildFileWithErrors(
  3990. "name: \"foo.proto\" "
  3991. "dependency: \"forward.proto\" "
  3992. "message_type {"
  3993. " name: \"Foo\""
  3994. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
  3995. "}",
  3996. "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
  3997. "which is not imported by \"foo.proto\". To use it here, please add the "
  3998. "necessary import.\n");
  3999. }
  4000. TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) {
  4001. // Test for public dependencies.
  4002. //
  4003. // // bar.proto
  4004. // message Bar{}
  4005. //
  4006. // // forward.proto
  4007. // import public "bar.proto"
  4008. //
  4009. // // foo.proto
  4010. // import "forward.proto"
  4011. // message Foo {
  4012. // optional Bar foo = 1; // Correct. "bar.proto" is public imported into
  4013. // // forward.proto, so when "foo.proto" imports
  4014. // // "forward.proto", it imports "bar.proto" too.
  4015. // }
  4016. //
  4017. BuildFile(
  4018. "name: \"bar.proto\" "
  4019. "message_type { name: \"Bar\" }");
  4020. BuildFile(
  4021. "name: \"forward.proto\""
  4022. "dependency: \"bar.proto\" "
  4023. "public_dependency: 0");
  4024. BuildFile(
  4025. "name: \"foo.proto\" "
  4026. "dependency: \"forward.proto\" "
  4027. "message_type {"
  4028. " name: \"Foo\""
  4029. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
  4030. "}");
  4031. }
  4032. TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
  4033. // Test for public dependencies.
  4034. //
  4035. // // bar.proto
  4036. // message Bar{}
  4037. //
  4038. // // forward.proto
  4039. // import public "bar.proto"
  4040. //
  4041. // // forward2.proto
  4042. // import public "forward.proto"
  4043. //
  4044. // // foo.proto
  4045. // import "forward2.proto"
  4046. // message Foo {
  4047. // optional Bar foo = 1; // Correct, public imports are transitive.
  4048. // }
  4049. //
  4050. BuildFile(
  4051. "name: \"bar.proto\" "
  4052. "message_type { name: \"Bar\" }");
  4053. BuildFile(
  4054. "name: \"forward.proto\""
  4055. "dependency: \"bar.proto\" "
  4056. "public_dependency: 0");
  4057. BuildFile(
  4058. "name: \"forward2.proto\""
  4059. "dependency: \"forward.proto\" "
  4060. "public_dependency: 0");
  4061. BuildFile(
  4062. "name: \"foo.proto\" "
  4063. "dependency: \"forward2.proto\" "
  4064. "message_type {"
  4065. " name: \"Foo\""
  4066. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
  4067. "}");
  4068. }
  4069. TEST_F(ValidationErrorTest,
  4070. FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
  4071. // Test for public dependencies.
  4072. //
  4073. // // bar.proto
  4074. // message Bar{}
  4075. //
  4076. // // forward.proto
  4077. // import "bar.proto"
  4078. //
  4079. // // forward2.proto
  4080. // import public "forward.proto"
  4081. //
  4082. // // foo.proto
  4083. // import "forward2.proto"
  4084. // message Foo {
  4085. // optional Bar foo = 1; // Error, the "bar.proto" is not public imported
  4086. // // into "forward.proto", so will not be imported
  4087. // // into either "forward2.proto" or "foo.proto".
  4088. // }
  4089. //
  4090. BuildFile(
  4091. "name: \"bar.proto\" "
  4092. "message_type { name: \"Bar\" }");
  4093. BuildFile(
  4094. "name: \"forward.proto\""
  4095. "dependency: \"bar.proto\"");
  4096. BuildFile(
  4097. "name: \"forward2.proto\""
  4098. "dependency: \"forward.proto\" "
  4099. "public_dependency: 0");
  4100. BuildFileWithErrors(
  4101. "name: \"foo.proto\" "
  4102. "dependency: \"forward2.proto\" "
  4103. "message_type {"
  4104. " name: \"Foo\""
  4105. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
  4106. "}",
  4107. "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
  4108. "which is not imported by \"foo.proto\". To use it here, please add the "
  4109. "necessary import.\n");
  4110. }
  4111. TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
  4112. // The following should produce an error that Bar.Baz is resolved but
  4113. // not defined:
  4114. // message Bar { message Baz {} }
  4115. // message Foo {
  4116. // message Bar {
  4117. // // Placing "message Baz{}" here, or removing Foo.Bar altogether,
  4118. // // would fix the error.
  4119. // }
  4120. // optional Bar.Baz baz = 1;
  4121. // }
  4122. // An one point the lookup code incorrectly did not produce an error in this
  4123. // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
  4124. // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
  4125. // refer to the inner Bar, not the outer one.
  4126. BuildFileWithErrors(
  4127. "name: \"foo.proto\" "
  4128. "message_type {"
  4129. " name: \"Bar\""
  4130. " nested_type { name: \"Baz\" }"
  4131. "}"
  4132. "message_type {"
  4133. " name: \"Foo\""
  4134. " nested_type { name: \"Bar\" }"
  4135. " field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
  4136. " type_name:\"Bar.Baz\" }"
  4137. "}",
  4138. "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is resolved to \"Foo.Bar.Baz\","
  4139. " which is not defined. The innermost scope is searched first in name "
  4140. "resolution. Consider using a leading '.'(i.e., \".Bar.Baz\") to start "
  4141. "from the outermost scope.\n");
  4142. }
  4143. TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
  4144. // This test would find the most local "Bar" first, and does, but
  4145. // proceeds to find the outer one because the inner one's not an
  4146. // aggregate.
  4147. BuildFile(
  4148. "name: \"foo.proto\" "
  4149. "message_type {"
  4150. " name: \"Bar\""
  4151. " nested_type { name: \"Baz\" }"
  4152. "}"
  4153. "message_type {"
  4154. " name: \"Foo\""
  4155. " field { name: \"Bar\" number:1 type:TYPE_BYTES } "
  4156. " field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
  4157. " type_name:\"Bar.Baz\" }"
  4158. "}");
  4159. }
  4160. TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
  4161. // Imagine we have the following:
  4162. //
  4163. // foo.proto:
  4164. // package foo.bar;
  4165. // bar.proto:
  4166. // package foo.bar;
  4167. // import "foo.proto";
  4168. // message Bar {}
  4169. // baz.proto:
  4170. // package foo;
  4171. // import "bar.proto"
  4172. // message Baz { optional bar.Bar qux = 1; }
  4173. //
  4174. // When validating baz.proto, we will look up "bar.Bar". As part of this
  4175. // lookup, we first lookup "bar" then try to find "Bar" within it. "bar"
  4176. // should resolve to "foo.bar". Note, though, that "foo.bar" was originally
  4177. // defined in foo.proto, which is not a direct dependency of baz.proto. The
  4178. // implementation of FindSymbol() normally only returns symbols in direct
  4179. // dependencies, not indirect ones. This test insures that this does not
  4180. // prevent it from finding "foo.bar".
  4181. BuildFile(
  4182. "name: \"foo.proto\" "
  4183. "package: \"foo.bar\" ");
  4184. BuildFile(
  4185. "name: \"bar.proto\" "
  4186. "package: \"foo.bar\" "
  4187. "dependency: \"foo.proto\" "
  4188. "message_type { name: \"Bar\" }");
  4189. BuildFile(
  4190. "name: \"baz.proto\" "
  4191. "package: \"foo\" "
  4192. "dependency: \"bar.proto\" "
  4193. "message_type { "
  4194. " name: \"Baz\" "
  4195. " field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
  4196. " type_name:\"bar.Bar\" }"
  4197. "}");
  4198. }
  4199. TEST_F(ValidationErrorTest, FieldTypeNotAType) {
  4200. BuildFileWithErrors(
  4201. "name: \"foo.proto\" "
  4202. "message_type {"
  4203. " name: \"Foo\""
  4204. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
  4205. " type_name:\".Foo.bar\" }"
  4206. " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  4207. "}",
  4208. "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
  4209. }
  4210. TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
  4211. BuildFileWithErrors(
  4212. "name: \"foo.proto\" "
  4213. "message_type {"
  4214. " nested_type {"
  4215. " name: \"Bar\""
  4216. " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  4217. " }"
  4218. " name: \"Foo\""
  4219. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
  4220. " type_name:\"Bar.Baz\" }"
  4221. "}",
  4222. "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
  4223. }
  4224. TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
  4225. BuildFile(
  4226. "name: \"foo.proto\" "
  4227. "message_type {"
  4228. " name: \"Bar\""
  4229. "}"
  4230. "message_type {"
  4231. " name: \"Foo\""
  4232. " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
  4233. "}");
  4234. }
  4235. TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
  4236. BuildFileWithErrors(
  4237. "name: \"foo.proto\" "
  4238. "message_type { name: \"Bar\" } "
  4239. "message_type {"
  4240. " name: \"Foo\""
  4241. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
  4242. " type_name:\"Bar\" }"
  4243. "}",
  4244. "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
  4245. }
  4246. TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
  4247. BuildFileWithErrors(
  4248. "name: \"foo.proto\" "
  4249. "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
  4250. "message_type {"
  4251. " name: \"Foo\""
  4252. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
  4253. " type_name:\"Bar\" }"
  4254. "}",
  4255. "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
  4256. }
  4257. TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
  4258. BuildFileWithErrors(
  4259. "name: \"foo.proto\" "
  4260. "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
  4261. "message_type {"
  4262. " name: \"Foo\""
  4263. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
  4264. " default_value:\"NO_SUCH_VALUE\" }"
  4265. "}",
  4266. "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
  4267. "\"NO_SUCH_VALUE\".\n");
  4268. }
  4269. TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) {
  4270. BuildFileWithErrors(
  4271. "name: \"foo.proto\" "
  4272. "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
  4273. "message_type {"
  4274. " name: \"Foo\""
  4275. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
  4276. " default_value:\"0\" }"
  4277. "}",
  4278. "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must "
  4279. "be an identifier.\n");
  4280. }
  4281. TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
  4282. BuildFileWithErrors(
  4283. "name: \"foo.proto\" "
  4284. "message_type {"
  4285. " name: \"Foo\""
  4286. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
  4287. " type_name:\"Foo\" }"
  4288. "}",
  4289. "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
  4290. }
  4291. TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
  4292. BuildFileWithErrors(
  4293. "name: \"foo.proto\" "
  4294. "message_type {"
  4295. " name: \"Foo\""
  4296. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
  4297. "}",
  4298. "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
  4299. "type_name.\n");
  4300. }
  4301. TEST_F(ValidationErrorTest, OneofWithNoFields) {
  4302. BuildFileWithErrors(
  4303. "name: \"foo.proto\" "
  4304. "message_type {"
  4305. " name: \"Foo\""
  4306. " oneof_decl { name:\"bar\" }"
  4307. "}",
  4308. "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n");
  4309. }
  4310. TEST_F(ValidationErrorTest, OneofLabelMismatch) {
  4311. BuildFileWithErrors(
  4312. "name: \"foo.proto\" "
  4313. "message_type {"
  4314. " name: \"Foo\""
  4315. " field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 "
  4316. " oneof_index:0 }"
  4317. " oneof_decl { name:\"bar\" }"
  4318. "}",
  4319. "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label "
  4320. "LABEL_OPTIONAL.\n");
  4321. }
  4322. TEST_F(ValidationErrorTest, InputTypeNotDefined) {
  4323. BuildFileWithErrors(
  4324. "name: \"foo.proto\" "
  4325. "message_type { name: \"Foo\" } "
  4326. "service {"
  4327. " name: \"TestService\""
  4328. " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
  4329. "}",
  4330. "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"
  4331. );
  4332. }
  4333. TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
  4334. BuildFileWithErrors(
  4335. "name: \"foo.proto\" "
  4336. "message_type { name: \"Foo\" } "
  4337. "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
  4338. "service {"
  4339. " name: \"TestService\""
  4340. " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
  4341. "}",
  4342. "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"
  4343. );
  4344. }
  4345. TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
  4346. BuildFileWithErrors(
  4347. "name: \"foo.proto\" "
  4348. "message_type { name: \"Foo\" } "
  4349. "service {"
  4350. " name: \"TestService\""
  4351. " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
  4352. "}",
  4353. "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"
  4354. );
  4355. }
  4356. TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
  4357. BuildFileWithErrors(
  4358. "name: \"foo.proto\" "
  4359. "message_type { name: \"Foo\" } "
  4360. "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
  4361. "service {"
  4362. " name: \"TestService\""
  4363. " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
  4364. "}",
  4365. "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n"
  4366. );
  4367. }
  4368. TEST_F(ValidationErrorTest, IllegalPackedField) {
  4369. BuildFileWithErrors(
  4370. "name: \"foo.proto\" "
  4371. "message_type {\n"
  4372. " name: \"Foo\""
  4373. " field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
  4374. " type:TYPE_STRING "
  4375. " options { uninterpreted_option {"
  4376. " name { name_part: \"packed\" is_extension: false }"
  4377. " identifier_value: \"true\" }}}\n"
  4378. " field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
  4379. " type_name: \"Foo\""
  4380. " options { uninterpreted_option {"
  4381. " name { name_part: \"packed\" is_extension: false }"
  4382. " identifier_value: \"true\" }}}\n"
  4383. " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
  4384. " type:TYPE_INT32 "
  4385. " options { uninterpreted_option {"
  4386. " name { name_part: \"packed\" is_extension: false }"
  4387. " identifier_value: \"true\" }}}\n"
  4388. "}",
  4389. "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
  4390. "specified for repeated primitive fields.\n"
  4391. "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
  4392. "specified for repeated primitive fields.\n"
  4393. "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
  4394. "specified for repeated primitive fields.\n");
  4395. }
  4396. TEST_F(ValidationErrorTest, OptionWrongType) {
  4397. BuildFileWithErrors(
  4398. "name: \"foo.proto\" "
  4399. "message_type { "
  4400. " name: \"TestMessage\" "
  4401. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
  4402. " options { uninterpreted_option { name { name_part: \"ctype\" "
  4403. " is_extension: false }"
  4404. " positive_int_value: 1 }"
  4405. " }"
  4406. " }"
  4407. "}\n",
  4408. "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
  4409. "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
  4410. }
  4411. TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
  4412. BuildFileWithErrors(
  4413. "name: \"foo.proto\" "
  4414. "message_type { "
  4415. " name: \"TestMessage\" "
  4416. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
  4417. " options { uninterpreted_option { name { name_part: \"ctype\" "
  4418. " is_extension: false }"
  4419. " name { name_part: \"foo\" "
  4420. " is_extension: true }"
  4421. " positive_int_value: 1 }"
  4422. " }"
  4423. " }"
  4424. "}\n",
  4425. "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
  4426. "atomic type, not a message.\n");
  4427. }
  4428. TEST_F(ValidationErrorTest, DupOption) {
  4429. BuildFileWithErrors(
  4430. "name: \"foo.proto\" "
  4431. "message_type { "
  4432. " name: \"TestMessage\" "
  4433. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
  4434. " options { uninterpreted_option { name { name_part: \"ctype\" "
  4435. " is_extension: false }"
  4436. " identifier_value: \"CORD\" }"
  4437. " uninterpreted_option { name { name_part: \"ctype\" "
  4438. " is_extension: false }"
  4439. " identifier_value: \"CORD\" }"
  4440. " }"
  4441. " }"
  4442. "}\n",
  4443. "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
  4444. "already set.\n");
  4445. }
  4446. TEST_F(ValidationErrorTest, InvalidOptionName) {
  4447. BuildFileWithErrors(
  4448. "name: \"foo.proto\" "
  4449. "message_type { "
  4450. " name: \"TestMessage\" "
  4451. " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
  4452. " options { uninterpreted_option { "
  4453. " name { name_part: \"uninterpreted_option\" "
  4454. " is_extension: false }"
  4455. " positive_int_value: 1 "
  4456. " }"
  4457. " }"
  4458. " }"
  4459. "}\n",
  4460. "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
  4461. "reserved name \"uninterpreted_option\".\n");
  4462. }
  4463. TEST_F(ValidationErrorTest, RepeatedMessageOption) {
  4464. BuildDescriptorMessagesInTestPool();
  4465. BuildFileWithErrors(
  4466. "name: \"foo.proto\" "
  4467. "dependency: \"google/protobuf/descriptor.proto\" "
  4468. "message_type: { name: \"Bar\" field: { "
  4469. " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
  4470. "} "
  4471. "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED "
  4472. " type: TYPE_MESSAGE type_name: \"Bar\" "
  4473. " extendee: \"google.protobuf.FileOptions\" }"
  4474. "options { uninterpreted_option { name { name_part: \"bar\" "
  4475. " is_extension: true } "
  4476. " name { name_part: \"foo\" "
  4477. " is_extension: false } "
  4478. " positive_int_value: 1 } }",
  4479. "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a "
  4480. "repeated message. Repeated message options must be initialized "
  4481. "using an aggregate value.\n");
  4482. }
  4483. TEST_F(ValidationErrorTest, ResolveUndefinedOption) {
  4484. // The following should produce an error that baz.bar is resolved but not
  4485. // defined.
  4486. // foo.proto:
  4487. // package baz
  4488. // import google/protobuf/descriptor.proto
  4489. // message Bar { optional int32 foo = 1; }
  4490. // extend FileOptions { optional Bar bar = 7672757; }
  4491. //
  4492. // qux.proto:
  4493. // package qux.baz
  4494. // option (baz.bar).foo = 1;
  4495. //
  4496. // Although "baz.bar" is already defined, the lookup code will try
  4497. // "qux.baz.bar", since it's the match from the innermost scope, which will
  4498. // cause a symbol not defined error.
  4499. BuildDescriptorMessagesInTestPool();
  4500. BuildFile(
  4501. "name: \"foo.proto\" "
  4502. "package: \"baz\" "
  4503. "dependency: \"google/protobuf/descriptor.proto\" "
  4504. "message_type: { name: \"Bar\" field: { "
  4505. " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
  4506. "} "
  4507. "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
  4508. " type: TYPE_MESSAGE type_name: \"Bar\" "
  4509. " extendee: \"google.protobuf.FileOptions\" }");
  4510. BuildFileWithErrors(
  4511. "name: \"qux.proto\" "
  4512. "package: \"qux.baz\" "
  4513. "options { uninterpreted_option { name { name_part: \"baz.bar\" "
  4514. " is_extension: true } "
  4515. " name { name_part: \"foo\" "
  4516. " is_extension: false } "
  4517. " positive_int_value: 1 } }",
  4518. "qux.proto: qux.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to "
  4519. "\"(qux.baz.bar)\","
  4520. " which is not defined. The innermost scope is searched first in name "
  4521. "resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\") to start "
  4522. "from the outermost scope.\n");
  4523. }
  4524. TEST_F(ValidationErrorTest, UnknownOption) {
  4525. BuildFileWithErrors(
  4526. "name: \"qux.proto\" "
  4527. "package: \"qux.baz\" "
  4528. "options { uninterpreted_option { name { name_part: \"baaz.bar\" "
  4529. " is_extension: true } "
  4530. " name { name_part: \"foo\" "
  4531. " is_extension: false } "
  4532. " positive_int_value: 1 } }",
  4533. "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown. "
  4534. "Ensure "
  4535. "that your proto definition file imports the proto which defines the "
  4536. "option.\n");
  4537. }
  4538. TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
  4539. BuildDescriptorMessagesInTestPool();
  4540. BuildFileWithErrors(
  4541. "name: \"foo.proto\" "
  4542. "dependency: \"google/protobuf/descriptor.proto\" "
  4543. "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
  4544. " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
  4545. "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
  4546. " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
  4547. "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
  4548. "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
  4549. }
  4550. TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
  4551. BuildDescriptorMessagesInTestPool();
  4552. BuildFileWithErrors(
  4553. "name: \"foo.proto\" "
  4554. "dependency: \"google/protobuf/descriptor.proto\" "
  4555. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4556. " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
  4557. "options { uninterpreted_option { name { name_part: \"foo\" "
  4558. " is_extension: true } "
  4559. " positive_int_value: 0x80000000 } "
  4560. "}",
  4561. "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
  4562. "for int32 option \"foo\".\n");
  4563. }
  4564. TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
  4565. BuildDescriptorMessagesInTestPool();
  4566. BuildFileWithErrors(
  4567. "name: \"foo.proto\" "
  4568. "dependency: \"google/protobuf/descriptor.proto\" "
  4569. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4570. " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
  4571. "options { uninterpreted_option { name { name_part: \"foo\" "
  4572. " is_extension: true } "
  4573. " negative_int_value: -0x80000001 } "
  4574. "}",
  4575. "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
  4576. "for int32 option \"foo\".\n");
  4577. }
  4578. TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
  4579. BuildDescriptorMessagesInTestPool();
  4580. BuildFileWithErrors(
  4581. "name: \"foo.proto\" "
  4582. "dependency: \"google/protobuf/descriptor.proto\" "
  4583. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4584. " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
  4585. "options { uninterpreted_option { name { name_part: \"foo\" "
  4586. " is_extension: true } "
  4587. " string_value: \"5\" } }",
  4588. "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
  4589. "for int32 option \"foo\".\n");
  4590. }
  4591. TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
  4592. BuildDescriptorMessagesInTestPool();
  4593. BuildFileWithErrors(
  4594. "name: \"foo.proto\" "
  4595. "dependency: \"google/protobuf/descriptor.proto\" "
  4596. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4597. " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
  4598. "options { uninterpreted_option { name { name_part: \"foo\" "
  4599. " is_extension: true } "
  4600. " positive_int_value: 0x8000000000000000 "
  4601. "} "
  4602. "}",
  4603. "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
  4604. "for int64 option \"foo\".\n");
  4605. }
  4606. TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
  4607. BuildDescriptorMessagesInTestPool();
  4608. BuildFileWithErrors(
  4609. "name: \"foo.proto\" "
  4610. "dependency: \"google/protobuf/descriptor.proto\" "
  4611. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4612. " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
  4613. "options { uninterpreted_option { name { name_part: \"foo\" "
  4614. " is_extension: true } "
  4615. " identifier_value: \"5\" } }",
  4616. "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
  4617. "for int64 option \"foo\".\n");
  4618. }
  4619. TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
  4620. BuildDescriptorMessagesInTestPool();
  4621. BuildFileWithErrors(
  4622. "name: \"foo.proto\" "
  4623. "dependency: \"google/protobuf/descriptor.proto\" "
  4624. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4625. " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
  4626. "options { uninterpreted_option { name { name_part: \"foo\" "
  4627. " is_extension: true } "
  4628. " positive_int_value: 0x100000000 } }",
  4629. "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
  4630. "for uint32 option \"foo\".\n");
  4631. }
  4632. TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
  4633. BuildDescriptorMessagesInTestPool();
  4634. BuildFileWithErrors(
  4635. "name: \"foo.proto\" "
  4636. "dependency: \"google/protobuf/descriptor.proto\" "
  4637. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4638. " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
  4639. "options { uninterpreted_option { name { name_part: \"foo\" "
  4640. " is_extension: true } "
  4641. " double_value: -5.6 } }",
  4642. "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
  4643. "for uint32 option \"foo\".\n");
  4644. }
  4645. TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
  4646. BuildDescriptorMessagesInTestPool();
  4647. BuildFileWithErrors(
  4648. "name: \"foo.proto\" "
  4649. "dependency: \"google/protobuf/descriptor.proto\" "
  4650. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4651. " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
  4652. "options { uninterpreted_option { name { name_part: \"foo\" "
  4653. " is_extension: true } "
  4654. " negative_int_value: -5 } }",
  4655. "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
  4656. "for uint64 option \"foo\".\n");
  4657. }
  4658. TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
  4659. BuildDescriptorMessagesInTestPool();
  4660. BuildFileWithErrors(
  4661. "name: \"foo.proto\" "
  4662. "dependency: \"google/protobuf/descriptor.proto\" "
  4663. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4664. " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
  4665. "options { uninterpreted_option { name { name_part: \"foo\" "
  4666. " is_extension: true } "
  4667. " string_value: \"bar\" } }",
  4668. "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
  4669. "for float option \"foo\".\n");
  4670. }
  4671. TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
  4672. BuildDescriptorMessagesInTestPool();
  4673. BuildFileWithErrors(
  4674. "name: \"foo.proto\" "
  4675. "dependency: \"google/protobuf/descriptor.proto\" "
  4676. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4677. " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
  4678. "options { uninterpreted_option { name { name_part: \"foo\" "
  4679. " is_extension: true } "
  4680. " string_value: \"bar\" } }",
  4681. "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
  4682. "for double option \"foo\".\n");
  4683. }
  4684. TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
  4685. BuildDescriptorMessagesInTestPool();
  4686. BuildFileWithErrors(
  4687. "name: \"foo.proto\" "
  4688. "dependency: \"google/protobuf/descriptor.proto\" "
  4689. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4690. " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
  4691. "options { uninterpreted_option { name { name_part: \"foo\" "
  4692. " is_extension: true } "
  4693. " identifier_value: \"bar\" } }",
  4694. "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
  4695. "for boolean option \"foo\".\n");
  4696. }
  4697. TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
  4698. BuildDescriptorMessagesInTestPool();
  4699. BuildFileWithErrors(
  4700. "name: \"foo.proto\" "
  4701. "dependency: \"google/protobuf/descriptor.proto\" "
  4702. "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
  4703. " value { name: \"BAZ\" number: 2 } }"
  4704. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4705. " type: TYPE_ENUM type_name: \"FooEnum\" "
  4706. " extendee: \"google.protobuf.FileOptions\" }"
  4707. "options { uninterpreted_option { name { name_part: \"foo\" "
  4708. " is_extension: true } "
  4709. " string_value: \"QUUX\" } }",
  4710. "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
  4711. "enum-valued option \"foo\".\n");
  4712. }
  4713. TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
  4714. BuildDescriptorMessagesInTestPool();
  4715. BuildFileWithErrors(
  4716. "name: \"foo.proto\" "
  4717. "dependency: \"google/protobuf/descriptor.proto\" "
  4718. "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
  4719. " value { name: \"BAZ\" number: 2 } }"
  4720. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4721. " type: TYPE_ENUM type_name: \"FooEnum\" "
  4722. " extendee: \"google.protobuf.FileOptions\" }"
  4723. "options { uninterpreted_option { name { name_part: \"foo\" "
  4724. " is_extension: true } "
  4725. " identifier_value: \"QUUX\" } }",
  4726. "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
  4727. "named \"QUUX\" for option \"foo\".\n");
  4728. }
  4729. TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
  4730. BuildDescriptorMessagesInTestPool();
  4731. BuildFileWithErrors(
  4732. "name: \"foo.proto\" "
  4733. "dependency: \"google/protobuf/descriptor.proto\" "
  4734. "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
  4735. " value { name: \"BAZ\" number: 2 } }"
  4736. "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
  4737. " value { name: \"QUUX\" number: 2 } }"
  4738. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4739. " type: TYPE_ENUM type_name: \"FooEnum1\" "
  4740. " extendee: \"google.protobuf.FileOptions\" }"
  4741. "options { uninterpreted_option { name { name_part: \"foo\" "
  4742. " is_extension: true } "
  4743. " identifier_value: \"QUUX\" } }",
  4744. "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
  4745. "named \"QUUX\" for option \"foo\". This appears to be a value from a "
  4746. "sibling type.\n");
  4747. }
  4748. TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
  4749. BuildDescriptorMessagesInTestPool();
  4750. BuildFileWithErrors(
  4751. "name: \"foo.proto\" "
  4752. "dependency: \"google/protobuf/descriptor.proto\" "
  4753. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4754. " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
  4755. "options { uninterpreted_option { name { name_part: \"foo\" "
  4756. " is_extension: true } "
  4757. " identifier_value: \"QUUX\" } }",
  4758. "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string "
  4759. "for "
  4760. "string option \"foo\".\n");
  4761. }
  4762. TEST_F(ValidationErrorTest, JsonNameOptionOnExtensions) {
  4763. BuildFileWithErrors(
  4764. "name: \"foo.proto\" "
  4765. "package: \"foo\" "
  4766. "message_type {"
  4767. " name: \"Foo\""
  4768. " extension_range { start: 10 end: 20 }"
  4769. "}"
  4770. "extension {"
  4771. " name: \"value\""
  4772. " number: 10"
  4773. " label: LABEL_OPTIONAL"
  4774. " type: TYPE_INT32"
  4775. " extendee: \"foo.Foo\""
  4776. " json_name: \"myName\""
  4777. "}",
  4778. "foo.proto: foo.value: OPTION_NAME: option json_name is not allowed on "
  4779. "extension fields.\n");
  4780. }
  4781. TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
  4782. BuildDescriptorMessagesInTestPool();
  4783. BuildFile(
  4784. "name: \"foo.proto\" "
  4785. "dependency: \"google/protobuf/descriptor.proto\" "
  4786. "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL "
  4787. " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }");
  4788. BuildFileWithWarnings(
  4789. "name: \"bar.proto\" "
  4790. "dependency: \"google/protobuf/descriptor.proto\" "
  4791. "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL "
  4792. " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }",
  4793. "bar.proto: option2: NUMBER: Extension number 1000 has already been used "
  4794. "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in "
  4795. "foo.proto.\n");
  4796. }
  4797. // Helper function for tests that check for aggregate value parsing
  4798. // errors. The "value" argument is embedded inside the
  4799. // "uninterpreted_option" portion of the result.
  4800. static std::string EmbedAggregateValue(const char* value) {
  4801. return strings::Substitute(
  4802. "name: \"foo.proto\" "
  4803. "dependency: \"google/protobuf/descriptor.proto\" "
  4804. "message_type { name: \"Foo\" } "
  4805. "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
  4806. " type: TYPE_MESSAGE type_name: \"Foo\" "
  4807. " extendee: \"google.protobuf.FileOptions\" }"
  4808. "options { uninterpreted_option { name { name_part: \"foo\" "
  4809. " is_extension: true } "
  4810. " $0 } }",
  4811. value);
  4812. }
  4813. TEST_F(ValidationErrorTest, AggregateValueNotFound) {
  4814. BuildDescriptorMessagesInTestPool();
  4815. BuildFileWithErrors(
  4816. EmbedAggregateValue("string_value: \"\""),
  4817. "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
  4818. "To set the entire message, use syntax like "
  4819. "\"foo = { <proto text format> }\". To set fields within it, use "
  4820. "syntax like \"foo.foo = value\".\n");
  4821. }
  4822. TEST_F(ValidationErrorTest, AggregateValueParseError) {
  4823. BuildDescriptorMessagesInTestPool();
  4824. BuildFileWithErrors(
  4825. EmbedAggregateValue("aggregate_value: \"1+2\""),
  4826. "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
  4827. "value for \"foo\": Expected identifier, got: 1\n");
  4828. }
  4829. TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
  4830. BuildDescriptorMessagesInTestPool();
  4831. BuildFileWithErrors(
  4832. EmbedAggregateValue("aggregate_value: \"x:100\""),
  4833. "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
  4834. "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
  4835. }
  4836. TEST_F(ValidationErrorTest, NotLiteImportsLite) {
  4837. BuildFile(
  4838. "name: \"bar.proto\" "
  4839. "options { optimize_for: LITE_RUNTIME } ");
  4840. BuildFileWithErrors(
  4841. "name: \"foo.proto\" "
  4842. "dependency: \"bar.proto\" ",
  4843. "foo.proto: bar.proto: IMPORT: Files that do not use optimize_for = "
  4844. "LITE_RUNTIME cannot import files which do use this option. This file "
  4845. "is not lite, but it imports \"bar.proto\" which is.\n");
  4846. }
  4847. TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
  4848. BuildFile(
  4849. "name: \"bar.proto\" "
  4850. "message_type: {"
  4851. " name: \"Bar\""
  4852. " extension_range { start: 1 end: 1000 }"
  4853. "}");
  4854. BuildFileWithErrors(
  4855. "name: \"foo.proto\" "
  4856. "dependency: \"bar.proto\" "
  4857. "options { optimize_for: LITE_RUNTIME } "
  4858. "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
  4859. " type: TYPE_INT32 extendee: \"Bar\" }",
  4860. "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
  4861. "declared in non-lite files. Note that you cannot extend a non-lite "
  4862. "type to contain a lite type, but the reverse is allowed.\n");
  4863. }
  4864. TEST_F(ValidationErrorTest, NoLiteServices) {
  4865. BuildFileWithErrors(
  4866. "name: \"foo.proto\" "
  4867. "options {"
  4868. " optimize_for: LITE_RUNTIME"
  4869. " cc_generic_services: true"
  4870. " java_generic_services: true"
  4871. "} "
  4872. "service { name: \"Foo\" }",
  4873. "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
  4874. "define services unless you set both options cc_generic_services and "
  4875. "java_generic_services to false.\n");
  4876. BuildFile(
  4877. "name: \"bar.proto\" "
  4878. "options {"
  4879. " optimize_for: LITE_RUNTIME"
  4880. " cc_generic_services: false"
  4881. " java_generic_services: false"
  4882. "} "
  4883. "service { name: \"Bar\" }");
  4884. }
  4885. TEST_F(ValidationErrorTest, RollbackAfterError) {
  4886. // Build a file which contains every kind of construct but references an
  4887. // undefined type. All these constructs will be added to the symbol table
  4888. // before the undefined type error is noticed. The DescriptorPool will then
  4889. // have to roll everything back.
  4890. BuildFileWithErrors(
  4891. "name: \"foo.proto\" "
  4892. "message_type {"
  4893. " name: \"TestMessage\""
  4894. " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
  4895. "} "
  4896. "enum_type {"
  4897. " name: \"TestEnum\""
  4898. " value { name:\"BAR\" number:1 }"
  4899. "} "
  4900. "service {"
  4901. " name: \"TestService\""
  4902. " method {"
  4903. " name: \"Baz\""
  4904. " input_type: \"NoSuchType\"" // error
  4905. " output_type: \"TestMessage\""
  4906. " }"
  4907. "}",
  4908. "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n"
  4909. );
  4910. // Make sure that if we build the same file again with the error fixed,
  4911. // it works. If the above rollback was incomplete, then some symbols will
  4912. // be left defined, and this second attempt will fail since it tries to
  4913. // re-define the same symbols.
  4914. BuildFile(
  4915. "name: \"foo.proto\" "
  4916. "message_type {"
  4917. " name: \"TestMessage\""
  4918. " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
  4919. "} "
  4920. "enum_type {"
  4921. " name: \"TestEnum\""
  4922. " value { name:\"BAR\" number:1 }"
  4923. "} "
  4924. "service {"
  4925. " name: \"TestService\""
  4926. " method { name:\"Baz\""
  4927. " input_type:\"TestMessage\""
  4928. " output_type:\"TestMessage\" }"
  4929. "}");
  4930. }
  4931. TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
  4932. // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
  4933. // provided.
  4934. FileDescriptorProto file_proto;
  4935. ASSERT_TRUE(
  4936. TextFormat::ParseFromString("name: \"foo.proto\" "
  4937. "message_type { name: \"Foo\" } "
  4938. "message_type { name: \"Foo\" } ",
  4939. &file_proto));
  4940. std::vector<std::string> errors;
  4941. {
  4942. ScopedMemoryLog log;
  4943. EXPECT_TRUE(pool_.BuildFile(file_proto) == nullptr);
  4944. errors = log.GetMessages(ERROR);
  4945. }
  4946. ASSERT_EQ(2, errors.size());
  4947. EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
  4948. EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]);
  4949. }
  4950. TEST_F(ValidationErrorTest, DisallowEnumAlias) {
  4951. BuildFileWithErrors(
  4952. "name: \"foo.proto\" "
  4953. "enum_type {"
  4954. " name: \"Bar\""
  4955. " value { name:\"ENUM_A\" number:0 }"
  4956. " value { name:\"ENUM_B\" number:0 }"
  4957. "}",
  4958. "foo.proto: Bar: NUMBER: "
  4959. "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
  4960. "If this is intended, set 'option allow_alias = true;' to the enum "
  4961. "definition.\n");
  4962. }
  4963. TEST_F(ValidationErrorTest, AllowEnumAlias) {
  4964. BuildFile(
  4965. "name: \"foo.proto\" "
  4966. "enum_type {"
  4967. " name: \"Bar\""
  4968. " value { name:\"ENUM_A\" number:0 }"
  4969. " value { name:\"ENUM_B\" number:0 }"
  4970. " options { allow_alias: true }"
  4971. "}");
  4972. }
  4973. TEST_F(ValidationErrorTest, UnusedImportWarning) {
  4974. pool_.AddUnusedImportTrackFile("bar.proto");
  4975. BuildFile(
  4976. "name: \"bar.proto\" "
  4977. "message_type { name: \"Bar\" }");
  4978. pool_.AddUnusedImportTrackFile("base.proto");
  4979. BuildFile(
  4980. "name: \"base.proto\" "
  4981. "message_type { name: \"Base\" }");
  4982. pool_.AddUnusedImportTrackFile("baz.proto");
  4983. BuildFile(
  4984. "name: \"baz.proto\" "
  4985. "message_type { name: \"Baz\" }");
  4986. pool_.AddUnusedImportTrackFile("public.proto");
  4987. BuildFile(
  4988. "name: \"public.proto\" "
  4989. "dependency: \"bar.proto\""
  4990. "public_dependency: 0");
  4991. // // forward.proto
  4992. // import "base.proto" // No warning: Base message is used.
  4993. // import "bar.proto" // Will log a warning.
  4994. // import public "baz.proto" // No warning: Do not track import public.
  4995. // import "public.proto" // No warning: public.proto has import public.
  4996. // message Forward {
  4997. // optional Base base = 1;
  4998. // }
  4999. //
  5000. pool_.AddUnusedImportTrackFile("forward.proto");
  5001. BuildFileWithWarnings(
  5002. "name: \"forward.proto\""
  5003. "dependency: \"base.proto\""
  5004. "dependency: \"bar.proto\""
  5005. "dependency: \"baz.proto\""
  5006. "dependency: \"public.proto\""
  5007. "public_dependency: 2 "
  5008. "message_type {"
  5009. " name: \"Forward\""
  5010. " field { name:\"base\" number:1 label:LABEL_OPTIONAL "
  5011. "type_name:\"Base\" }"
  5012. "}",
  5013. "forward.proto: bar.proto: IMPORT: Import bar.proto is unused.\n");
  5014. }
  5015. namespace {
  5016. void FillValidMapEntry(FileDescriptorProto* file_proto) {
  5017. ASSERT_TRUE(TextFormat::ParseFromString(
  5018. "name: 'foo.proto' "
  5019. "message_type { "
  5020. " name: 'Foo' "
  5021. " field { "
  5022. " name: 'foo_map' number: 1 label:LABEL_REPEATED "
  5023. " type_name: 'FooMapEntry' "
  5024. " } "
  5025. " nested_type { "
  5026. " name: 'FooMapEntry' "
  5027. " options { map_entry: true } "
  5028. " field { "
  5029. " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
  5030. " } "
  5031. " field { "
  5032. " name: 'value' number: 2 type:TYPE_INT32 label:LABEL_OPTIONAL "
  5033. " } "
  5034. " } "
  5035. "} "
  5036. "message_type { "
  5037. " name: 'Bar' "
  5038. " extension_range { start: 1 end: 10 }"
  5039. "} ",
  5040. file_proto));
  5041. }
  5042. static const char* kMapEntryErrorMessage =
  5043. "foo.proto: Foo.foo_map: TYPE: map_entry should not be set explicitly. "
  5044. "Use map<KeyType, ValueType> instead.\n";
  5045. static const char* kMapEntryKeyTypeErrorMessage =
  5046. "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot be float/double, "
  5047. "bytes or message types.\n";
  5048. } // namespace
  5049. TEST_F(ValidationErrorTest, MapEntryBase) {
  5050. FileDescriptorProto file_proto;
  5051. FillValidMapEntry(&file_proto);
  5052. BuildFile(file_proto.DebugString());
  5053. }
  5054. TEST_F(ValidationErrorTest, MapEntryExtensionRange) {
  5055. FileDescriptorProto file_proto;
  5056. FillValidMapEntry(&file_proto);
  5057. TextFormat::MergeFromString(
  5058. "extension_range { "
  5059. " start: 10 end: 20 "
  5060. "} ",
  5061. file_proto.mutable_message_type(0)->mutable_nested_type(0));
  5062. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5063. }
  5064. TEST_F(ValidationErrorTest, MapEntryExtension) {
  5065. FileDescriptorProto file_proto;
  5066. FillValidMapEntry(&file_proto);
  5067. TextFormat::MergeFromString(
  5068. "extension { "
  5069. " name: 'foo_ext' extendee: '.Bar' number: 5"
  5070. "} ",
  5071. file_proto.mutable_message_type(0)->mutable_nested_type(0));
  5072. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5073. }
  5074. TEST_F(ValidationErrorTest, MapEntryNestedType) {
  5075. FileDescriptorProto file_proto;
  5076. FillValidMapEntry(&file_proto);
  5077. TextFormat::MergeFromString(
  5078. "nested_type { "
  5079. " name: 'Bar' "
  5080. "} ",
  5081. file_proto.mutable_message_type(0)->mutable_nested_type(0));
  5082. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5083. }
  5084. TEST_F(ValidationErrorTest, MapEntryEnumTypes) {
  5085. FileDescriptorProto file_proto;
  5086. FillValidMapEntry(&file_proto);
  5087. TextFormat::MergeFromString(
  5088. "enum_type { "
  5089. " name: 'BarEnum' "
  5090. " value { name: 'BAR_BAR' number:0 } "
  5091. "} ",
  5092. file_proto.mutable_message_type(0)->mutable_nested_type(0));
  5093. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5094. }
  5095. TEST_F(ValidationErrorTest, MapEntryExtraField) {
  5096. FileDescriptorProto file_proto;
  5097. FillValidMapEntry(&file_proto);
  5098. TextFormat::MergeFromString(
  5099. "field { "
  5100. " name: 'other_field' "
  5101. " label: LABEL_OPTIONAL "
  5102. " type: TYPE_INT32 "
  5103. " number: 3 "
  5104. "} ",
  5105. file_proto.mutable_message_type(0)->mutable_nested_type(0));
  5106. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5107. }
  5108. TEST_F(ValidationErrorTest, MapEntryMessageName) {
  5109. FileDescriptorProto file_proto;
  5110. FillValidMapEntry(&file_proto);
  5111. file_proto.mutable_message_type(0)->mutable_nested_type(0)->set_name(
  5112. "OtherMapEntry");
  5113. file_proto.mutable_message_type(0)->mutable_field(0)->set_type_name(
  5114. "OtherMapEntry");
  5115. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5116. }
  5117. TEST_F(ValidationErrorTest, MapEntryNoneRepeatedMapEntry) {
  5118. FileDescriptorProto file_proto;
  5119. FillValidMapEntry(&file_proto);
  5120. file_proto.mutable_message_type(0)->mutable_field(0)->set_label(
  5121. FieldDescriptorProto::LABEL_OPTIONAL);
  5122. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5123. }
  5124. TEST_F(ValidationErrorTest, MapEntryDifferentContainingType) {
  5125. FileDescriptorProto file_proto;
  5126. FillValidMapEntry(&file_proto);
  5127. // Move the nested MapEntry message into the top level, which should not pass
  5128. // the validation.
  5129. file_proto.mutable_message_type()->AddAllocated(
  5130. file_proto.mutable_message_type(0)->mutable_nested_type()->ReleaseLast());
  5131. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5132. }
  5133. TEST_F(ValidationErrorTest, MapEntryKeyName) {
  5134. FileDescriptorProto file_proto;
  5135. FillValidMapEntry(&file_proto);
  5136. FieldDescriptorProto* key =
  5137. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5138. 0);
  5139. key->set_name("Key");
  5140. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5141. }
  5142. TEST_F(ValidationErrorTest, MapEntryKeyLabel) {
  5143. FileDescriptorProto file_proto;
  5144. FillValidMapEntry(&file_proto);
  5145. FieldDescriptorProto* key =
  5146. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5147. 0);
  5148. key->set_label(FieldDescriptorProto::LABEL_REQUIRED);
  5149. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5150. }
  5151. TEST_F(ValidationErrorTest, MapEntryKeyNumber) {
  5152. FileDescriptorProto file_proto;
  5153. FillValidMapEntry(&file_proto);
  5154. FieldDescriptorProto* key =
  5155. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5156. 0);
  5157. key->set_number(3);
  5158. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5159. }
  5160. TEST_F(ValidationErrorTest, MapEntryValueName) {
  5161. FileDescriptorProto file_proto;
  5162. FillValidMapEntry(&file_proto);
  5163. FieldDescriptorProto* value =
  5164. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5165. 1);
  5166. value->set_name("Value");
  5167. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5168. }
  5169. TEST_F(ValidationErrorTest, MapEntryValueLabel) {
  5170. FileDescriptorProto file_proto;
  5171. FillValidMapEntry(&file_proto);
  5172. FieldDescriptorProto* value =
  5173. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5174. 1);
  5175. value->set_label(FieldDescriptorProto::LABEL_REQUIRED);
  5176. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5177. }
  5178. TEST_F(ValidationErrorTest, MapEntryValueNumber) {
  5179. FileDescriptorProto file_proto;
  5180. FillValidMapEntry(&file_proto);
  5181. FieldDescriptorProto* value =
  5182. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5183. 1);
  5184. value->set_number(3);
  5185. BuildFileWithErrors(file_proto.DebugString(), kMapEntryErrorMessage);
  5186. }
  5187. TEST_F(ValidationErrorTest, MapEntryKeyTypeFloat) {
  5188. FileDescriptorProto file_proto;
  5189. FillValidMapEntry(&file_proto);
  5190. FieldDescriptorProto* key =
  5191. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5192. 0);
  5193. key->set_type(FieldDescriptorProto::TYPE_FLOAT);
  5194. BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
  5195. }
  5196. TEST_F(ValidationErrorTest, MapEntryKeyTypeDouble) {
  5197. FileDescriptorProto file_proto;
  5198. FillValidMapEntry(&file_proto);
  5199. FieldDescriptorProto* key =
  5200. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5201. 0);
  5202. key->set_type(FieldDescriptorProto::TYPE_DOUBLE);
  5203. BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
  5204. }
  5205. TEST_F(ValidationErrorTest, MapEntryKeyTypeBytes) {
  5206. FileDescriptorProto file_proto;
  5207. FillValidMapEntry(&file_proto);
  5208. FieldDescriptorProto* key =
  5209. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5210. 0);
  5211. key->set_type(FieldDescriptorProto::TYPE_BYTES);
  5212. BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
  5213. }
  5214. TEST_F(ValidationErrorTest, MapEntryKeyTypeEnum) {
  5215. FileDescriptorProto file_proto;
  5216. FillValidMapEntry(&file_proto);
  5217. FieldDescriptorProto* key =
  5218. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5219. 0);
  5220. key->clear_type();
  5221. key->set_type_name("BarEnum");
  5222. EnumDescriptorProto* enum_proto = file_proto.add_enum_type();
  5223. enum_proto->set_name("BarEnum");
  5224. EnumValueDescriptorProto* enum_value_proto = enum_proto->add_value();
  5225. enum_value_proto->set_name("BAR_VALUE0");
  5226. enum_value_proto->set_number(0);
  5227. BuildFileWithErrors(file_proto.DebugString(),
  5228. "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
  5229. "be enum types.\n");
  5230. // Enum keys are not allowed in proto3 as well.
  5231. // Get rid of extensions for proto3 to make it proto3 compatible.
  5232. file_proto.mutable_message_type()->RemoveLast();
  5233. file_proto.set_syntax("proto3");
  5234. BuildFileWithErrors(file_proto.DebugString(),
  5235. "foo.proto: Foo.foo_map: TYPE: Key in map fields cannot "
  5236. "be enum types.\n");
  5237. }
  5238. TEST_F(ValidationErrorTest, MapEntryKeyTypeMessage) {
  5239. FileDescriptorProto file_proto;
  5240. FillValidMapEntry(&file_proto);
  5241. FieldDescriptorProto* key =
  5242. file_proto.mutable_message_type(0)->mutable_nested_type(0)->mutable_field(
  5243. 0);
  5244. key->clear_type();
  5245. key->set_type_name(".Bar");
  5246. BuildFileWithErrors(file_proto.DebugString(), kMapEntryKeyTypeErrorMessage);
  5247. }
  5248. TEST_F(ValidationErrorTest, MapEntryConflictsWithField) {
  5249. FileDescriptorProto file_proto;
  5250. FillValidMapEntry(&file_proto);
  5251. TextFormat::MergeFromString(
  5252. "field { "
  5253. " name: 'FooMapEntry' "
  5254. " type: TYPE_INT32 "
  5255. " label: LABEL_OPTIONAL "
  5256. " number: 100 "
  5257. "}",
  5258. file_proto.mutable_message_type(0));
  5259. BuildFileWithErrors(
  5260. file_proto.DebugString(),
  5261. "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
  5262. "\"Foo\".\n"
  5263. "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
  5264. "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
  5265. "with an existing field.\n");
  5266. }
  5267. TEST_F(ValidationErrorTest, MapEntryConflictsWithMessage) {
  5268. FileDescriptorProto file_proto;
  5269. FillValidMapEntry(&file_proto);
  5270. TextFormat::MergeFromString(
  5271. "nested_type { "
  5272. " name: 'FooMapEntry' "
  5273. "}",
  5274. file_proto.mutable_message_type(0));
  5275. BuildFileWithErrors(
  5276. file_proto.DebugString(),
  5277. "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
  5278. "\"Foo\".\n"
  5279. "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
  5280. "with an existing nested message type.\n");
  5281. }
  5282. TEST_F(ValidationErrorTest, MapEntryConflictsWithEnum) {
  5283. FileDescriptorProto file_proto;
  5284. FillValidMapEntry(&file_proto);
  5285. TextFormat::MergeFromString(
  5286. "enum_type { "
  5287. " name: 'FooMapEntry' "
  5288. " value { name: 'ENTRY_FOO' number: 0 }"
  5289. "}",
  5290. file_proto.mutable_message_type(0));
  5291. BuildFileWithErrors(
  5292. file_proto.DebugString(),
  5293. "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
  5294. "\"Foo\".\n"
  5295. "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
  5296. "with an existing enum type.\n");
  5297. }
  5298. TEST_F(ValidationErrorTest, EnumValuesConflictWithDifferentCasing) {
  5299. BuildFileWithErrors(
  5300. "syntax: 'proto3'"
  5301. "name: 'foo.proto' "
  5302. "enum_type {"
  5303. " name: 'FooEnum' "
  5304. " value { name: 'BAR' number: 0 }"
  5305. " value { name: 'bar' number: 1 }"
  5306. "}",
  5307. "foo.proto: bar: NAME: Enum name bar has the same name as BAR "
  5308. "if you ignore case and strip out the enum name prefix (if any). "
  5309. "This is error-prone and can lead to undefined behavior. "
  5310. "Please avoid doing this. If you are using allow_alias, please assign "
  5311. "the same numeric value to both enums.\n");
  5312. // Not an error because both enums are mapped to the same value.
  5313. BuildFile(
  5314. "syntax: 'proto3'"
  5315. "name: 'foo.proto' "
  5316. "enum_type {"
  5317. " name: 'FooEnum' "
  5318. " options { allow_alias: true }"
  5319. " value { name: 'UNKNOWN' number: 0 }"
  5320. " value { name: 'BAR' number: 1 }"
  5321. " value { name: 'bar' number: 1 }"
  5322. "}");
  5323. }
  5324. TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) {
  5325. BuildFileWithErrors(
  5326. "syntax: 'proto3'"
  5327. "name: 'foo.proto' "
  5328. "enum_type {"
  5329. " name: 'FooEnum' "
  5330. " value { name: 'FOO_ENUM_BAZ' number: 0 }"
  5331. " value { name: 'BAZ' number: 1 }"
  5332. "}",
  5333. "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOO_ENUM_BAZ "
  5334. "if you ignore case and strip out the enum name prefix (if any). "
  5335. "This is error-prone and can lead to undefined behavior. "
  5336. "Please avoid doing this. If you are using allow_alias, please assign "
  5337. "the same numeric value to both enums.\n");
  5338. BuildFileWithErrors(
  5339. "syntax: 'proto3'"
  5340. "name: 'foo.proto' "
  5341. "enum_type {"
  5342. " name: 'FooEnum' "
  5343. " value { name: 'FOOENUM_BAZ' number: 0 }"
  5344. " value { name: 'BAZ' number: 1 }"
  5345. "}",
  5346. "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOOENUM_BAZ "
  5347. "if you ignore case and strip out the enum name prefix (if any). "
  5348. "This is error-prone and can lead to undefined behavior. "
  5349. "Please avoid doing this. If you are using allow_alias, please assign "
  5350. "the same numeric value to both enums.\n");
  5351. BuildFileWithErrors(
  5352. "syntax: 'proto3'"
  5353. "name: 'foo.proto' "
  5354. "enum_type {"
  5355. " name: 'FooEnum' "
  5356. " value { name: 'FOO_ENUM_BAR_BAZ' number: 0 }"
  5357. " value { name: 'BAR__BAZ' number: 1 }"
  5358. "}",
  5359. "foo.proto: BAR__BAZ: NAME: Enum name BAR__BAZ has the same name as "
  5360. "FOO_ENUM_BAR_BAZ if you ignore case and strip out the enum name prefix "
  5361. "(if any). This is error-prone and can lead to undefined behavior. "
  5362. "Please avoid doing this. If you are using allow_alias, please assign "
  5363. "the same numeric value to both enums.\n");
  5364. BuildFileWithErrors(
  5365. "syntax: 'proto3'"
  5366. "name: 'foo.proto' "
  5367. "enum_type {"
  5368. " name: 'FooEnum' "
  5369. " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }"
  5370. " value { name: 'BAR_BAZ' number: 1 }"
  5371. "}",
  5372. "foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as "
  5373. "FOO_ENUM__BAR_BAZ if you ignore case and strip out the enum name prefix "
  5374. "(if any). This is error-prone and can lead to undefined behavior. "
  5375. "Please avoid doing this. If you are using allow_alias, please assign "
  5376. "the same numeric value to both enums.\n");
  5377. // This isn't an error because the underscore will cause the PascalCase to
  5378. // differ by case (BarBaz vs. Barbaz).
  5379. BuildFile(
  5380. "syntax: 'proto3'"
  5381. "name: 'foo.proto' "
  5382. "enum_type {"
  5383. " name: 'FooEnum' "
  5384. " value { name: 'BAR_BAZ' number: 0 }"
  5385. " value { name: 'BARBAZ' number: 1 }"
  5386. "}");
  5387. }
  5388. TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) {
  5389. FileDescriptorProto file_proto;
  5390. FillValidMapEntry(&file_proto);
  5391. TextFormat::MergeFromString(
  5392. "oneof_decl { "
  5393. " name: 'FooMapEntry' "
  5394. "}"
  5395. "field { "
  5396. " name: 'int_field' "
  5397. " type: TYPE_INT32 "
  5398. " label: LABEL_OPTIONAL "
  5399. " oneof_index: 0 "
  5400. " number: 100 "
  5401. "} ",
  5402. file_proto.mutable_message_type(0));
  5403. BuildFileWithErrors(
  5404. file_proto.DebugString(),
  5405. "foo.proto: Foo.FooMapEntry: NAME: \"FooMapEntry\" is already defined in "
  5406. "\"Foo\".\n"
  5407. "foo.proto: Foo.foo_map: TYPE: \"FooMapEntry\" is not defined.\n"
  5408. "foo.proto: Foo: NAME: Expanded map entry type FooMapEntry conflicts "
  5409. "with an existing oneof type.\n");
  5410. }
  5411. TEST_F(ValidationErrorTest, MapEntryUsesNoneZeroEnumDefaultValue) {
  5412. BuildFileWithErrors(
  5413. "name: \"foo.proto\" "
  5414. "enum_type {"
  5415. " name: \"Bar\""
  5416. " value { name:\"ENUM_A\" number:1 }"
  5417. " value { name:\"ENUM_B\" number:2 }"
  5418. "}"
  5419. "message_type {"
  5420. " name: 'Foo' "
  5421. " field { "
  5422. " name: 'foo_map' number: 1 label:LABEL_REPEATED "
  5423. " type_name: 'FooMapEntry' "
  5424. " } "
  5425. " nested_type { "
  5426. " name: 'FooMapEntry' "
  5427. " options { map_entry: true } "
  5428. " field { "
  5429. " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
  5430. " } "
  5431. " field { "
  5432. " name: 'value' number: 2 type_name:\"Bar\" label:LABEL_OPTIONAL "
  5433. " } "
  5434. " } "
  5435. "}",
  5436. "foo.proto: Foo.foo_map: "
  5437. "TYPE: Enum value in map must define 0 as the first value.\n");
  5438. }
  5439. TEST_F(ValidationErrorTest, Proto3RequiredFields) {
  5440. BuildFileWithErrors(
  5441. "name: 'foo.proto' "
  5442. "syntax: 'proto3' "
  5443. "message_type { "
  5444. " name: 'Foo' "
  5445. " field { name:'foo' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
  5446. "}",
  5447. "foo.proto: Foo.foo: TYPE: Required fields are not allowed in "
  5448. "proto3.\n");
  5449. // applied to nested types as well.
  5450. BuildFileWithErrors(
  5451. "name: 'foo.proto' "
  5452. "syntax: 'proto3' "
  5453. "message_type { "
  5454. " name: 'Foo' "
  5455. " nested_type { "
  5456. " name : 'Bar' "
  5457. " field { name:'bar' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } "
  5458. " } "
  5459. "}",
  5460. "foo.proto: Foo.Bar.bar: TYPE: Required fields are not allowed in "
  5461. "proto3.\n");
  5462. // optional and repeated fields are OK.
  5463. BuildFile(
  5464. "name: 'foo.proto' "
  5465. "syntax: 'proto3' "
  5466. "message_type { "
  5467. " name: 'Foo' "
  5468. " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
  5469. " field { name:'bar' number:2 label:LABEL_REPEATED type:TYPE_INT32 } "
  5470. "}");
  5471. }
  5472. TEST_F(ValidationErrorTest, ValidateProto3DefaultValue) {
  5473. BuildFileWithErrors(
  5474. "name: 'foo.proto' "
  5475. "syntax: 'proto3' "
  5476. "message_type { "
  5477. " name: 'Foo' "
  5478. " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  5479. " default_value: '1' }"
  5480. "}",
  5481. "foo.proto: Foo.foo: DEFAULT_VALUE: Explicit default values are not "
  5482. "allowed in proto3.\n");
  5483. BuildFileWithErrors(
  5484. "name: 'foo.proto' "
  5485. "syntax: 'proto3' "
  5486. "message_type { "
  5487. " name: 'Foo' "
  5488. " nested_type { "
  5489. " name : 'Bar' "
  5490. " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
  5491. " default_value: '1' }"
  5492. " } "
  5493. "}",
  5494. "foo.proto: Foo.Bar.bar: DEFAULT_VALUE: Explicit default values are not "
  5495. "allowed in proto3.\n");
  5496. }
  5497. TEST_F(ValidationErrorTest, ValidateProto3ExtensionRange) {
  5498. BuildFileWithErrors(
  5499. "name: 'foo.proto' "
  5500. "syntax: 'proto3' "
  5501. "message_type { "
  5502. " name: 'Foo' "
  5503. " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
  5504. " extension_range { start:10 end:100 } "
  5505. "}",
  5506. "foo.proto: Foo: NUMBER: Extension ranges are not allowed in "
  5507. "proto3.\n");
  5508. BuildFileWithErrors(
  5509. "name: 'foo.proto' "
  5510. "syntax: 'proto3' "
  5511. "message_type { "
  5512. " name: 'Foo' "
  5513. " nested_type { "
  5514. " name : 'Bar' "
  5515. " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } "
  5516. " extension_range { start:10 end:100 } "
  5517. " } "
  5518. "}",
  5519. "foo.proto: Foo.Bar: NUMBER: Extension ranges are not allowed in "
  5520. "proto3.\n");
  5521. }
  5522. TEST_F(ValidationErrorTest, ValidateProto3MessageSetWireFormat) {
  5523. BuildFileWithErrors(
  5524. "name: 'foo.proto' "
  5525. "syntax: 'proto3' "
  5526. "message_type { "
  5527. " name: 'Foo' "
  5528. " options { message_set_wire_format: true } "
  5529. "}",
  5530. "foo.proto: Foo: NAME: MessageSet is not supported "
  5531. "in proto3.\n");
  5532. }
  5533. TEST_F(ValidationErrorTest, ValidateProto3Enum) {
  5534. BuildFileWithErrors(
  5535. "name: 'foo.proto' "
  5536. "syntax: 'proto3' "
  5537. "enum_type { "
  5538. " name: 'FooEnum' "
  5539. " value { name: 'FOO_FOO' number:1 } "
  5540. "}",
  5541. "foo.proto: FooEnum: NUMBER: The first enum value must be "
  5542. "zero in proto3.\n");
  5543. BuildFileWithErrors(
  5544. "name: 'foo.proto' "
  5545. "syntax: 'proto3' "
  5546. "message_type { "
  5547. " name: 'Foo' "
  5548. " enum_type { "
  5549. " name: 'FooEnum' "
  5550. " value { name: 'FOO_FOO' number:1 } "
  5551. " } "
  5552. "}",
  5553. "foo.proto: Foo.FooEnum: NUMBER: The first enum value must be "
  5554. "zero in proto3.\n");
  5555. // valid case.
  5556. BuildFile(
  5557. "name: 'foo.proto' "
  5558. "syntax: 'proto3' "
  5559. "enum_type { "
  5560. " name: 'FooEnum' "
  5561. " value { name: 'FOO_FOO' number:0 } "
  5562. "}");
  5563. }
  5564. TEST_F(ValidationErrorTest, ValidateProto3Group) {
  5565. BuildFileWithErrors(
  5566. "name: 'foo.proto' "
  5567. "syntax: 'proto3' "
  5568. "message_type { "
  5569. " name: 'Foo' "
  5570. " nested_type { "
  5571. " name: 'FooGroup' "
  5572. " } "
  5573. " field { name:'foo_group' number: 1 label:LABEL_OPTIONAL "
  5574. " type: TYPE_GROUP type_name:'FooGroup' } "
  5575. "}",
  5576. "foo.proto: Foo.foo_group: TYPE: Groups are not supported in proto3 "
  5577. "syntax.\n");
  5578. }
  5579. TEST_F(ValidationErrorTest, ValidateProto3EnumFromProto2) {
  5580. // Define an enum in a proto2 file.
  5581. BuildFile(
  5582. "name: 'foo.proto' "
  5583. "package: 'foo' "
  5584. "syntax: 'proto2' "
  5585. "enum_type { "
  5586. " name: 'FooEnum' "
  5587. " value { name: 'DEFAULT_OPTION' number:0 } "
  5588. "}");
  5589. // Now try to refer to it. (All tests in the fixture use the same pool, so we
  5590. // can refer to the enum above in this definition.)
  5591. BuildFileWithErrors(
  5592. "name: 'bar.proto' "
  5593. "dependency: 'foo.proto' "
  5594. "syntax: 'proto3' "
  5595. "message_type { "
  5596. " name: 'Foo' "
  5597. " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_ENUM "
  5598. " type_name: 'foo.FooEnum' }"
  5599. "}",
  5600. "bar.proto: Foo.bar: TYPE: Enum type \"foo.FooEnum\" is not a proto3 "
  5601. "enum, but is used in \"Foo\" which is a proto3 message type.\n");
  5602. }
  5603. TEST_F(ValidationErrorTest, ValidateProto3Extension) {
  5604. // Valid for options.
  5605. DescriptorPool pool;
  5606. FileDescriptorProto file_proto;
  5607. // Add "google/protobuf/descriptor.proto".
  5608. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
  5609. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  5610. // Add "foo.proto":
  5611. // import "google/protobuf/descriptor.proto";
  5612. // extend google.protobuf.FieldOptions {
  5613. // optional int32 option1 = 1000;
  5614. // }
  5615. file_proto.Clear();
  5616. file_proto.set_name("foo.proto");
  5617. file_proto.set_syntax("proto3");
  5618. file_proto.add_dependency("google/protobuf/descriptor.proto");
  5619. AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
  5620. FieldDescriptorProto::LABEL_OPTIONAL,
  5621. FieldDescriptorProto::TYPE_INT32);
  5622. ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr);
  5623. // Copy and change the package of the descriptor.proto
  5624. BuildFile(
  5625. "name: 'google.protobuf.proto' "
  5626. "syntax: 'proto2' "
  5627. "message_type { "
  5628. " name: 'Container' extension_range { start: 1 end: 1000 } "
  5629. "}");
  5630. BuildFileWithErrors(
  5631. "name: 'bar.proto' "
  5632. "syntax: 'proto3' "
  5633. "dependency: 'google.protobuf.proto' "
  5634. "extension { "
  5635. " name: 'bar' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 "
  5636. " extendee: 'Container' "
  5637. "}",
  5638. "bar.proto: bar: EXTENDEE: Extensions in proto3 are only allowed for "
  5639. "defining options.\n");
  5640. }
  5641. // Test that field names that may conflict in JSON is not allowed by protoc.
  5642. TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
  5643. // The comparison is case-insensitive.
  5644. BuildFileWithErrors(
  5645. "name: 'foo.proto' "
  5646. "syntax: 'proto3' "
  5647. "message_type {"
  5648. " name: 'Foo'"
  5649. " field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  5650. " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  5651. "}",
  5652. "foo.proto: Foo: NAME: The JSON camel-case name of field \"Name\" "
  5653. "conflicts with field \"name\". This is not allowed in proto3.\n");
  5654. // Underscores are ignored.
  5655. BuildFileWithErrors(
  5656. "name: 'foo.proto' "
  5657. "syntax: 'proto3' "
  5658. "message_type {"
  5659. " name: 'Foo'"
  5660. " field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  5661. " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
  5662. "}",
  5663. "foo.proto: Foo: NAME: The JSON camel-case name of field \"_a__b_\" "
  5664. "conflicts with field \"ab\". This is not allowed in proto3.\n");
  5665. }
  5666. TEST_F(ValidationErrorTest, UnusedImportWithOtherError) {
  5667. BuildFile(
  5668. "name: 'bar.proto' "
  5669. "message_type {"
  5670. " name: 'Bar'"
  5671. "}");
  5672. pool_.AddUnusedImportTrackFile("foo.proto", true);
  5673. BuildFileWithErrors(
  5674. "name: 'foo.proto' "
  5675. "dependency: 'bar.proto' "
  5676. "message_type {"
  5677. " name: 'Foo'"
  5678. " extension { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
  5679. " extendee: 'Baz' }"
  5680. "}",
  5681. // Should not also contain unused import error.
  5682. "foo.proto: Foo.foo: EXTENDEE: \"Baz\" is not defined.\n");
  5683. }
  5684. // ===================================================================
  5685. // DescriptorDatabase
  5686. static void AddToDatabase(SimpleDescriptorDatabase* database,
  5687. const char* file_text) {
  5688. FileDescriptorProto file_proto;
  5689. EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
  5690. database->Add(file_proto);
  5691. }
  5692. class DatabaseBackedPoolTest : public testing::Test {
  5693. protected:
  5694. DatabaseBackedPoolTest() {}
  5695. SimpleDescriptorDatabase database_;
  5696. virtual void SetUp() {
  5697. AddToDatabase(
  5698. &database_,
  5699. "name: 'foo.proto' "
  5700. "message_type { name:'Foo' extension_range { start: 1 end: 100 } } "
  5701. "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } "
  5702. "service { name:'TestService' } ");
  5703. AddToDatabase(&database_,
  5704. "name: 'bar.proto' "
  5705. "dependency: 'foo.proto' "
  5706. "message_type { name:'Bar' } "
  5707. "extension { name:'foo_ext' extendee: '.Foo' number:5 "
  5708. " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
  5709. // Baz has an undeclared dependency on Foo.
  5710. AddToDatabase(
  5711. &database_,
  5712. "name: 'baz.proto' "
  5713. "message_type { "
  5714. " name:'Baz' "
  5715. " field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
  5716. "}");
  5717. }
  5718. // We can't inject a file containing errors into a DescriptorPool, so we
  5719. // need an actual mock DescriptorDatabase to test errors.
  5720. class ErrorDescriptorDatabase : public DescriptorDatabase {
  5721. public:
  5722. ErrorDescriptorDatabase() {}
  5723. ~ErrorDescriptorDatabase() {}
  5724. // implements DescriptorDatabase ---------------------------------
  5725. bool FindFileByName(const std::string& filename,
  5726. FileDescriptorProto* output) {
  5727. // error.proto and error2.proto cyclically import each other.
  5728. if (filename == "error.proto") {
  5729. output->Clear();
  5730. output->set_name("error.proto");
  5731. output->add_dependency("error2.proto");
  5732. return true;
  5733. } else if (filename == "error2.proto") {
  5734. output->Clear();
  5735. output->set_name("error2.proto");
  5736. output->add_dependency("error.proto");
  5737. return true;
  5738. } else {
  5739. return false;
  5740. }
  5741. }
  5742. bool FindFileContainingSymbol(const std::string& symbol_name,
  5743. FileDescriptorProto* output) {
  5744. return false;
  5745. }
  5746. bool FindFileContainingExtension(const std::string& containing_type,
  5747. int field_number,
  5748. FileDescriptorProto* output) {
  5749. return false;
  5750. }
  5751. };
  5752. // A DescriptorDatabase that counts how many times each method has been
  5753. // called and forwards to some other DescriptorDatabase.
  5754. class CallCountingDatabase : public DescriptorDatabase {
  5755. public:
  5756. CallCountingDatabase(DescriptorDatabase* wrapped_db)
  5757. : wrapped_db_(wrapped_db) {
  5758. Clear();
  5759. }
  5760. ~CallCountingDatabase() {}
  5761. DescriptorDatabase* wrapped_db_;
  5762. int call_count_;
  5763. void Clear() { call_count_ = 0; }
  5764. // implements DescriptorDatabase ---------------------------------
  5765. bool FindFileByName(const std::string& filename,
  5766. FileDescriptorProto* output) {
  5767. ++call_count_;
  5768. return wrapped_db_->FindFileByName(filename, output);
  5769. }
  5770. bool FindFileContainingSymbol(const std::string& symbol_name,
  5771. FileDescriptorProto* output) {
  5772. ++call_count_;
  5773. return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
  5774. }
  5775. bool FindFileContainingExtension(const std::string& containing_type,
  5776. int field_number,
  5777. FileDescriptorProto* output) {
  5778. ++call_count_;
  5779. return wrapped_db_->FindFileContainingExtension(containing_type,
  5780. field_number, output);
  5781. }
  5782. };
  5783. // A DescriptorDatabase which falsely always returns foo.proto when searching
  5784. // for any symbol or extension number. This shouldn't cause the
  5785. // DescriptorPool to reload foo.proto if it is already loaded.
  5786. class FalsePositiveDatabase : public DescriptorDatabase {
  5787. public:
  5788. FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
  5789. : wrapped_db_(wrapped_db) {}
  5790. ~FalsePositiveDatabase() {}
  5791. DescriptorDatabase* wrapped_db_;
  5792. // implements DescriptorDatabase ---------------------------------
  5793. bool FindFileByName(const std::string& filename,
  5794. FileDescriptorProto* output) {
  5795. return wrapped_db_->FindFileByName(filename, output);
  5796. }
  5797. bool FindFileContainingSymbol(const std::string& symbol_name,
  5798. FileDescriptorProto* output) {
  5799. return FindFileByName("foo.proto", output);
  5800. }
  5801. bool FindFileContainingExtension(const std::string& containing_type,
  5802. int field_number,
  5803. FileDescriptorProto* output) {
  5804. return FindFileByName("foo.proto", output);
  5805. }
  5806. };
  5807. };
  5808. TEST_F(DatabaseBackedPoolTest, FindFileByName) {
  5809. DescriptorPool pool(&database_);
  5810. const FileDescriptor* foo = pool.FindFileByName("foo.proto");
  5811. ASSERT_TRUE(foo != nullptr);
  5812. EXPECT_EQ("foo.proto", foo->name());
  5813. ASSERT_EQ(1, foo->message_type_count());
  5814. EXPECT_EQ("Foo", foo->message_type(0)->name());
  5815. EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
  5816. EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == nullptr);
  5817. }
  5818. TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
  5819. DescriptorPool pool(&database_);
  5820. const FileDescriptor* foo = pool.FindFileByName("foo.proto");
  5821. ASSERT_TRUE(foo != nullptr);
  5822. EXPECT_EQ("foo.proto", foo->name());
  5823. ASSERT_EQ(1, foo->message_type_count());
  5824. EXPECT_EQ("Foo", foo->message_type(0)->name());
  5825. const FileDescriptor* bar = pool.FindFileByName("bar.proto");
  5826. ASSERT_TRUE(bar != nullptr);
  5827. EXPECT_EQ("bar.proto", bar->name());
  5828. ASSERT_EQ(1, bar->message_type_count());
  5829. EXPECT_EQ("Bar", bar->message_type(0)->name());
  5830. ASSERT_EQ(1, bar->dependency_count());
  5831. EXPECT_EQ(foo, bar->dependency(0));
  5832. }
  5833. TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
  5834. DescriptorPool pool(&database_);
  5835. const FileDescriptor* bar = pool.FindFileByName("bar.proto");
  5836. ASSERT_TRUE(bar != nullptr);
  5837. EXPECT_EQ("bar.proto", bar->name());
  5838. ASSERT_EQ(1, bar->message_type_count());
  5839. ASSERT_EQ("Bar", bar->message_type(0)->name());
  5840. const FileDescriptor* foo = pool.FindFileByName("foo.proto");
  5841. ASSERT_TRUE(foo != nullptr);
  5842. EXPECT_EQ("foo.proto", foo->name());
  5843. ASSERT_EQ(1, foo->message_type_count());
  5844. ASSERT_EQ("Foo", foo->message_type(0)->name());
  5845. ASSERT_EQ(1, bar->dependency_count());
  5846. EXPECT_EQ(foo, bar->dependency(0));
  5847. }
  5848. TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
  5849. DescriptorPool pool(&database_);
  5850. const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
  5851. ASSERT_TRUE(file != nullptr);
  5852. EXPECT_EQ("foo.proto", file->name());
  5853. EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
  5854. EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == nullptr);
  5855. }
  5856. TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
  5857. DescriptorPool pool(&database_);
  5858. const Descriptor* type = pool.FindMessageTypeByName("Foo");
  5859. ASSERT_TRUE(type != nullptr);
  5860. EXPECT_EQ("Foo", type->name());
  5861. EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
  5862. EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == nullptr);
  5863. }
  5864. TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
  5865. DescriptorPool pool(&database_);
  5866. const Descriptor* foo = pool.FindMessageTypeByName("Foo");
  5867. ASSERT_TRUE(foo != nullptr);
  5868. const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
  5869. ASSERT_TRUE(extension != nullptr);
  5870. EXPECT_EQ("foo_ext", extension->name());
  5871. EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
  5872. EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == nullptr);
  5873. }
  5874. TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
  5875. DescriptorPool pool(&database_);
  5876. const Descriptor* foo = pool.FindMessageTypeByName("Foo");
  5877. for (int i = 0; i < 2; ++i) {
  5878. // Repeat the lookup twice, to check that we get consistent
  5879. // results despite the fallback database lookup mutating the pool.
  5880. std::vector<const FieldDescriptor*> extensions;
  5881. pool.FindAllExtensions(foo, &extensions);
  5882. ASSERT_EQ(1, extensions.size());
  5883. EXPECT_EQ(5, extensions[0]->number());
  5884. }
  5885. }
  5886. TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
  5887. ErrorDescriptorDatabase error_database;
  5888. DescriptorPool pool(&error_database);
  5889. std::vector<std::string> errors;
  5890. {
  5891. ScopedMemoryLog log;
  5892. EXPECT_TRUE(pool.FindFileByName("error.proto") == nullptr);
  5893. errors = log.GetMessages(ERROR);
  5894. }
  5895. EXPECT_FALSE(errors.empty());
  5896. }
  5897. TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
  5898. ErrorDescriptorDatabase error_database;
  5899. MockErrorCollector error_collector;
  5900. DescriptorPool pool(&error_database, &error_collector);
  5901. EXPECT_TRUE(pool.FindFileByName("error.proto") == nullptr);
  5902. EXPECT_EQ(
  5903. "error.proto: error2.proto: IMPORT: File recursively imports itself: "
  5904. "error.proto -> error2.proto -> error.proto\n"
  5905. "error2.proto: error.proto: IMPORT: Import \"error.proto\" was not "
  5906. "found or had errors.\n"
  5907. "error.proto: error2.proto: IMPORT: Import \"error2.proto\" was not "
  5908. "found or had errors.\n",
  5909. error_collector.text_);
  5910. }
  5911. TEST_F(DatabaseBackedPoolTest, UndeclaredDependencyOnUnbuiltType) {
  5912. // Check that we find and report undeclared dependencies on types that exist
  5913. // in the descriptor database but that have not not been built yet.
  5914. MockErrorCollector error_collector;
  5915. DescriptorPool pool(&database_, &error_collector);
  5916. EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
  5917. EXPECT_EQ(
  5918. "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
  5919. "which is not imported by \"baz.proto\". To use it here, please add "
  5920. "the necessary import.\n",
  5921. error_collector.text_);
  5922. }
  5923. TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
  5924. // Make sure that all traces of bad types are removed from the pool. This used
  5925. // to be b/4529436, due to the fact that a symbol resolution failure could
  5926. // potentially cause another file to be recursively built, which would trigger
  5927. // a checkpoint _past_ possibly invalid symbols.
  5928. // Baz is defined in the database, but the file is invalid because it is
  5929. // missing a necessary import.
  5930. DescriptorPool pool(&database_);
  5931. EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
  5932. // Make sure that searching again for the file or the type fails.
  5933. EXPECT_TRUE(pool.FindFileByName("baz.proto") == nullptr);
  5934. EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == nullptr);
  5935. }
  5936. TEST_F(DatabaseBackedPoolTest, UnittestProto) {
  5937. // Try to load all of unittest.proto from a DescriptorDatabase. This should
  5938. // thoroughly test all paths through DescriptorBuilder to insure that there
  5939. // are no deadlocking problems when pool_->mutex_ is non-null.
  5940. const FileDescriptor* original_file =
  5941. protobuf_unittest::TestAllTypes::descriptor()->file();
  5942. DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
  5943. DescriptorPool pool(&database);
  5944. const FileDescriptor* file_from_database =
  5945. pool.FindFileByName(original_file->name());
  5946. ASSERT_TRUE(file_from_database != nullptr);
  5947. FileDescriptorProto original_file_proto;
  5948. original_file->CopyTo(&original_file_proto);
  5949. FileDescriptorProto file_from_database_proto;
  5950. file_from_database->CopyTo(&file_from_database_proto);
  5951. EXPECT_EQ(original_file_proto.DebugString(),
  5952. file_from_database_proto.DebugString());
  5953. // Also verify that CopyTo() did not omit any information.
  5954. EXPECT_EQ(original_file->DebugString(), file_from_database->DebugString());
  5955. }
  5956. TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
  5957. // Searching for a child of an existing descriptor should never fall back
  5958. // to the DescriptorDatabase even if it isn't found, because we know all
  5959. // children are already loaded.
  5960. CallCountingDatabase call_counter(&database_);
  5961. DescriptorPool pool(&call_counter);
  5962. const FileDescriptor* file = pool.FindFileByName("foo.proto");
  5963. ASSERT_TRUE(file != nullptr);
  5964. const Descriptor* foo = pool.FindMessageTypeByName("Foo");
  5965. ASSERT_TRUE(foo != nullptr);
  5966. const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
  5967. ASSERT_TRUE(test_enum != nullptr);
  5968. const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
  5969. ASSERT_TRUE(test_service != nullptr);
  5970. EXPECT_NE(0, call_counter.call_count_);
  5971. call_counter.Clear();
  5972. EXPECT_TRUE(foo->FindFieldByName("no_such_field") == nullptr);
  5973. EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == nullptr);
  5974. EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == nullptr);
  5975. EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == nullptr);
  5976. EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
  5977. EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == nullptr);
  5978. EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == nullptr);
  5979. EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == nullptr);
  5980. EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == nullptr);
  5981. EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == nullptr);
  5982. EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == nullptr);
  5983. EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == nullptr);
  5984. EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == nullptr);
  5985. EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == nullptr);
  5986. EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == nullptr);
  5987. EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == nullptr);
  5988. EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == nullptr);
  5989. EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == nullptr);
  5990. EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == nullptr);
  5991. EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == nullptr);
  5992. EXPECT_EQ(0, call_counter.call_count_);
  5993. }
  5994. TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
  5995. // If FindFileContainingSymbol() or FindFileContainingExtension() return a
  5996. // file that is already in the DescriptorPool, it should not attempt to
  5997. // reload the file.
  5998. FalsePositiveDatabase false_positive_database(&database_);
  5999. MockErrorCollector error_collector;
  6000. DescriptorPool pool(&false_positive_database, &error_collector);
  6001. // First make sure foo.proto is loaded.
  6002. const Descriptor* foo = pool.FindMessageTypeByName("Foo");
  6003. ASSERT_TRUE(foo != nullptr);
  6004. // Try inducing false positives.
  6005. EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == nullptr);
  6006. EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == nullptr);
  6007. // No errors should have been reported. (If foo.proto was incorrectly
  6008. // loaded multiple times, errors would have been reported.)
  6009. EXPECT_EQ("", error_collector.text_);
  6010. }
  6011. // DescriptorDatabase that attempts to induce exponentially-bad performance
  6012. // in DescriptorPool. For every positive N, the database contains a file
  6013. // fileN.proto, which defines a message MessageN, which contains fields of
  6014. // type MessageK for all K in [0,N). Message0 is not defined anywhere
  6015. // (file0.proto exists, but is empty), so every other file and message type
  6016. // will fail to build.
  6017. //
  6018. // If the DescriptorPool is not careful to memoize errors, an attempt to
  6019. // build a descriptor for MessageN can require O(2^N) time.
  6020. class ExponentialErrorDatabase : public DescriptorDatabase {
  6021. public:
  6022. ExponentialErrorDatabase() {}
  6023. ~ExponentialErrorDatabase() {}
  6024. // implements DescriptorDatabase ---------------------------------
  6025. bool FindFileByName(const std::string& filename,
  6026. FileDescriptorProto* output) {
  6027. int file_num = -1;
  6028. FullMatch(filename, "file", ".proto", &file_num);
  6029. if (file_num > -1) {
  6030. return PopulateFile(file_num, output);
  6031. } else {
  6032. return false;
  6033. }
  6034. }
  6035. bool FindFileContainingSymbol(const std::string& symbol_name,
  6036. FileDescriptorProto* output) {
  6037. int file_num = -1;
  6038. FullMatch(symbol_name, "Message", "", &file_num);
  6039. if (file_num > 0) {
  6040. return PopulateFile(file_num, output);
  6041. } else {
  6042. return false;
  6043. }
  6044. }
  6045. bool FindFileContainingExtension(const std::string& containing_type,
  6046. int field_number,
  6047. FileDescriptorProto* output) {
  6048. return false;
  6049. }
  6050. private:
  6051. void FullMatch(const std::string& name, const std::string& begin_with,
  6052. const std::string& end_with, int* file_num) {
  6053. int begin_size = begin_with.size();
  6054. int end_size = end_with.size();
  6055. if (name.substr(0, begin_size) != begin_with ||
  6056. name.substr(name.size() - end_size, end_size) != end_with) {
  6057. return;
  6058. }
  6059. safe_strto32(
  6060. name.substr(begin_size, name.size() - end_size - begin_size), file_num);
  6061. }
  6062. bool PopulateFile(int file_num, FileDescriptorProto* output) {
  6063. GOOGLE_CHECK_GE(file_num, 0);
  6064. output->Clear();
  6065. output->set_name(strings::Substitute("file$0.proto", file_num));
  6066. // file0.proto doesn't define Message0
  6067. if (file_num > 0) {
  6068. DescriptorProto* message = output->add_message_type();
  6069. message->set_name(strings::Substitute("Message$0", file_num));
  6070. for (int i = 0; i < file_num; ++i) {
  6071. output->add_dependency(strings::Substitute("file$0.proto", i));
  6072. FieldDescriptorProto* field = message->add_field();
  6073. field->set_name(strings::Substitute("field$0", i));
  6074. field->set_number(i);
  6075. field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
  6076. field->set_type(FieldDescriptorProto::TYPE_MESSAGE);
  6077. field->set_type_name(strings::Substitute("Message$0", i));
  6078. }
  6079. }
  6080. return true;
  6081. }
  6082. };
  6083. TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
  6084. ExponentialErrorDatabase error_database;
  6085. DescriptorPool pool(&error_database);
  6086. GOOGLE_LOG(INFO) << "A timeout in this test probably indicates a real bug.";
  6087. EXPECT_TRUE(pool.FindFileByName("file40.proto") == nullptr);
  6088. EXPECT_TRUE(pool.FindMessageTypeByName("Message40") == nullptr);
  6089. }
  6090. TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
  6091. // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
  6092. // to FindFieldByName()), we should fail fast, without checking the fallback
  6093. // database.
  6094. CallCountingDatabase call_counter(&database_);
  6095. DescriptorPool pool(&call_counter);
  6096. const FileDescriptor* file = pool.FindFileByName("foo.proto");
  6097. ASSERT_TRUE(file != nullptr);
  6098. const Descriptor* foo = pool.FindMessageTypeByName("Foo");
  6099. ASSERT_TRUE(foo != nullptr);
  6100. const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
  6101. ASSERT_TRUE(test_enum != nullptr);
  6102. EXPECT_NE(0, call_counter.call_count_);
  6103. call_counter.Clear();
  6104. EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == nullptr);
  6105. EXPECT_TRUE(pool.FindFieldByName("Foo") == nullptr);
  6106. EXPECT_TRUE(pool.FindExtensionByName("Foo") == nullptr);
  6107. EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == nullptr);
  6108. EXPECT_TRUE(pool.FindEnumValueByName("Foo") == nullptr);
  6109. EXPECT_TRUE(pool.FindServiceByName("Foo") == nullptr);
  6110. EXPECT_TRUE(pool.FindMethodByName("Foo") == nullptr);
  6111. EXPECT_EQ(0, call_counter.call_count_);
  6112. }
  6113. // ===================================================================
  6114. class AbortingErrorCollector : public DescriptorPool::ErrorCollector {
  6115. public:
  6116. AbortingErrorCollector() {}
  6117. virtual void AddError(const std::string& filename,
  6118. const std::string& element_name, const Message* message,
  6119. ErrorLocation location,
  6120. const std::string& error_message) {
  6121. GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << " ["
  6122. << element_name << "]: " << error_message;
  6123. }
  6124. private:
  6125. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector);
  6126. };
  6127. // A source tree containing only one file.
  6128. class SingletonSourceTree : public compiler::SourceTree {
  6129. public:
  6130. SingletonSourceTree(const std::string& filename, const std::string& contents)
  6131. : filename_(filename), contents_(contents) {}
  6132. virtual io::ZeroCopyInputStream* Open(const std::string& filename) {
  6133. return filename == filename_
  6134. ? new io::ArrayInputStream(contents_.data(), contents_.size())
  6135. : nullptr;
  6136. }
  6137. private:
  6138. const std::string filename_;
  6139. const std::string contents_;
  6140. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
  6141. };
  6142. const char* const kSourceLocationTestInput =
  6143. "syntax = \"proto2\";\n"
  6144. "option java_package = \"com.foo.bar\";\n"
  6145. "option (test_file_opt) = \"foobar\";\n"
  6146. "message A {\n"
  6147. " option (test_msg_opt) = \"foobar\";\n"
  6148. " optional int32 a = 1 [deprecated = true];\n"
  6149. " message B {\n"
  6150. " required double b = 1 [(test_field_opt) = \"foobar\"];\n"
  6151. " }\n"
  6152. " oneof c {\n"
  6153. " option (test_oneof_opt) = \"foobar\";\n"
  6154. " string d = 2;\n"
  6155. " string e = 3;\n"
  6156. " string f = 4;\n"
  6157. " }\n"
  6158. "}\n"
  6159. "enum Indecision {\n"
  6160. " option (test_enum_opt) = 21;\n"
  6161. " option (test_enum_opt) = 42;\n"
  6162. " option (test_enum_opt) = 63;\n"
  6163. " YES = 1 [(test_enumval_opt).a = 100];\n"
  6164. " NO = 2 [(test_enumval_opt) = {a:200}];\n"
  6165. " MAYBE = 3;\n"
  6166. "}\n"
  6167. "service S {\n"
  6168. " option (test_svc_opt) = {a:100};\n"
  6169. " option (test_svc_opt) = {a:200};\n"
  6170. " option (test_svc_opt) = {a:300};\n"
  6171. " rpc Method(A) returns (A.B);\n"
  6172. // Put an empty line here to make the source location range match.
  6173. "\n"
  6174. " rpc OtherMethod(A) returns (A) {\n"
  6175. " option deprecated = true;\n"
  6176. " option (test_method_opt) = \"foobar\";\n"
  6177. " }\n"
  6178. "}\n"
  6179. "message MessageWithExtensions {\n"
  6180. " extensions 1000 to 2000, 2001 to max [(test_ext_opt) = \"foobar\"];\n"
  6181. "}\n"
  6182. "extend MessageWithExtensions {\n"
  6183. " repeated int32 int32_extension = 1001 [packed=true];\n"
  6184. "}\n"
  6185. "message C {\n"
  6186. " extend MessageWithExtensions {\n"
  6187. " optional C message_extension = 1002;\n"
  6188. " }\n"
  6189. "}\n"
  6190. "import \"google/protobuf/descriptor.proto\";\n"
  6191. "extend google.protobuf.FileOptions {\n"
  6192. " optional string test_file_opt = 10101;\n"
  6193. "}\n"
  6194. "extend google.protobuf.MessageOptions {\n"
  6195. " optional string test_msg_opt = 10101;\n"
  6196. "}\n"
  6197. "extend google.protobuf.FieldOptions {\n"
  6198. " optional string test_field_opt = 10101;\n"
  6199. "}\n"
  6200. "extend google.protobuf.EnumOptions {\n"
  6201. " repeated int32 test_enum_opt = 10101;\n"
  6202. "}\n"
  6203. "extend google.protobuf.EnumValueOptions {\n"
  6204. " optional A test_enumval_opt = 10101;\n"
  6205. "}\n"
  6206. "extend google.protobuf.ServiceOptions {\n"
  6207. " repeated A test_svc_opt = 10101;\n"
  6208. "}\n"
  6209. "extend google.protobuf.MethodOptions {\n"
  6210. " optional string test_method_opt = 10101;\n"
  6211. "}\n"
  6212. "extend google.protobuf.OneofOptions {\n"
  6213. " optional string test_oneof_opt = 10101;\n"
  6214. "}\n"
  6215. "extend google.protobuf.ExtensionRangeOptions {\n"
  6216. " optional string test_ext_opt = 10101;\n"
  6217. "}\n";
  6218. class SourceLocationTest : public testing::Test {
  6219. public:
  6220. SourceLocationTest()
  6221. : source_tree_("/test/test.proto", kSourceLocationTestInput),
  6222. simple_db_(),
  6223. source_tree_db_(&source_tree_),
  6224. merged_db_(&simple_db_, &source_tree_db_),
  6225. pool_(&merged_db_, &collector_) {
  6226. // we need descriptor.proto to be accessible by the pool
  6227. // since our test file imports it
  6228. FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto_);
  6229. simple_db_.Add(file_proto_);
  6230. }
  6231. static std::string PrintSourceLocation(const SourceLocation& loc) {
  6232. return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line,
  6233. 1 + loc.start_column, 1 + loc.end_line,
  6234. 1 + loc.end_column);
  6235. }
  6236. private:
  6237. FileDescriptorProto file_proto_;
  6238. AbortingErrorCollector collector_;
  6239. SingletonSourceTree source_tree_;
  6240. SimpleDescriptorDatabase simple_db_; // contains descriptor.proto
  6241. compiler::SourceTreeDescriptorDatabase source_tree_db_; // loads test.proto
  6242. MergedDescriptorDatabase merged_db_; // combines above two dbs
  6243. protected:
  6244. DescriptorPool pool_;
  6245. // tag number of all custom options in above test file
  6246. static constexpr int kCustomOptionFieldNumber = 10101;
  6247. // tag number of field "a" in message type "A" in above test file
  6248. static constexpr int kAFieldNumber = 1;
  6249. };
  6250. // TODO(adonovan): implement support for option fields and for
  6251. // subparts of declarations.
  6252. TEST_F(SourceLocationTest, GetSourceLocation) {
  6253. SourceLocation loc;
  6254. const FileDescriptor* file_desc =
  6255. GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
  6256. const Descriptor* a_desc = file_desc->FindMessageTypeByName("A");
  6257. EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
  6258. EXPECT_EQ("4:1-16:2", PrintSourceLocation(loc));
  6259. const Descriptor* a_b_desc = a_desc->FindNestedTypeByName("B");
  6260. EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
  6261. EXPECT_EQ("7:3-9:4", PrintSourceLocation(loc));
  6262. const EnumDescriptor* e_desc = file_desc->FindEnumTypeByName("Indecision");
  6263. EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
  6264. EXPECT_EQ("17:1-24:2", PrintSourceLocation(loc));
  6265. const EnumValueDescriptor* yes_desc = e_desc->FindValueByName("YES");
  6266. EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
  6267. EXPECT_EQ("21:3-21:42", PrintSourceLocation(loc));
  6268. const ServiceDescriptor* s_desc = file_desc->FindServiceByName("S");
  6269. EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
  6270. EXPECT_EQ("25:1-35:2", PrintSourceLocation(loc));
  6271. const MethodDescriptor* m_desc = s_desc->FindMethodByName("Method");
  6272. EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
  6273. EXPECT_EQ("29:3-29:31", PrintSourceLocation(loc));
  6274. }
  6275. TEST_F(SourceLocationTest, ExtensionSourceLocation) {
  6276. SourceLocation loc;
  6277. const FileDescriptor* file_desc =
  6278. GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
  6279. const FieldDescriptor* int32_extension_desc =
  6280. file_desc->FindExtensionByName("int32_extension");
  6281. EXPECT_TRUE(int32_extension_desc->GetSourceLocation(&loc));
  6282. EXPECT_EQ("40:3-40:55", PrintSourceLocation(loc));
  6283. const Descriptor* c_desc = file_desc->FindMessageTypeByName("C");
  6284. EXPECT_TRUE(c_desc->GetSourceLocation(&loc));
  6285. EXPECT_EQ("42:1-46:2", PrintSourceLocation(loc));
  6286. const FieldDescriptor* message_extension_desc =
  6287. c_desc->FindExtensionByName("message_extension");
  6288. EXPECT_TRUE(message_extension_desc->GetSourceLocation(&loc));
  6289. EXPECT_EQ("44:5-44:41", PrintSourceLocation(loc));
  6290. }
  6291. TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) {
  6292. // This one's a doozy. It checks every kind of option, including
  6293. // extension range options.
  6294. // We are verifying that the file's source info contains correct
  6295. // info for interpreted options and that it does *not* contain
  6296. // any info for corresponding uninterpreted option path.
  6297. SourceLocation loc;
  6298. const FileDescriptor* file_desc =
  6299. GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
  6300. // File options
  6301. {
  6302. int path[] = {FileDescriptorProto::kOptionsFieldNumber,
  6303. FileOptions::kJavaPackageFieldNumber};
  6304. int unint[] = {FileDescriptorProto::kOptionsFieldNumber,
  6305. FileOptions::kUninterpretedOptionFieldNumber, 0};
  6306. std::vector<int> vpath(path, path + 2);
  6307. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6308. EXPECT_EQ("2:1-2:37", PrintSourceLocation(loc));
  6309. std::vector<int> vunint(unint, unint + 3);
  6310. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6311. }
  6312. {
  6313. int path[] = {FileDescriptorProto::kOptionsFieldNumber,
  6314. kCustomOptionFieldNumber};
  6315. int unint[] = {FileDescriptorProto::kOptionsFieldNumber,
  6316. FileOptions::kUninterpretedOptionFieldNumber, 1};
  6317. std::vector<int> vpath(path, path + 2);
  6318. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6319. EXPECT_EQ("3:1-3:35", PrintSourceLocation(loc));
  6320. std::vector<int> vunint(unint, unint + 3);
  6321. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6322. }
  6323. // Message option
  6324. {
  6325. int path[] = {FileDescriptorProto::kMessageTypeFieldNumber, 0,
  6326. DescriptorProto::kOptionsFieldNumber,
  6327. kCustomOptionFieldNumber};
  6328. int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber, 0,
  6329. DescriptorProto::kOptionsFieldNumber,
  6330. MessageOptions::kUninterpretedOptionFieldNumber, 0};
  6331. std::vector<int> vpath(path, path + 4);
  6332. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6333. EXPECT_EQ("5:3-5:36", PrintSourceLocation(loc));
  6334. std::vector<int> vunint(unint, unint + 5);
  6335. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6336. }
  6337. // Field option
  6338. {
  6339. int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6340. 0,
  6341. DescriptorProto::kFieldFieldNumber,
  6342. 0,
  6343. FieldDescriptorProto::kOptionsFieldNumber,
  6344. FieldOptions::kDeprecatedFieldNumber};
  6345. int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6346. 0,
  6347. DescriptorProto::kFieldFieldNumber,
  6348. 0,
  6349. FieldDescriptorProto::kOptionsFieldNumber,
  6350. FieldOptions::kUninterpretedOptionFieldNumber,
  6351. 0};
  6352. std::vector<int> vpath(path, path + 6);
  6353. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6354. EXPECT_EQ("6:25-6:42", PrintSourceLocation(loc));
  6355. std::vector<int> vunint(unint, unint + 7);
  6356. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6357. }
  6358. // Nested message option
  6359. {
  6360. int path[] = {
  6361. FileDescriptorProto::kMessageTypeFieldNumber, 0,
  6362. DescriptorProto::kNestedTypeFieldNumber, 0,
  6363. DescriptorProto::kFieldFieldNumber, 0,
  6364. FieldDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
  6365. int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6366. 0,
  6367. DescriptorProto::kNestedTypeFieldNumber,
  6368. 0,
  6369. DescriptorProto::kFieldFieldNumber,
  6370. 0,
  6371. FieldDescriptorProto::kOptionsFieldNumber,
  6372. FieldOptions::kUninterpretedOptionFieldNumber,
  6373. 0};
  6374. std::vector<int> vpath(path, path + 8);
  6375. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6376. EXPECT_EQ("8:28-8:55", PrintSourceLocation(loc));
  6377. std::vector<int> vunint(unint, unint + 9);
  6378. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6379. }
  6380. // One-of option
  6381. {
  6382. int path[] = {
  6383. FileDescriptorProto::kMessageTypeFieldNumber, 0,
  6384. DescriptorProto::kOneofDeclFieldNumber, 0,
  6385. OneofDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
  6386. int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6387. 0,
  6388. DescriptorProto::kOneofDeclFieldNumber,
  6389. 0,
  6390. OneofDescriptorProto::kOptionsFieldNumber,
  6391. OneofOptions::kUninterpretedOptionFieldNumber,
  6392. 0};
  6393. std::vector<int> vpath(path, path + 6);
  6394. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6395. EXPECT_EQ("11:5-11:40", PrintSourceLocation(loc));
  6396. std::vector<int> vunint(unint, unint + 7);
  6397. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6398. }
  6399. // Enum option, repeated options
  6400. {
  6401. int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
  6402. EnumDescriptorProto::kOptionsFieldNumber,
  6403. kCustomOptionFieldNumber, 0};
  6404. int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
  6405. EnumDescriptorProto::kOptionsFieldNumber,
  6406. EnumOptions::kUninterpretedOptionFieldNumber, 0};
  6407. std::vector<int> vpath(path, path + 5);
  6408. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6409. EXPECT_EQ("18:3-18:31", PrintSourceLocation(loc));
  6410. std::vector<int> vunint(unint, unint + 5);
  6411. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6412. }
  6413. {
  6414. int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
  6415. EnumDescriptorProto::kOptionsFieldNumber,
  6416. kCustomOptionFieldNumber, 1};
  6417. int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
  6418. EnumDescriptorProto::kOptionsFieldNumber,
  6419. EnumOptions::kUninterpretedOptionFieldNumber, 1};
  6420. std::vector<int> vpath(path, path + 5);
  6421. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6422. EXPECT_EQ("19:3-19:31", PrintSourceLocation(loc));
  6423. std::vector<int> vunint(unint, unint + 5);
  6424. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6425. }
  6426. {
  6427. int path[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
  6428. EnumDescriptorProto::kOptionsFieldNumber,
  6429. kCustomOptionFieldNumber, 2};
  6430. int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber, 0,
  6431. EnumDescriptorProto::kOptionsFieldNumber,
  6432. OneofOptions::kUninterpretedOptionFieldNumber, 2};
  6433. std::vector<int> vpath(path, path + 5);
  6434. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6435. EXPECT_EQ("20:3-20:31", PrintSourceLocation(loc));
  6436. std::vector<int> vunint(unint, unint + 5);
  6437. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6438. }
  6439. // Enum value options
  6440. {
  6441. // option w/ message type that directly sets field
  6442. int path[] = {FileDescriptorProto::kEnumTypeFieldNumber,
  6443. 0,
  6444. EnumDescriptorProto::kValueFieldNumber,
  6445. 0,
  6446. EnumValueDescriptorProto::kOptionsFieldNumber,
  6447. kCustomOptionFieldNumber,
  6448. kAFieldNumber};
  6449. int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
  6450. 0,
  6451. EnumDescriptorProto::kValueFieldNumber,
  6452. 0,
  6453. EnumValueDescriptorProto::kOptionsFieldNumber,
  6454. EnumValueOptions::kUninterpretedOptionFieldNumber,
  6455. 0};
  6456. std::vector<int> vpath(path, path + 7);
  6457. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6458. EXPECT_EQ("21:14-21:40", PrintSourceLocation(loc));
  6459. std::vector<int> vunint(unint, unint + 7);
  6460. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6461. }
  6462. {
  6463. int path[] = {FileDescriptorProto::kEnumTypeFieldNumber,
  6464. 0,
  6465. EnumDescriptorProto::kValueFieldNumber,
  6466. 1,
  6467. EnumValueDescriptorProto::kOptionsFieldNumber,
  6468. kCustomOptionFieldNumber};
  6469. int unint[] = {FileDescriptorProto::kEnumTypeFieldNumber,
  6470. 0,
  6471. EnumDescriptorProto::kValueFieldNumber,
  6472. 1,
  6473. EnumValueDescriptorProto::kOptionsFieldNumber,
  6474. EnumValueOptions::kUninterpretedOptionFieldNumber,
  6475. 0};
  6476. std::vector<int> vpath(path, path + 6);
  6477. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6478. EXPECT_EQ("22:14-22:42", PrintSourceLocation(loc));
  6479. std::vector<int> vunint(unint, unint + 7);
  6480. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6481. }
  6482. // Service option, repeated options
  6483. {
  6484. int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
  6485. ServiceDescriptorProto::kOptionsFieldNumber,
  6486. kCustomOptionFieldNumber, 0};
  6487. int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
  6488. ServiceDescriptorProto::kOptionsFieldNumber,
  6489. ServiceOptions::kUninterpretedOptionFieldNumber, 0};
  6490. std::vector<int> vpath(path, path + 5);
  6491. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6492. EXPECT_EQ("26:3-26:35", PrintSourceLocation(loc));
  6493. std::vector<int> vunint(unint, unint + 5);
  6494. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6495. }
  6496. {
  6497. int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
  6498. ServiceDescriptorProto::kOptionsFieldNumber,
  6499. kCustomOptionFieldNumber, 1};
  6500. int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
  6501. ServiceDescriptorProto::kOptionsFieldNumber,
  6502. ServiceOptions::kUninterpretedOptionFieldNumber, 1};
  6503. std::vector<int> vpath(path, path + 5);
  6504. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6505. EXPECT_EQ("27:3-27:35", PrintSourceLocation(loc));
  6506. std::vector<int> vunint(unint, unint + 5);
  6507. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6508. }
  6509. {
  6510. int path[] = {FileDescriptorProto::kServiceFieldNumber, 0,
  6511. ServiceDescriptorProto::kOptionsFieldNumber,
  6512. kCustomOptionFieldNumber, 2};
  6513. int unint[] = {FileDescriptorProto::kServiceFieldNumber, 0,
  6514. ServiceDescriptorProto::kOptionsFieldNumber,
  6515. ServiceOptions::kUninterpretedOptionFieldNumber, 2};
  6516. std::vector<int> vpath(path, path + 5);
  6517. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6518. EXPECT_EQ("28:3-28:35", PrintSourceLocation(loc));
  6519. std::vector<int> vunint(unint, unint + 5);
  6520. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6521. }
  6522. // Method options
  6523. {
  6524. int path[] = {FileDescriptorProto::kServiceFieldNumber,
  6525. 0,
  6526. ServiceDescriptorProto::kMethodFieldNumber,
  6527. 1,
  6528. MethodDescriptorProto::kOptionsFieldNumber,
  6529. MethodOptions::kDeprecatedFieldNumber};
  6530. int unint[] = {FileDescriptorProto::kServiceFieldNumber,
  6531. 0,
  6532. ServiceDescriptorProto::kMethodFieldNumber,
  6533. 1,
  6534. MethodDescriptorProto::kOptionsFieldNumber,
  6535. MethodOptions::kUninterpretedOptionFieldNumber,
  6536. 0};
  6537. std::vector<int> vpath(path, path + 6);
  6538. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6539. EXPECT_EQ("32:5-32:30", PrintSourceLocation(loc));
  6540. std::vector<int> vunint(unint, unint + 7);
  6541. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6542. }
  6543. {
  6544. int path[] = {
  6545. FileDescriptorProto::kServiceFieldNumber, 0,
  6546. ServiceDescriptorProto::kMethodFieldNumber, 1,
  6547. MethodDescriptorProto::kOptionsFieldNumber, kCustomOptionFieldNumber};
  6548. int unint[] = {FileDescriptorProto::kServiceFieldNumber,
  6549. 0,
  6550. ServiceDescriptorProto::kMethodFieldNumber,
  6551. 1,
  6552. MethodDescriptorProto::kOptionsFieldNumber,
  6553. MethodOptions::kUninterpretedOptionFieldNumber,
  6554. 1};
  6555. std::vector<int> vpath(path, path + 6);
  6556. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6557. EXPECT_EQ("33:5-33:41", PrintSourceLocation(loc));
  6558. std::vector<int> vunint(unint, unint + 7);
  6559. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6560. }
  6561. // Extension range options
  6562. {
  6563. int path[] = {FileDescriptorProto::kMessageTypeFieldNumber, 1,
  6564. DescriptorProto::kExtensionRangeFieldNumber, 0,
  6565. DescriptorProto_ExtensionRange::kOptionsFieldNumber};
  6566. std::vector<int> vpath(path, path + 5);
  6567. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6568. EXPECT_EQ("37:40-37:67", PrintSourceLocation(loc));
  6569. }
  6570. {
  6571. int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6572. 1,
  6573. DescriptorProto::kExtensionRangeFieldNumber,
  6574. 0,
  6575. DescriptorProto_ExtensionRange::kOptionsFieldNumber,
  6576. kCustomOptionFieldNumber};
  6577. int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6578. 1,
  6579. DescriptorProto::kExtensionRangeFieldNumber,
  6580. 0,
  6581. DescriptorProto_ExtensionRange::kOptionsFieldNumber,
  6582. ExtensionRangeOptions::kUninterpretedOptionFieldNumber,
  6583. 0};
  6584. std::vector<int> vpath(path, path + 6);
  6585. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6586. EXPECT_EQ("37:41-37:66", PrintSourceLocation(loc));
  6587. std::vector<int> vunint(unint, unint + 7);
  6588. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6589. }
  6590. {
  6591. int path[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6592. 1,
  6593. DescriptorProto::kExtensionRangeFieldNumber,
  6594. 1,
  6595. DescriptorProto_ExtensionRange::kOptionsFieldNumber,
  6596. kCustomOptionFieldNumber};
  6597. int unint[] = {FileDescriptorProto::kMessageTypeFieldNumber,
  6598. 1,
  6599. DescriptorProto::kExtensionRangeFieldNumber,
  6600. 1,
  6601. DescriptorProto_ExtensionRange::kOptionsFieldNumber,
  6602. ExtensionRangeOptions::kUninterpretedOptionFieldNumber,
  6603. 0};
  6604. std::vector<int> vpath(path, path + 6);
  6605. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6606. EXPECT_EQ("37:41-37:66", PrintSourceLocation(loc));
  6607. std::vector<int> vunint(unint, unint + 7);
  6608. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6609. }
  6610. // Field option on extension
  6611. {
  6612. int path[] = {FileDescriptorProto::kExtensionFieldNumber, 0,
  6613. FieldDescriptorProto::kOptionsFieldNumber,
  6614. FieldOptions::kPackedFieldNumber};
  6615. int unint[] = {FileDescriptorProto::kExtensionFieldNumber, 0,
  6616. FieldDescriptorProto::kOptionsFieldNumber,
  6617. FieldOptions::kUninterpretedOptionFieldNumber, 0};
  6618. std::vector<int> vpath(path, path + 4);
  6619. EXPECT_TRUE(file_desc->GetSourceLocation(vpath, &loc));
  6620. EXPECT_EQ("40:42-40:53", PrintSourceLocation(loc));
  6621. std::vector<int> vunint(unint, unint + 5);
  6622. EXPECT_FALSE(file_desc->GetSourceLocation(vunint, &loc));
  6623. }
  6624. }
  6625. // Missing SourceCodeInfo doesn't cause crash:
  6626. TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
  6627. SourceLocation loc;
  6628. const FileDescriptor* file_desc =
  6629. GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
  6630. FileDescriptorProto proto;
  6631. file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
  6632. EXPECT_FALSE(proto.has_source_code_info());
  6633. DescriptorPool bad1_pool(&pool_);
  6634. const FileDescriptor* bad1_file_desc =
  6635. GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
  6636. const Descriptor* bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
  6637. EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
  6638. }
  6639. // Corrupt SourceCodeInfo doesn't cause crash:
  6640. TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
  6641. SourceLocation loc;
  6642. const FileDescriptor* file_desc =
  6643. GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
  6644. FileDescriptorProto proto;
  6645. file_desc->CopyTo(&proto); // Note, this discards the SourceCodeInfo.
  6646. EXPECT_FALSE(proto.has_source_code_info());
  6647. SourceCodeInfo_Location* loc_msg =
  6648. proto.mutable_source_code_info()->add_location();
  6649. loc_msg->add_path(1);
  6650. loc_msg->add_path(2);
  6651. loc_msg->add_path(3);
  6652. loc_msg->add_span(4);
  6653. loc_msg->add_span(5);
  6654. loc_msg->add_span(6);
  6655. DescriptorPool bad2_pool(&pool_);
  6656. const FileDescriptor* bad2_file_desc =
  6657. GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
  6658. const Descriptor* bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
  6659. EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
  6660. }
  6661. // ===================================================================
  6662. const char* const kCopySourceCodeInfoToTestInput =
  6663. "syntax = \"proto2\";\n"
  6664. "message Foo {}\n";
  6665. // Required since source code information is not preserved by
  6666. // FileDescriptorTest.
  6667. class CopySourceCodeInfoToTest : public testing::Test {
  6668. public:
  6669. CopySourceCodeInfoToTest()
  6670. : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
  6671. db_(&source_tree_),
  6672. pool_(&db_, &collector_) {}
  6673. private:
  6674. AbortingErrorCollector collector_;
  6675. SingletonSourceTree source_tree_;
  6676. compiler::SourceTreeDescriptorDatabase db_;
  6677. protected:
  6678. DescriptorPool pool_;
  6679. };
  6680. TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
  6681. const FileDescriptor* file_desc =
  6682. GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
  6683. FileDescriptorProto file_desc_proto;
  6684. ASSERT_FALSE(file_desc_proto.has_source_code_info());
  6685. file_desc->CopyTo(&file_desc_proto);
  6686. EXPECT_FALSE(file_desc_proto.has_source_code_info());
  6687. }
  6688. TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
  6689. const FileDescriptor* file_desc =
  6690. GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
  6691. FileDescriptorProto file_desc_proto;
  6692. ASSERT_FALSE(file_desc_proto.has_source_code_info());
  6693. file_desc->CopySourceCodeInfoTo(&file_desc_proto);
  6694. const SourceCodeInfo& info = file_desc_proto.source_code_info();
  6695. ASSERT_EQ(4, info.location_size());
  6696. // Get the Foo message location
  6697. const SourceCodeInfo_Location& foo_location = info.location(2);
  6698. ASSERT_EQ(2, foo_location.path_size());
  6699. EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
  6700. EXPECT_EQ(0, foo_location.path(1)); // Foo is the first message defined
  6701. ASSERT_EQ(3, foo_location.span_size()); // Foo spans one line
  6702. EXPECT_EQ(1, foo_location.span(0)); // Foo is declared on line 1
  6703. EXPECT_EQ(0, foo_location.span(1)); // Foo starts at column 0
  6704. EXPECT_EQ(14, foo_location.span(2)); // Foo ends on column 14
  6705. }
  6706. // ===================================================================
  6707. class LazilyBuildDependenciesTest : public testing::Test {
  6708. public:
  6709. LazilyBuildDependenciesTest() : pool_(&db_, nullptr) {
  6710. pool_.InternalSetLazilyBuildDependencies();
  6711. }
  6712. void ParseProtoAndAddToDb(const char* proto) {
  6713. FileDescriptorProto tmp;
  6714. ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp));
  6715. db_.Add(tmp);
  6716. }
  6717. void ParseProtoAndAddToDb(const std::string& proto) {
  6718. FileDescriptorProto tmp;
  6719. ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp));
  6720. db_.Add(tmp);
  6721. }
  6722. void AddSimpleMessageProtoFileToDb(const char* file_name,
  6723. const char* message_name) {
  6724. ParseProtoAndAddToDb("name: '" + std::string(file_name) +
  6725. ".proto' "
  6726. "package: \"protobuf_unittest\" "
  6727. "message_type { "
  6728. " name:'" +
  6729. std::string(message_name) +
  6730. "' "
  6731. " field { name:'a' number:1 "
  6732. " label:LABEL_OPTIONAL "
  6733. " type_name:'int32' } "
  6734. "}");
  6735. }
  6736. void AddSimpleEnumProtoFileToDb(const char* file_name, const char* enum_name,
  6737. const char* enum_value_name) {
  6738. ParseProtoAndAddToDb("name: '" + std::string(file_name) +
  6739. ".proto' "
  6740. "package: 'protobuf_unittest' "
  6741. "enum_type { "
  6742. " name:'" +
  6743. std::string(enum_name) +
  6744. "' "
  6745. " value { name:'" +
  6746. std::string(enum_value_name) +
  6747. "' number:1 } "
  6748. "}");
  6749. }
  6750. protected:
  6751. SimpleDescriptorDatabase db_;
  6752. DescriptorPool pool_;
  6753. };
  6754. TEST_F(LazilyBuildDependenciesTest, Message) {
  6755. ParseProtoAndAddToDb(
  6756. "name: 'foo.proto' "
  6757. "package: 'protobuf_unittest' "
  6758. "dependency: 'bar.proto' "
  6759. "message_type { "
  6760. " name:'Foo' "
  6761. " field { name:'bar' number:1 label:LABEL_OPTIONAL "
  6762. "type_name:'.protobuf_unittest.Bar' } "
  6763. "}");
  6764. AddSimpleMessageProtoFileToDb("bar", "Bar");
  6765. // Verify neither has been built yet.
  6766. EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
  6767. EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
  6768. const FileDescriptor* file = pool_.FindFileByName("foo.proto");
  6769. // Verify only foo gets built when asking for foo.proto
  6770. EXPECT_TRUE(file != nullptr);
  6771. EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
  6772. EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
  6773. // Verify calling FindFieldBy* works when the type of the field was
  6774. // not built at cross link time. Verify this doesn't build the file
  6775. // the field's type is defined in, as well.
  6776. const Descriptor* desc = file->FindMessageTypeByName("Foo");
  6777. const FieldDescriptor* field = desc->FindFieldByName("bar");
  6778. EXPECT_TRUE(field != nullptr);
  6779. EXPECT_EQ(field, desc->FindFieldByNumber(1));
  6780. EXPECT_EQ(field, desc->FindFieldByLowercaseName("bar"));
  6781. EXPECT_EQ(field, desc->FindFieldByCamelcaseName("bar"));
  6782. EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
  6783. // Finally, verify that if we call message_type() on the field, we will
  6784. // build the file where the message is defined, and get a valid descriptor
  6785. EXPECT_TRUE(field->message_type() != nullptr);
  6786. EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
  6787. }
  6788. TEST_F(LazilyBuildDependenciesTest, Enum) {
  6789. ParseProtoAndAddToDb(
  6790. "name: 'foo.proto' "
  6791. "package: 'protobuf_unittest' "
  6792. "dependency: 'enum1.proto' "
  6793. "dependency: 'enum2.proto' "
  6794. "message_type { "
  6795. " name:'Lazy' "
  6796. " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
  6797. "type_name:'.protobuf_unittest.Enum1' } "
  6798. " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
  6799. "type_name:'.protobuf_unittest.Enum2' } "
  6800. "}");
  6801. AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
  6802. AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
  6803. const FileDescriptor* file = pool_.FindFileByName("foo.proto");
  6804. // Verify calling enum_type() on a field whose definition is not
  6805. // yet built will build the file and return a descriptor.
  6806. EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
  6807. const Descriptor* desc = file->FindMessageTypeByName("Lazy");
  6808. EXPECT_TRUE(desc != nullptr);
  6809. const FieldDescriptor* field = desc->FindFieldByName("enum1");
  6810. EXPECT_TRUE(field != nullptr);
  6811. EXPECT_TRUE(field->enum_type() != nullptr);
  6812. EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
  6813. // Verify calling default_value_enum() on a field whose definition is not
  6814. // yet built will build the file and return a descriptor to the value.
  6815. EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
  6816. field = desc->FindFieldByName("enum2");
  6817. EXPECT_TRUE(field != nullptr);
  6818. EXPECT_TRUE(field->default_value_enum() != nullptr);
  6819. EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
  6820. }
  6821. TEST_F(LazilyBuildDependenciesTest, Type) {
  6822. ParseProtoAndAddToDb(
  6823. "name: 'foo.proto' "
  6824. "package: 'protobuf_unittest' "
  6825. "dependency: 'message1.proto' "
  6826. "dependency: 'message2.proto' "
  6827. "dependency: 'enum1.proto' "
  6828. "dependency: 'enum2.proto' "
  6829. "message_type { "
  6830. " name:'Lazy' "
  6831. " field { name:'message1' number:1 label:LABEL_OPTIONAL "
  6832. "type_name:'.protobuf_unittest.Message1' } "
  6833. " field { name:'message2' number:1 label:LABEL_OPTIONAL "
  6834. "type_name:'.protobuf_unittest.Message2' } "
  6835. " field { name:'enum1' number:1 label:LABEL_OPTIONAL "
  6836. "type_name:'.protobuf_unittest.Enum1' } "
  6837. " field { name:'enum2' number:1 label:LABEL_OPTIONAL "
  6838. "type_name:'.protobuf_unittest.Enum2' } "
  6839. "}");
  6840. AddSimpleMessageProtoFileToDb("message1", "Message1");
  6841. AddSimpleMessageProtoFileToDb("message2", "Message2");
  6842. AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1");
  6843. AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2");
  6844. const FileDescriptor* file = pool_.FindFileByName("foo.proto");
  6845. // Verify calling type() on a field that is a message type will
  6846. // build the type defined in another file.
  6847. EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
  6848. const Descriptor* desc = file->FindMessageTypeByName("Lazy");
  6849. EXPECT_TRUE(desc != nullptr);
  6850. const FieldDescriptor* field = desc->FindFieldByName("message1");
  6851. EXPECT_TRUE(field != nullptr);
  6852. EXPECT_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE);
  6853. EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
  6854. // Verify calling cpp_type() on a field that is a message type will
  6855. // build the type defined in another file.
  6856. EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
  6857. field = desc->FindFieldByName("message2");
  6858. EXPECT_TRUE(field != nullptr);
  6859. EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_MESSAGE);
  6860. EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
  6861. // Verify calling type() on a field that is an enum type will
  6862. // build the type defined in another file.
  6863. EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto"));
  6864. field = desc->FindFieldByName("enum1");
  6865. EXPECT_TRUE(field != nullptr);
  6866. EXPECT_EQ(field->type(), FieldDescriptor::TYPE_ENUM);
  6867. EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto"));
  6868. // Verify calling cpp_type() on a field that is an enum type will
  6869. // build the type defined in another file.
  6870. EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto"));
  6871. field = desc->FindFieldByName("enum2");
  6872. EXPECT_TRUE(field != nullptr);
  6873. EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM);
  6874. EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto"));
  6875. }
  6876. TEST_F(LazilyBuildDependenciesTest, Extension) {
  6877. ParseProtoAndAddToDb(
  6878. "name: 'foo.proto' "
  6879. "package: 'protobuf_unittest' "
  6880. "dependency: 'bar.proto' "
  6881. "dependency: 'baz.proto' "
  6882. "extension { extendee: '.protobuf_unittest.Bar' name:'bar' number:11"
  6883. " label:LABEL_OPTIONAL type_name:'.protobuf_unittest.Baz' }");
  6884. ParseProtoAndAddToDb(
  6885. "name: 'bar.proto' "
  6886. "package: 'protobuf_unittest' "
  6887. "message_type { "
  6888. " name:'Bar' "
  6889. " extension_range { start: 10 end: 20 }"
  6890. "}");
  6891. AddSimpleMessageProtoFileToDb("baz", "Baz");
  6892. // Verify none have been built yet.
  6893. EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto"));
  6894. EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
  6895. EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
  6896. const FileDescriptor* file = pool_.FindFileByName("foo.proto");
  6897. // Verify foo.bar gets loaded, and bar.proto gets loaded
  6898. // to register the extension. baz.proto should not get loaded.
  6899. EXPECT_TRUE(file != nullptr);
  6900. EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
  6901. EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
  6902. EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
  6903. }
  6904. TEST_F(LazilyBuildDependenciesTest, Service) {
  6905. ParseProtoAndAddToDb(
  6906. "name: 'foo.proto' "
  6907. "package: 'protobuf_unittest' "
  6908. "dependency: 'message1.proto' "
  6909. "dependency: 'message2.proto' "
  6910. "dependency: 'message3.proto' "
  6911. "dependency: 'message4.proto' "
  6912. "service {"
  6913. " name: 'LazyService'"
  6914. " method { name: 'A' input_type: '.protobuf_unittest.Message1' "
  6915. " output_type: '.protobuf_unittest.Message2' }"
  6916. "}");
  6917. AddSimpleMessageProtoFileToDb("message1", "Message1");
  6918. AddSimpleMessageProtoFileToDb("message2", "Message2");
  6919. AddSimpleMessageProtoFileToDb("message3", "Message3");
  6920. AddSimpleMessageProtoFileToDb("message4", "Message4");
  6921. const FileDescriptor* file = pool_.FindFileByName("foo.proto");
  6922. // Verify calling FindServiceByName or FindMethodByName doesn't build the
  6923. // files defining the input and output type, and input_type() and
  6924. // output_type() does indeed build the appropriate files.
  6925. const ServiceDescriptor* service = file->FindServiceByName("LazyService");
  6926. EXPECT_TRUE(service != nullptr);
  6927. const MethodDescriptor* method = service->FindMethodByName("A");
  6928. EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto"));
  6929. EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
  6930. EXPECT_TRUE(method != nullptr);
  6931. EXPECT_TRUE(method->input_type() != nullptr);
  6932. EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto"));
  6933. EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto"));
  6934. EXPECT_TRUE(method->output_type() != nullptr);
  6935. EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto"));
  6936. }
  6937. TEST_F(LazilyBuildDependenciesTest, GeneratedFile) {
  6938. // Most testing is done with custom pools with lazy dependencies forced on,
  6939. // do some sanity checking that lazy imports is on by default for the
  6940. // generated pool, and do custom options testing with generated to
  6941. // be able to use the GetExtension ids for the custom options.
  6942. // Verify none of the files are loaded yet.
  6943. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6944. "google/protobuf/unittest_lazy_dependencies.proto"));
  6945. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6946. "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
  6947. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6948. "google/protobuf/unittest_lazy_dependencies_enum.proto"));
  6949. // Verify calling autogenerated function to get a descriptor in the base
  6950. // file will build that file but none of it's imports. This verifies that
  6951. // lazily_build_dependencies_ is set on the generated pool, and also that
  6952. // the generated function "descriptor()" doesn't somehow subvert the laziness
  6953. // by manually loading the dependencies or something.
  6954. EXPECT_TRUE(protobuf_unittest::lazy_imports::ImportedMessage::descriptor() !=
  6955. nullptr);
  6956. EXPECT_TRUE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6957. "google/protobuf/unittest_lazy_dependencies.proto"));
  6958. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6959. "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
  6960. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6961. "google/protobuf/unittest_lazy_dependencies_enum.proto"));
  6962. // Verify custom options work when defined in an import that isn't loaded,
  6963. // and that a non-default value of a custom option doesn't load the file
  6964. // where that enum is defined.
  6965. const MessageOptions& options =
  6966. protobuf_unittest::lazy_imports::MessageCustomOption::descriptor()
  6967. ->options();
  6968. protobuf_unittest::lazy_imports::LazyEnum custom_option_value =
  6969. options.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
  6970. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6971. "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
  6972. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6973. "google/protobuf/unittest_lazy_dependencies_enum.proto"));
  6974. EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_1);
  6975. const MessageOptions& options2 =
  6976. protobuf_unittest::lazy_imports::MessageCustomOption2::descriptor()
  6977. ->options();
  6978. custom_option_value =
  6979. options2.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option);
  6980. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6981. "google/protobuf/unittest_lazy_dependencies_custom_option.proto"));
  6982. EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded(
  6983. "google/protobuf/unittest_lazy_dependencies_enum.proto"));
  6984. EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_0);
  6985. }
  6986. TEST_F(LazilyBuildDependenciesTest, Dependency) {
  6987. ParseProtoAndAddToDb(
  6988. "name: 'foo.proto' "
  6989. "package: 'protobuf_unittest' "
  6990. "dependency: 'bar.proto' "
  6991. "message_type { "
  6992. " name:'Foo' "
  6993. " field { name:'bar' number:1 label:LABEL_OPTIONAL "
  6994. "type_name:'.protobuf_unittest.Bar' } "
  6995. "}");
  6996. ParseProtoAndAddToDb(
  6997. "name: 'bar.proto' "
  6998. "package: 'protobuf_unittest' "
  6999. "dependency: 'baz.proto' "
  7000. "message_type { "
  7001. " name:'Bar' "
  7002. " field { name:'baz' number:1 label:LABEL_OPTIONAL "
  7003. "type_name:'.protobuf_unittest.Baz' } "
  7004. "}");
  7005. AddSimpleMessageProtoFileToDb("baz", "Baz");
  7006. const FileDescriptor* foo_file = pool_.FindFileByName("foo.proto");
  7007. EXPECT_TRUE(foo_file != nullptr);
  7008. // As expected, requesting foo.proto shouldn't build it's dependencies
  7009. EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto"));
  7010. EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto"));
  7011. EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
  7012. // Verify calling dependency(N) will build the dependency, but
  7013. // not that file's dependencies.
  7014. const FileDescriptor* bar_file = foo_file->dependency(0);
  7015. EXPECT_TRUE(bar_file != nullptr);
  7016. EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto"));
  7017. EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto"));
  7018. }
  7019. // ===================================================================
  7020. } // namespace descriptor_unittest
  7021. } // namespace protobuf
  7022. } // namespace google