descriptor_unittest.cc 285 KB

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