cpp_message.cc 139 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080
  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. #include <google/protobuf/compiler/cpp/cpp_message.h>
  34. #include <algorithm>
  35. #include <functional>
  36. #include <map>
  37. #include <memory>
  38. #include <unordered_map>
  39. #include <utility>
  40. #include <vector>
  41. #include <google/protobuf/compiler/cpp/cpp_enum.h>
  42. #include <google/protobuf/compiler/cpp/cpp_extension.h>
  43. #include <google/protobuf/compiler/cpp/cpp_field.h>
  44. #include <google/protobuf/compiler/cpp/cpp_helpers.h>
  45. #include <google/protobuf/compiler/cpp/cpp_padding_optimizer.h>
  46. #include <google/protobuf/descriptor.pb.h>
  47. #include <google/protobuf/io/coded_stream.h>
  48. #include <google/protobuf/io/printer.h>
  49. #include <google/protobuf/generated_message_table_driven.h>
  50. #include <google/protobuf/generated_message_util.h>
  51. #include <google/protobuf/map_entry_lite.h>
  52. #include <google/protobuf/wire_format.h>
  53. #include <google/protobuf/stubs/strutil.h>
  54. #include <google/protobuf/stubs/substitute.h>
  55. #include <google/protobuf/stubs/hash.h>
  56. namespace google {
  57. namespace protobuf {
  58. namespace compiler {
  59. namespace cpp {
  60. using internal::WireFormat;
  61. using internal::WireFormatLite;
  62. namespace {
  63. static constexpr int kNoHasbit = -1;
  64. // Create an expression that evaluates to
  65. // "for all i, (_has_bits_[i] & masks[i]) == masks[i]"
  66. // masks is allowed to be shorter than _has_bits_, but at least one element of
  67. // masks must be non-zero.
  68. std::string ConditionalToCheckBitmasks(
  69. const std::vector<uint32>& masks, bool return_success = true,
  70. StringPiece has_bits_var = "_has_bits_") {
  71. std::vector<std::string> parts;
  72. for (int i = 0; i < masks.size(); i++) {
  73. if (masks[i] == 0) continue;
  74. std::string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
  75. // Each xor evaluates to 0 if the expected bits are present.
  76. parts.push_back(
  77. StrCat("((", has_bits_var, "[", i, "] & ", m, ") ^ ", m, ")"));
  78. }
  79. GOOGLE_CHECK(!parts.empty());
  80. // If we have multiple parts, each expected to be 0, then bitwise-or them.
  81. std::string result =
  82. parts.size() == 1
  83. ? parts[0]
  84. : StrCat("(", Join(parts, "\n | "), ")");
  85. return result + (return_success ? " == 0" : " != 0");
  86. }
  87. void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field,
  88. const std::vector<int>& has_bit_indices,
  89. io::Printer* printer, int* cached_has_word_index) {
  90. if (!field->options().weak()) {
  91. int has_bit_index = has_bit_indices[field->index()];
  92. if (*cached_has_word_index != (has_bit_index / 32)) {
  93. *cached_has_word_index = (has_bit_index / 32);
  94. format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_word_index);
  95. }
  96. const std::string mask =
  97. StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  98. format("if (cached_has_bits & 0x$1$u) {\n", mask);
  99. } else {
  100. format("if (has_$1$()) {\n", FieldName(field));
  101. }
  102. format.Indent();
  103. }
  104. struct FieldOrderingByNumber {
  105. inline bool operator()(const FieldDescriptor* a,
  106. const FieldDescriptor* b) const {
  107. return a->number() < b->number();
  108. }
  109. };
  110. // Sort the fields of the given Descriptor by number into a new[]'d array
  111. // and return it.
  112. std::vector<const FieldDescriptor*> SortFieldsByNumber(
  113. const Descriptor* descriptor) {
  114. std::vector<const FieldDescriptor*> fields(descriptor->field_count());
  115. for (int i = 0; i < descriptor->field_count(); i++) {
  116. fields[i] = descriptor->field(i);
  117. }
  118. std::sort(fields.begin(), fields.end(), FieldOrderingByNumber());
  119. return fields;
  120. }
  121. // Functor for sorting extension ranges by their "start" field number.
  122. struct ExtensionRangeSorter {
  123. bool operator()(const Descriptor::ExtensionRange* left,
  124. const Descriptor::ExtensionRange* right) const {
  125. return left->start < right->start;
  126. }
  127. };
  128. bool IsPOD(const FieldDescriptor* field) {
  129. if (field->is_repeated() || field->is_extension()) return false;
  130. switch (field->cpp_type()) {
  131. case FieldDescriptor::CPPTYPE_ENUM:
  132. case FieldDescriptor::CPPTYPE_INT32:
  133. case FieldDescriptor::CPPTYPE_INT64:
  134. case FieldDescriptor::CPPTYPE_UINT32:
  135. case FieldDescriptor::CPPTYPE_UINT64:
  136. case FieldDescriptor::CPPTYPE_FLOAT:
  137. case FieldDescriptor::CPPTYPE_DOUBLE:
  138. case FieldDescriptor::CPPTYPE_BOOL:
  139. return true;
  140. case FieldDescriptor::CPPTYPE_STRING:
  141. return false;
  142. default:
  143. return false;
  144. }
  145. }
  146. // Helper for the code that emits the SharedCtor() and InternalSwap() methods.
  147. // Anything that is a POD or a "normal" message (represented by a pointer) can
  148. // be manipulated as raw bytes.
  149. bool CanBeManipulatedAsRawBytes(const FieldDescriptor* field,
  150. const Options& options) {
  151. bool ret = CanInitializeByZeroing(field);
  152. // Non-repeated, non-lazy message fields are simply raw pointers, so we can
  153. // swap them or use memset to initialize these in SharedCtor. We cannot use
  154. // this in Clear, as we need to potentially delete the existing value.
  155. ret = ret || (!field->is_repeated() && !IsLazy(field, options) &&
  156. field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
  157. return ret;
  158. }
  159. // Finds runs of fields for which `predicate` is true.
  160. // RunMap maps from fields that start each run to the number of fields in that
  161. // run. This is optimized for the common case that there are very few runs in
  162. // a message and that most of the eligible fields appear together.
  163. using RunMap = std::unordered_map<const FieldDescriptor*, size_t>;
  164. RunMap FindRuns(const std::vector<const FieldDescriptor*>& fields,
  165. const std::function<bool(const FieldDescriptor*)>& predicate) {
  166. RunMap runs;
  167. const FieldDescriptor* last_start = nullptr;
  168. for (auto field : fields) {
  169. if (predicate(field)) {
  170. if (last_start == nullptr) {
  171. last_start = field;
  172. }
  173. runs[last_start]++;
  174. } else {
  175. last_start = nullptr;
  176. }
  177. }
  178. return runs;
  179. }
  180. // Emits an if-statement with a condition that evaluates to true if |field| is
  181. // considered non-default (will be sent over the wire), for message types
  182. // without true field presence. Should only be called if
  183. // !HasHasbit(field).
  184. bool EmitFieldNonDefaultCondition(io::Printer* printer,
  185. const std::string& prefix,
  186. const FieldDescriptor* field) {
  187. GOOGLE_CHECK(!HasHasbit(field));
  188. Formatter format(printer);
  189. format.Set("prefix", prefix);
  190. format.Set("name", FieldName(field));
  191. // Merge and serialize semantics: primitive fields are merged/serialized only
  192. // if non-zero (numeric) or non-empty (string).
  193. if (!field->is_repeated() && !field->containing_oneof()) {
  194. if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
  195. format("if ($prefix$$name$().size() > 0) {\n");
  196. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  197. // Message fields still have has_$name$() methods.
  198. format("if ($prefix$has_$name$()) {\n");
  199. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE ||
  200. field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) {
  201. // Handle float comparison to prevent -Wfloat-equal warnings
  202. format("if (!($prefix$$name$() <= 0 && $prefix$$name$() >= 0)) {\n");
  203. } else {
  204. format("if ($prefix$$name$() != 0) {\n");
  205. }
  206. format.Indent();
  207. return true;
  208. } else if (field->real_containing_oneof()) {
  209. format("if (_internal_has_$name$()) {\n");
  210. format.Indent();
  211. return true;
  212. }
  213. return false;
  214. }
  215. // Does the given field have a has_$name$() method?
  216. bool HasHasMethod(const FieldDescriptor* field) {
  217. if (HasFieldPresence(field->file())) {
  218. // In proto1/proto2, every field has a has_$name$() method.
  219. return true;
  220. }
  221. // For message types without true field presence, only fields with a message
  222. // type have a has_$name$() method.
  223. return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
  224. field->has_optional_keyword();
  225. }
  226. // Collects map entry message type information.
  227. void CollectMapInfo(const Options& options, const Descriptor* descriptor,
  228. std::map<std::string, std::string>* variables) {
  229. GOOGLE_CHECK(IsMapEntryMessage(descriptor));
  230. std::map<std::string, std::string>& vars = *variables;
  231. const FieldDescriptor* key = descriptor->FindFieldByName("key");
  232. const FieldDescriptor* val = descriptor->FindFieldByName("value");
  233. vars["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
  234. switch (val->cpp_type()) {
  235. case FieldDescriptor::CPPTYPE_MESSAGE:
  236. vars["val_cpp"] = FieldMessageTypeName(val, options);
  237. break;
  238. case FieldDescriptor::CPPTYPE_ENUM:
  239. vars["val_cpp"] = ClassName(val->enum_type(), true);
  240. break;
  241. default:
  242. vars["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
  243. }
  244. vars["key_wire_type"] =
  245. "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
  246. vars["val_wire_type"] =
  247. "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
  248. if (descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
  249. val->type() == FieldDescriptor::TYPE_ENUM) {
  250. const EnumValueDescriptor* default_value = val->default_value_enum();
  251. vars["default_enum_value"] = Int32ToString(default_value->number());
  252. } else {
  253. vars["default_enum_value"] = "0";
  254. }
  255. }
  256. // Does the given field have a private (internal helper only) has_$name$()
  257. // method?
  258. bool HasPrivateHasMethod(const FieldDescriptor* field) {
  259. // Only for oneofs in message types with no field presence. has_$name$(),
  260. // based on the oneof case, is still useful internally for generated code.
  261. return (!HasFieldPresence(field->file()) && field->real_containing_oneof());
  262. }
  263. // TODO(ckennelly): Cull these exclusions if/when these protos do not have
  264. // their methods overridden by subclasses.
  265. bool ShouldMarkClassAsFinal(const Descriptor* descriptor,
  266. const Options& options) {
  267. return true;
  268. }
  269. bool ShouldMarkClearAsFinal(const Descriptor* descriptor,
  270. const Options& options) {
  271. static std::set<std::string> exclusions{
  272. };
  273. const std::string name = ClassName(descriptor, true);
  274. return exclusions.find(name) == exclusions.end() ||
  275. options.opensource_runtime;
  276. }
  277. bool ShouldMarkIsInitializedAsFinal(const Descriptor* descriptor,
  278. const Options& options) {
  279. static std::set<std::string> exclusions{
  280. };
  281. const std::string name = ClassName(descriptor, true);
  282. return exclusions.find(name) == exclusions.end() ||
  283. options.opensource_runtime;
  284. }
  285. bool ShouldMarkNewAsFinal(const Descriptor* descriptor,
  286. const Options& options) {
  287. static std::set<std::string> exclusions{
  288. };
  289. const std::string name = ClassName(descriptor, true);
  290. return exclusions.find(name) == exclusions.end() ||
  291. options.opensource_runtime;
  292. }
  293. bool TableDrivenParsingEnabled(const Descriptor* descriptor,
  294. const Options& options) {
  295. if (!options.table_driven_parsing) {
  296. return false;
  297. }
  298. // Consider table-driven parsing. We only do this if:
  299. // - We have has_bits for fields. This avoids a check on every field we set
  300. // when are present (the common case).
  301. bool has_hasbit = false;
  302. for (int i = 0; i < descriptor->field_count(); i++) {
  303. if (HasHasbit(descriptor->field(i))) {
  304. has_hasbit = true;
  305. break;
  306. }
  307. }
  308. if (!has_hasbit) return false;
  309. const double table_sparseness = 0.5;
  310. int max_field_number = 0;
  311. for (auto field : FieldRange(descriptor)) {
  312. if (max_field_number < field->number()) {
  313. max_field_number = field->number();
  314. }
  315. // - There are no weak fields.
  316. if (IsWeak(field, options)) {
  317. return false;
  318. }
  319. // - There are no lazy fields (they require the non-lite library).
  320. if (IsLazy(field, options)) {
  321. return false;
  322. }
  323. }
  324. // - There range of field numbers is "small"
  325. if (max_field_number >= (2 << 14)) {
  326. return false;
  327. }
  328. // - Field numbers are relatively dense within the actual number of fields.
  329. // We check for strictly greater than in the case where there are no fields
  330. // (only extensions) so max_field_number == descriptor->field_count() == 0.
  331. if (max_field_number * table_sparseness > descriptor->field_count()) {
  332. return false;
  333. }
  334. // - This is not a MapEntryMessage.
  335. if (IsMapEntryMessage(descriptor)) {
  336. return false;
  337. }
  338. return true;
  339. }
  340. bool IsCrossFileMapField(const FieldDescriptor* field) {
  341. if (!field->is_map()) {
  342. return false;
  343. }
  344. const Descriptor* d = field->message_type();
  345. const FieldDescriptor* value = d->FindFieldByNumber(2);
  346. return IsCrossFileMessage(value);
  347. }
  348. bool IsCrossFileMaybeMap(const FieldDescriptor* field) {
  349. if (IsCrossFileMapField(field)) {
  350. return true;
  351. }
  352. return IsCrossFileMessage(field);
  353. }
  354. bool IsRequired(const std::vector<const FieldDescriptor*>& v) {
  355. return v.front()->is_required();
  356. }
  357. // Collects neighboring fields based on a given criteria (equivalent predicate).
  358. template <typename Predicate>
  359. std::vector<std::vector<const FieldDescriptor*>> CollectFields(
  360. const std::vector<const FieldDescriptor*>& fields,
  361. const Predicate& equivalent) {
  362. std::vector<std::vector<const FieldDescriptor*>> chunks;
  363. for (auto field : fields) {
  364. if (chunks.empty() || !equivalent(chunks.back().back(), field)) {
  365. chunks.emplace_back();
  366. }
  367. chunks.back().push_back(field);
  368. }
  369. return chunks;
  370. }
  371. // Returns a bit mask based on has_bit index of "fields" that are typically on
  372. // the same chunk. It is used in a group presence check where _has_bits_ is
  373. // masked to tell if any thing in "fields" is present.
  374. uint32 GenChunkMask(const std::vector<const FieldDescriptor*>& fields,
  375. const std::vector<int>& has_bit_indices) {
  376. GOOGLE_CHECK(!fields.empty());
  377. int first_index_offset = has_bit_indices[fields.front()->index()] / 32;
  378. uint32 chunk_mask = 0;
  379. for (auto field : fields) {
  380. // "index" defines where in the _has_bits_ the field appears.
  381. int index = has_bit_indices[field->index()];
  382. GOOGLE_CHECK_EQ(first_index_offset, index / 32);
  383. chunk_mask |= static_cast<uint32>(1) << (index % 32);
  384. }
  385. GOOGLE_CHECK_NE(0, chunk_mask);
  386. return chunk_mask;
  387. }
  388. // Return the number of bits set in n, a non-negative integer.
  389. static int popcnt(uint32 n) {
  390. int result = 0;
  391. while (n != 0) {
  392. result += (n & 1);
  393. n = n / 2;
  394. }
  395. return result;
  396. }
  397. // For a run of cold chunks, opens and closes an external if statement that
  398. // checks multiple has_bits words to skip bulk of cold fields.
  399. class ColdChunkSkipper {
  400. public:
  401. ColdChunkSkipper(
  402. const Options& options,
  403. const std::vector<std::vector<const FieldDescriptor*>>& chunks,
  404. const std::vector<int>& has_bit_indices, const double cold_threshold)
  405. : chunks_(chunks),
  406. has_bit_indices_(has_bit_indices),
  407. access_info_map_(options.access_info_map),
  408. cold_threshold_(cold_threshold) {
  409. SetCommonVars(options, &variables_);
  410. }
  411. // May open an external if check for a batch of cold fields. "from" is the
  412. // prefix to _has_bits_ to allow MergeFrom to use "from._has_bits_".
  413. // Otherwise, it should be "".
  414. void OnStartChunk(int chunk, int cached_has_word_index,
  415. const std::string& from, io::Printer* printer);
  416. bool OnEndChunk(int chunk, io::Printer* printer);
  417. private:
  418. bool IsColdChunk(int chunk);
  419. int HasbitWord(int chunk, int offset) {
  420. return has_bit_indices_[chunks_[chunk][offset]->index()] / 32;
  421. }
  422. const std::vector<std::vector<const FieldDescriptor*>>& chunks_;
  423. const std::vector<int>& has_bit_indices_;
  424. const AccessInfoMap* access_info_map_;
  425. const double cold_threshold_;
  426. std::map<std::string, std::string> variables_;
  427. int limit_chunk_ = -1;
  428. };
  429. // Tuning parameters for ColdChunkSkipper.
  430. const double kColdRatio = 0.005;
  431. bool ColdChunkSkipper::IsColdChunk(int chunk) {
  432. // Mark this variable as used until it is actually used
  433. (void)cold_threshold_;
  434. return false;
  435. }
  436. void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_word_index,
  437. const std::string& from,
  438. io::Printer* printer) {
  439. Formatter format(printer, variables_);
  440. if (!access_info_map_) {
  441. return;
  442. } else if (chunk < limit_chunk_) {
  443. // We are already inside a run of cold chunks.
  444. return;
  445. } else if (!IsColdChunk(chunk)) {
  446. // We can't start a run of cold chunks.
  447. return;
  448. }
  449. // Find the end of consecutive cold chunks.
  450. limit_chunk_ = chunk;
  451. while (limit_chunk_ < chunks_.size() && IsColdChunk(limit_chunk_)) {
  452. limit_chunk_++;
  453. }
  454. if (limit_chunk_ <= chunk + 1) {
  455. // Require at least two chunks to emit external has_bit checks.
  456. limit_chunk_ = -1;
  457. return;
  458. }
  459. // Emit has_bit check for each has_bit_dword index.
  460. format("if (PROTOBUF_PREDICT_FALSE(");
  461. int first_word = HasbitWord(chunk, 0);
  462. while (chunk < limit_chunk_) {
  463. uint32 mask = 0;
  464. int this_word = HasbitWord(chunk, 0);
  465. // Generate mask for chunks on the same word.
  466. for (; chunk < limit_chunk_ && HasbitWord(chunk, 0) == this_word; chunk++) {
  467. for (auto field : chunks_[chunk]) {
  468. int hasbit_index = has_bit_indices_[field->index()];
  469. // Fields on a chunk must be in the same word.
  470. GOOGLE_CHECK_EQ(this_word, hasbit_index / 32);
  471. mask |= 1 << (hasbit_index % 32);
  472. }
  473. }
  474. if (this_word != first_word) {
  475. format(" ||\n ");
  476. }
  477. format.Set("mask", strings::Hex(mask, strings::ZERO_PAD_8));
  478. if (this_word == cached_has_word_index) {
  479. format("(cached_has_bits & 0x$mask$u) != 0");
  480. } else {
  481. format("($1$_has_bits_[$2$] & 0x$mask$u) != 0", from, this_word);
  482. }
  483. }
  484. format(")) {\n");
  485. format.Indent();
  486. }
  487. bool ColdChunkSkipper::OnEndChunk(int chunk, io::Printer* printer) {
  488. Formatter format(printer, variables_);
  489. if (chunk != limit_chunk_ - 1) {
  490. return false;
  491. }
  492. format.Outdent();
  493. format("}\n");
  494. return true;
  495. }
  496. } // anonymous namespace
  497. // ===================================================================
  498. MessageGenerator::MessageGenerator(
  499. const Descriptor* descriptor,
  500. const std::map<std::string, std::string>& vars, int index_in_file_messages,
  501. const Options& options, MessageSCCAnalyzer* scc_analyzer)
  502. : descriptor_(descriptor),
  503. index_in_file_messages_(index_in_file_messages),
  504. classname_(ClassName(descriptor, false)),
  505. options_(options),
  506. field_generators_(descriptor, options, scc_analyzer),
  507. max_has_bit_index_(0),
  508. num_weak_fields_(0),
  509. scc_analyzer_(scc_analyzer),
  510. variables_(vars) {
  511. if (!message_layout_helper_) {
  512. message_layout_helper_.reset(new PaddingOptimizer());
  513. }
  514. // Variables that apply to this class
  515. variables_["classname"] = classname_;
  516. variables_["classtype"] = QualifiedClassName(descriptor_, options);
  517. variables_["scc_info"] =
  518. SccInfoSymbol(scc_analyzer_->GetSCC(descriptor_), options_);
  519. variables_["full_name"] = descriptor_->full_name();
  520. variables_["superclass"] = SuperClassName(descriptor_, options_);
  521. // Compute optimized field order to be used for layout and initialization
  522. // purposes.
  523. for (auto field : FieldRange(descriptor_)) {
  524. if (!IsFieldUsed(field, options_)) {
  525. continue;
  526. }
  527. if (IsWeak(field, options_)) {
  528. num_weak_fields_++;
  529. } else if (!field->real_containing_oneof()) {
  530. optimized_order_.push_back(field);
  531. }
  532. }
  533. message_layout_helper_->OptimizeLayout(&optimized_order_, options_);
  534. // This message has hasbits iff one or more fields need one.
  535. for (auto field : optimized_order_) {
  536. if (HasHasbit(field)) {
  537. if (has_bit_indices_.empty()) {
  538. has_bit_indices_.resize(descriptor_->field_count(), kNoHasbit);
  539. }
  540. has_bit_indices_[field->index()] = max_has_bit_index_++;
  541. }
  542. }
  543. if (!has_bit_indices_.empty()) {
  544. field_generators_.SetHasBitIndices(has_bit_indices_);
  545. }
  546. num_required_fields_ = 0;
  547. for (int i = 0; i < descriptor->field_count(); i++) {
  548. if (descriptor->field(i)->is_required()) {
  549. ++num_required_fields_;
  550. }
  551. }
  552. table_driven_ = TableDrivenParsingEnabled(descriptor_, options_);
  553. }
  554. MessageGenerator::~MessageGenerator() = default;
  555. size_t MessageGenerator::HasBitsSize() const {
  556. size_t sizeof_has_bits = (max_has_bit_index_ + 31) / 32 * 4;
  557. if (sizeof_has_bits == 0) {
  558. // Zero-size arrays aren't technically allowed, and MSVC in particular
  559. // doesn't like them. We still need to declare these arrays to make
  560. // other code compile. Since this is an uncommon case, we'll just declare
  561. // them with size 1 and waste some space. Oh well.
  562. sizeof_has_bits = 4;
  563. }
  564. return sizeof_has_bits;
  565. }
  566. int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const {
  567. return has_bit_indices_.empty() ? kNoHasbit
  568. : has_bit_indices_[field->index()];
  569. }
  570. int MessageGenerator::HasByteIndex(const FieldDescriptor* field) const {
  571. int hasbit = HasBitIndex(field);
  572. return hasbit == kNoHasbit ? kNoHasbit : hasbit / 8;
  573. }
  574. int MessageGenerator::HasWordIndex(const FieldDescriptor* field) const {
  575. int hasbit = HasBitIndex(field);
  576. return hasbit == kNoHasbit ? kNoHasbit : hasbit / 32;
  577. }
  578. void MessageGenerator::AddGenerators(
  579. std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
  580. std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators) {
  581. for (int i = 0; i < descriptor_->enum_type_count(); i++) {
  582. enum_generators->emplace_back(
  583. new EnumGenerator(descriptor_->enum_type(i), variables_, options_));
  584. enum_generators_.push_back(enum_generators->back().get());
  585. }
  586. for (int i = 0; i < descriptor_->extension_count(); i++) {
  587. extension_generators->emplace_back(
  588. new ExtensionGenerator(descriptor_->extension(i), options_));
  589. extension_generators_.push_back(extension_generators->back().get());
  590. }
  591. }
  592. void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) {
  593. Formatter format(printer, variables_);
  594. // optimized_fields_ does not contain fields where
  595. // field->real_containing_oneof()
  596. // so we need to iterate over those as well.
  597. //
  598. // We place the non-oneof fields in optimized_order_, as that controls the
  599. // order of the _has_bits_ entries and we want GDB's pretty printers to be
  600. // able to infer these indices from the k[FIELDNAME]FieldNumber order.
  601. std::vector<const FieldDescriptor*> ordered_fields;
  602. ordered_fields.reserve(descriptor_->field_count());
  603. ordered_fields.insert(ordered_fields.begin(), optimized_order_.begin(),
  604. optimized_order_.end());
  605. for (auto field : FieldRange(descriptor_)) {
  606. if (!field->real_containing_oneof() && !field->options().weak() &&
  607. IsFieldUsed(field, options_)) {
  608. continue;
  609. }
  610. ordered_fields.push_back(field);
  611. }
  612. if (!ordered_fields.empty()) {
  613. format("enum : int {\n");
  614. for (auto field : ordered_fields) {
  615. Formatter::SaveState save(&format);
  616. std::map<std::string, std::string> vars;
  617. SetCommonFieldVariables(field, &vars, options_);
  618. format.AddMap(vars);
  619. format(" ${1$$2$$}$ = $number$,\n", field, FieldConstantName(field));
  620. }
  621. format("};\n");
  622. }
  623. for (auto field : ordered_fields) {
  624. PrintFieldComment(format, field);
  625. Formatter::SaveState save(&format);
  626. std::map<std::string, std::string> vars;
  627. SetCommonFieldVariables(field, &vars, options_);
  628. format.AddMap(vars);
  629. if (field->is_repeated()) {
  630. format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field,
  631. IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}");
  632. if (IsFieldUsed(field, options_)) {
  633. format(
  634. "private:\n"
  635. "int ${1$_internal_$name$_size$}$() const;\n"
  636. "public:\n",
  637. field);
  638. }
  639. } else if (HasHasMethod(field)) {
  640. format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field,
  641. IsFieldUsed(field, options_) ? ";" : " {__builtin_trap();}");
  642. if (IsFieldUsed(field, options_)) {
  643. format(
  644. "private:\n"
  645. "bool _internal_has_$name$() const;\n"
  646. "public:\n");
  647. }
  648. } else if (HasPrivateHasMethod(field)) {
  649. if (IsFieldUsed(field, options_)) {
  650. format(
  651. "private:\n"
  652. "bool ${1$_internal_has_$name$$}$() const;\n"
  653. "public:\n",
  654. field);
  655. }
  656. }
  657. format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field,
  658. IsFieldUsed(field, options_) ? ";" : "{__builtin_trap();}");
  659. // Generate type-specific accessor declarations.
  660. field_generators_.get(field).GenerateAccessorDeclarations(printer);
  661. format("\n");
  662. }
  663. if (descriptor_->extension_range_count() > 0) {
  664. // Generate accessors for extensions. We just call a macro located in
  665. // extension_set.h since the accessors about 80 lines of static code.
  666. format("$GOOGLE_PROTOBUF$_EXTENSION_ACCESSORS($classname$)\n");
  667. // Generate MessageSet specific APIs for proto2 MessageSet.
  668. // For testing purposes we don't check for bridge.MessageSet, so
  669. // we don't use IsProto2MessageSet
  670. if (descriptor_->options().message_set_wire_format() &&
  671. !options_.opensource_runtime && !options_.lite_implicit_weak_fields) {
  672. // Special-case MessageSet
  673. format("GOOGLE_PROTOBUF_EXTENSION_MESSAGE_SET_ACCESSORS($classname$)\n");
  674. }
  675. }
  676. for (auto oneof : OneOfRange(descriptor_)) {
  677. Formatter::SaveState saver(&format);
  678. format.Set("oneof_name", oneof->name());
  679. format.Set("camel_oneof_name", UnderscoresToCamelCase(oneof->name(), true));
  680. format(
  681. "void ${1$clear_$oneof_name$$}$();\n"
  682. "$camel_oneof_name$Case $oneof_name$_case() const;\n",
  683. oneof);
  684. }
  685. }
  686. void MessageGenerator::GenerateSingularFieldHasBits(
  687. const FieldDescriptor* field, Formatter format) {
  688. if (!IsFieldUsed(field, options_)) {
  689. format(
  690. "inline bool $classname$::has_$name$() const { "
  691. "__builtin_trap(); }\n");
  692. return;
  693. }
  694. if (field->options().weak()) {
  695. format(
  696. "inline bool $classname$::has_$name$() const {\n"
  697. "$annotate_accessor$"
  698. " return _weak_field_map_.Has($number$);\n"
  699. "}\n");
  700. return;
  701. }
  702. if (HasHasbit(field)) {
  703. int has_bit_index = HasBitIndex(field);
  704. GOOGLE_CHECK_NE(has_bit_index, kNoHasbit);
  705. format.Set("has_array_index", has_bit_index / 32);
  706. format.Set("has_mask",
  707. strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  708. format(
  709. "inline bool $classname$::_internal_has_$name$() const {\n"
  710. " bool value = "
  711. "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n");
  712. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  713. !IsLazy(field, options_)) {
  714. // We maintain the invariant that for a submessage x, has_x() returning
  715. // true implies that x_ is not null. By giving this information to the
  716. // compiler, we allow it to eliminate unnecessary null checks later on.
  717. format(" PROTOBUF_ASSUME(!value || $name$_ != nullptr);\n");
  718. }
  719. format(
  720. " return value;\n"
  721. "}\n"
  722. "inline bool $classname$::has_$name$() const {\n"
  723. "$annotate_accessor$"
  724. " return _internal_has_$name$();\n"
  725. "}\n");
  726. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  727. // Message fields have a has_$name$() method.
  728. if (IsLazy(field, options_)) {
  729. format(
  730. "inline bool $classname$::_internal_has_$name$() const {\n"
  731. " return !$name$_.IsCleared();\n"
  732. "}\n");
  733. } else {
  734. format(
  735. "inline bool $classname$::_internal_has_$name$() const {\n"
  736. " return this != internal_default_instance() "
  737. "&& $name$_ != nullptr;\n"
  738. "}\n");
  739. }
  740. format(
  741. "inline bool $classname$::has_$name$() const {\n"
  742. "$annotate_accessor$"
  743. " return _internal_has_$name$();\n"
  744. "}\n");
  745. }
  746. }
  747. void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) {
  748. Formatter format(printer, variables_);
  749. for (auto oneof : OneOfRange(descriptor_)) {
  750. format.Set("oneof_name", oneof->name());
  751. format.Set("oneof_index", oneof->index());
  752. format.Set("cap_oneof_name", ToUpper(oneof->name()));
  753. format(
  754. "inline bool $classname$::has_$oneof_name$() const {\n"
  755. " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
  756. "}\n"
  757. "inline void $classname$::clear_has_$oneof_name$() {\n"
  758. " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
  759. "}\n");
  760. }
  761. }
  762. void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field,
  763. const Formatter& format) {
  764. if (!IsFieldUsed(field, options_)) {
  765. if (HasHasMethod(field)) {
  766. format(
  767. "inline bool $classname$::has_$name$() const { "
  768. "__builtin_trap(); }\n");
  769. }
  770. format(
  771. "inline void $classname$::set_has_$name$() { __builtin_trap(); "
  772. "}\n");
  773. return;
  774. }
  775. // Singular field in a oneof
  776. // N.B.: Without field presence, we do not use has-bits or generate
  777. // has_$name$() methods, but oneofs still have set_has_$name$().
  778. // Oneofs also have has_$name$() but only as a private helper
  779. // method, so that generated code is slightly cleaner (vs. comparing
  780. // _oneof_case_[index] against a constant everywhere).
  781. //
  782. // If has_$name$() is private, there is no need to add an internal accessor.
  783. // Only annotate public accessors.
  784. if (HasHasMethod(field)) {
  785. format(
  786. "inline bool $classname$::_internal_has_$name$() const {\n"
  787. " return $oneof_name$_case() == k$field_name$;\n"
  788. "}\n"
  789. "inline bool $classname$::has_$name$() const {\n"
  790. "$annotate_accessor$"
  791. " return _internal_has_$name$();\n"
  792. "}\n");
  793. } else if (HasPrivateHasMethod(field)) {
  794. format(
  795. "inline bool $classname$::_internal_has_$name$() const {\n"
  796. " return $oneof_name$_case() == k$field_name$;\n"
  797. "}\n");
  798. }
  799. // set_has_$name$() for oneof fields is always private; hence should not be
  800. // annotated.
  801. format(
  802. "inline void $classname$::set_has_$name$() {\n"
  803. " _oneof_case_[$oneof_index$] = k$field_name$;\n"
  804. "}\n");
  805. }
  806. void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
  807. bool is_inline, Formatter format) {
  808. if (!IsFieldUsed(field, options_)) {
  809. format("void $classname$::clear_$name$() { __builtin_trap(); }\n");
  810. return;
  811. }
  812. // Generate clear_$name$().
  813. if (is_inline) {
  814. format("inline ");
  815. }
  816. format(
  817. "void $classname$::clear_$name$() {\n"
  818. "$annotate_accessor$");
  819. format.Indent();
  820. if (field->real_containing_oneof()) {
  821. // Clear this field only if it is the active field in this oneof,
  822. // otherwise ignore
  823. format("if (_internal_has_$name$()) {\n");
  824. format.Indent();
  825. field_generators_.get(field).GenerateClearingCode(format.printer());
  826. format("clear_has_$oneof_name$();\n");
  827. format.Outdent();
  828. format("}\n");
  829. } else {
  830. field_generators_.get(field).GenerateClearingCode(format.printer());
  831. if (HasHasbit(field)) {
  832. int has_bit_index = HasBitIndex(field);
  833. format.Set("has_array_index", has_bit_index / 32);
  834. format.Set("has_mask",
  835. strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  836. format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n");
  837. }
  838. }
  839. format.Outdent();
  840. format("}\n");
  841. }
  842. void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
  843. Formatter format(printer, variables_);
  844. format("// $classname$\n\n");
  845. for (auto field : FieldRange(descriptor_)) {
  846. PrintFieldComment(format, field);
  847. if (!IsFieldUsed(field, options_)) {
  848. continue;
  849. }
  850. std::map<std::string, std::string> vars;
  851. SetCommonFieldVariables(field, &vars, options_);
  852. Formatter::SaveState saver(&format);
  853. format.AddMap(vars);
  854. // Generate has_$name$() or $name$_size().
  855. if (field->is_repeated()) {
  856. if (!IsFieldUsed(field, options_)) {
  857. format(
  858. "inline int $classname$::$name$_size() const { "
  859. "__builtin_trap(); }\n");
  860. } else {
  861. format(
  862. "inline int $classname$::_internal_$name$_size() const {\n"
  863. " return $name$_$1$.size();\n"
  864. "}\n"
  865. "inline int $classname$::$name$_size() const {\n"
  866. "$annotate_accessor$"
  867. " return _internal_$name$_size();\n"
  868. "}\n",
  869. IsImplicitWeakField(field, options_, scc_analyzer_) &&
  870. field->message_type()
  871. ? ".weak"
  872. : "");
  873. }
  874. } else if (field->real_containing_oneof()) {
  875. format.Set("field_name", UnderscoresToCamelCase(field->name(), true));
  876. format.Set("oneof_name", field->containing_oneof()->name());
  877. format.Set("oneof_index",
  878. StrCat(field->containing_oneof()->index()));
  879. GenerateOneofMemberHasBits(field, format);
  880. } else {
  881. // Singular field.
  882. GenerateSingularFieldHasBits(field, format);
  883. }
  884. if (!IsCrossFileMaybeMap(field)) {
  885. GenerateFieldClear(field, true, format);
  886. }
  887. // Generate type-specific accessors.
  888. if (IsFieldUsed(field, options_)) {
  889. field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
  890. }
  891. format("\n");
  892. }
  893. // Generate has_$name$() and clear_has_$name$() functions for oneofs.
  894. GenerateOneofHasBits(printer);
  895. }
  896. void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
  897. Formatter format(printer, variables_);
  898. format.Set("class_final", ShouldMarkClassAsFinal(descriptor_, options_)
  899. ? "PROTOBUF_FINAL"
  900. : "");
  901. if (IsMapEntryMessage(descriptor_)) {
  902. std::map<std::string, std::string> vars;
  903. CollectMapInfo(options_, descriptor_, &vars);
  904. vars["lite"] =
  905. HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite";
  906. format.AddMap(vars);
  907. format(
  908. "class $classname$ : public "
  909. "::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
  910. " $key_cpp$, $val_cpp$,\n"
  911. " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
  912. " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
  913. " $default_enum_value$ > {\n"
  914. "public:\n"
  915. " typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
  916. " $key_cpp$, $val_cpp$,\n"
  917. " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
  918. " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
  919. " $default_enum_value$ > SuperType;\n"
  920. " $classname$();\n"
  921. " explicit $classname$(::$proto_ns$::Arena* arena);\n"
  922. " void MergeFrom(const $classname$& other);\n"
  923. " static const $classname$* internal_default_instance() { return "
  924. "reinterpret_cast<const "
  925. "$classname$*>(&_$classname$_default_instance_); }\n");
  926. auto utf8_check = GetUtf8CheckMode(descriptor_->field(0), options_);
  927. if (descriptor_->field(0)->type() == FieldDescriptor::TYPE_STRING &&
  928. utf8_check != NONE) {
  929. if (utf8_check == STRICT) {
  930. format(
  931. " static bool ValidateKey(std::string* s) {\n"
  932. " return ::$proto_ns$::internal::WireFormatLite::"
  933. "VerifyUtf8String(s->data(), static_cast<int>(s->size()), "
  934. "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n"
  935. " }\n",
  936. descriptor_->field(0)->full_name());
  937. } else {
  938. GOOGLE_CHECK(utf8_check == VERIFY);
  939. format(
  940. " static bool ValidateKey(std::string* s) {\n"
  941. "#ifndef NDEBUG\n"
  942. " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
  943. " s->data(), static_cast<int>(s->size()), "
  944. "::$proto_ns$::internal::"
  945. "WireFormatLite::PARSE, \"$1$\");\n"
  946. "#endif\n"
  947. " return true;\n"
  948. " }\n",
  949. descriptor_->field(0)->full_name());
  950. }
  951. } else {
  952. format(" static bool ValidateKey(void*) { return true; }\n");
  953. }
  954. if (descriptor_->field(1)->type() == FieldDescriptor::TYPE_STRING &&
  955. utf8_check != NONE) {
  956. if (utf8_check == STRICT) {
  957. format(
  958. " static bool ValidateValue(std::string* s) {\n"
  959. " return ::$proto_ns$::internal::WireFormatLite::"
  960. "VerifyUtf8String(s->data(), static_cast<int>(s->size()), "
  961. "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n"
  962. " }\n",
  963. descriptor_->field(1)->full_name());
  964. } else {
  965. GOOGLE_CHECK(utf8_check = VERIFY);
  966. format(
  967. " static bool ValidateValue(std::string* s) {\n"
  968. "#ifndef NDEBUG\n"
  969. " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
  970. " s->data(), static_cast<int>(s->size()), "
  971. "::$proto_ns$::internal::"
  972. "WireFormatLite::PARSE, \"$1$\");\n"
  973. "#endif\n"
  974. " return true;\n"
  975. " }\n",
  976. descriptor_->field(1)->full_name());
  977. }
  978. } else {
  979. format(" static bool ValidateValue(void*) { return true; }\n");
  980. }
  981. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  982. format(
  983. " void MergeFrom(const ::$proto_ns$::Message& other) final;\n"
  984. " ::$proto_ns$::Metadata GetMetadata() const final;\n"
  985. " private:\n"
  986. " static ::$proto_ns$::Metadata GetMetadataStatic() {\n"
  987. " ::$proto_ns$::internal::AssignDescriptors(&::$desc_table$);\n"
  988. " return ::$desc_table$.file_level_metadata[$1$];\n"
  989. " }\n"
  990. "\n"
  991. " public:\n"
  992. "};\n",
  993. index_in_file_messages_);
  994. } else {
  995. format("};\n");
  996. }
  997. return;
  998. }
  999. format(
  1000. "class $dllexport_decl $${1$$classname$$}$$ class_final$ :\n"
  1001. " public $superclass$ /* @@protoc_insertion_point("
  1002. "class_definition:$full_name$) */ {\n",
  1003. descriptor_);
  1004. format(" public:\n");
  1005. format.Indent();
  1006. if (SupportsArenas(descriptor_)) {
  1007. format("inline $classname$() : $classname$(nullptr) {};\n");
  1008. } else {
  1009. format("$classname$();\n");
  1010. }
  1011. format(
  1012. "virtual ~$classname$();\n"
  1013. "\n"
  1014. "$classname$(const $classname$& from);\n"
  1015. "$classname$($classname$&& from) noexcept\n"
  1016. " : $classname$() {\n"
  1017. " *this = ::std::move(from);\n"
  1018. "}\n"
  1019. "\n"
  1020. "inline $classname$& operator=(const $classname$& from) {\n"
  1021. " CopyFrom(from);\n"
  1022. " return *this;\n"
  1023. "}\n"
  1024. "inline $classname$& operator=($classname$&& from) noexcept {\n"
  1025. " if (GetArena() == from.GetArena()) {\n"
  1026. " if (this != &from) InternalSwap(&from);\n"
  1027. " } else {\n"
  1028. " CopyFrom(from);\n"
  1029. " }\n"
  1030. " return *this;\n"
  1031. "}\n"
  1032. "\n");
  1033. if (options_.table_driven_serialization) {
  1034. format(
  1035. "private:\n"
  1036. "const void* InternalGetTable() const;\n"
  1037. "public:\n"
  1038. "\n");
  1039. }
  1040. std::map<std::string, std::string> vars;
  1041. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  1042. format.AddMap(vars);
  1043. if (PublicUnknownFieldsAccessors(descriptor_)) {
  1044. format(
  1045. "inline const $unknown_fields_type$& unknown_fields() const {\n"
  1046. " return $unknown_fields$;\n"
  1047. "}\n"
  1048. "inline $unknown_fields_type$* mutable_unknown_fields() {\n"
  1049. " return $mutable_unknown_fields$;\n"
  1050. "}\n"
  1051. "\n");
  1052. }
  1053. // Only generate this member if it's not disabled.
  1054. if (HasDescriptorMethods(descriptor_->file(), options_) &&
  1055. !descriptor_->options().no_standard_descriptor_accessor()) {
  1056. format(
  1057. "static const ::$proto_ns$::Descriptor* descriptor() {\n"
  1058. " return GetDescriptor();\n"
  1059. "}\n");
  1060. }
  1061. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  1062. // These shadow non-static methods of the same names in Message. We
  1063. // redefine them here because calls directly on the generated class can be
  1064. // statically analyzed -- we know what descriptor types are being requested.
  1065. // It also avoids a vtable dispatch.
  1066. //
  1067. // We would eventually like to eliminate the methods in Message, and having
  1068. // this separate also lets us track calls to the base class methods
  1069. // separately.
  1070. format(
  1071. "static const ::$proto_ns$::Descriptor* GetDescriptor() {\n"
  1072. " return GetMetadataStatic().descriptor;\n"
  1073. "}\n"
  1074. "static const ::$proto_ns$::Reflection* GetReflection() {\n"
  1075. " return GetMetadataStatic().reflection;\n"
  1076. "}\n");
  1077. }
  1078. format(
  1079. "static const $classname$& default_instance();\n"
  1080. "\n");
  1081. // Generate enum values for every field in oneofs. One list is generated for
  1082. // each oneof with an additional *_NOT_SET value.
  1083. for (auto oneof : OneOfRange(descriptor_)) {
  1084. format("enum $1$Case {\n", UnderscoresToCamelCase(oneof->name(), true));
  1085. format.Indent();
  1086. for (auto field : FieldRange(oneof)) {
  1087. std::string oneof_enum_case_field_name =
  1088. UnderscoresToCamelCase(field->name(), true);
  1089. format("k$1$ = $2$,\n", oneof_enum_case_field_name, // 1
  1090. field->number()); // 2
  1091. }
  1092. format("$1$_NOT_SET = 0,\n", ToUpper(oneof->name()));
  1093. format.Outdent();
  1094. format(
  1095. "};\n"
  1096. "\n");
  1097. }
  1098. // TODO(gerbens) make this private, while still granting other protos access.
  1099. format(
  1100. "static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY\n"
  1101. "static inline const $classname$* internal_default_instance() {\n"
  1102. " return reinterpret_cast<const $classname$*>(\n"
  1103. " &_$classname$_default_instance_);\n"
  1104. "}\n"
  1105. "static constexpr int kIndexInFileMessages =\n"
  1106. " $1$;\n"
  1107. "\n",
  1108. index_in_file_messages_);
  1109. if (IsAnyMessage(descriptor_, options_)) {
  1110. format(
  1111. "// implements Any -----------------------------------------------\n"
  1112. "\n");
  1113. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  1114. format(
  1115. "void PackFrom(const ::$proto_ns$::Message& message) {\n"
  1116. " _any_metadata_.PackFrom(message);\n"
  1117. "}\n"
  1118. "void PackFrom(const ::$proto_ns$::Message& message,\n"
  1119. " const std::string& type_url_prefix) {\n"
  1120. " _any_metadata_.PackFrom(message, type_url_prefix);\n"
  1121. "}\n"
  1122. "bool UnpackTo(::$proto_ns$::Message* message) const {\n"
  1123. " return _any_metadata_.UnpackTo(message);\n"
  1124. "}\n"
  1125. "static bool GetAnyFieldDescriptors(\n"
  1126. " const ::$proto_ns$::Message& message,\n"
  1127. " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
  1128. " const ::$proto_ns$::FieldDescriptor** value_field);\n"
  1129. "template <typename T, class = typename std::enable_if<"
  1130. "!std::is_convertible<T, const ::$proto_ns$::Message&>"
  1131. "::value>::type>\n"
  1132. "void PackFrom(const T& message) {\n"
  1133. " _any_metadata_.PackFrom<T>(message);\n"
  1134. "}\n"
  1135. "template <typename T, class = typename std::enable_if<"
  1136. "!std::is_convertible<T, const ::$proto_ns$::Message&>"
  1137. "::value>::type>\n"
  1138. "void PackFrom(const T& message,\n"
  1139. " const std::string& type_url_prefix) {\n"
  1140. " _any_metadata_.PackFrom<T>(message, type_url_prefix);"
  1141. "}\n"
  1142. "template <typename T, class = typename std::enable_if<"
  1143. "!std::is_convertible<T, const ::$proto_ns$::Message&>"
  1144. "::value>::type>\n"
  1145. "bool UnpackTo(T* message) const {\n"
  1146. " return _any_metadata_.UnpackTo<T>(message);\n"
  1147. "}\n");
  1148. } else {
  1149. format(
  1150. "template <typename T>\n"
  1151. "void PackFrom(const T& message) {\n"
  1152. " _any_metadata_.PackFrom(message);\n"
  1153. "}\n"
  1154. "template <typename T>\n"
  1155. "void PackFrom(const T& message,\n"
  1156. " const std::string& type_url_prefix) {\n"
  1157. " _any_metadata_.PackFrom(message, type_url_prefix);\n"
  1158. "}\n"
  1159. "template <typename T>\n"
  1160. "bool UnpackTo(T* message) const {\n"
  1161. " return _any_metadata_.UnpackTo(message);\n"
  1162. "}\n");
  1163. }
  1164. format(
  1165. "template<typename T> bool Is() const {\n"
  1166. " return _any_metadata_.Is<T>();\n"
  1167. "}\n"
  1168. "static bool ParseAnyTypeUrl(const string& type_url,\n"
  1169. " std::string* full_type_name);\n");
  1170. }
  1171. format.Set("new_final",
  1172. ShouldMarkNewAsFinal(descriptor_, options_) ? "final" : "");
  1173. format(
  1174. "friend void swap($classname$& a, $classname$& b) {\n"
  1175. " a.Swap(&b);\n"
  1176. "}\n");
  1177. if (SupportsArenas(descriptor_)) {
  1178. format(
  1179. "inline void Swap($classname$* other) {\n"
  1180. " if (other == this) return;\n"
  1181. " if (GetArena() == other->GetArena()) {\n"
  1182. " InternalSwap(other);\n"
  1183. " } else {\n"
  1184. " ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n"
  1185. " }\n"
  1186. "}\n"
  1187. "void UnsafeArenaSwap($classname$* other) {\n"
  1188. " if (other == this) return;\n"
  1189. " $DCHK$(GetArena() == other->GetArena());\n"
  1190. " InternalSwap(other);\n"
  1191. "}\n");
  1192. } else {
  1193. format(
  1194. "inline void Swap($classname$* other) {\n"
  1195. " if (other == this) return;\n"
  1196. " InternalSwap(other);\n"
  1197. "}\n");
  1198. }
  1199. format(
  1200. "\n"
  1201. "// implements Message ----------------------------------------------\n"
  1202. "\n"
  1203. "inline $classname$* New() const$ new_final$ {\n"
  1204. " return CreateMaybeMessage<$classname$>(nullptr);\n"
  1205. "}\n"
  1206. "\n"
  1207. "$classname$* New(::$proto_ns$::Arena* arena) const$ new_final$ {\n"
  1208. " return CreateMaybeMessage<$classname$>(arena);\n"
  1209. "}\n");
  1210. // For instances that derive from Message (rather than MessageLite), some
  1211. // methods are virtual and should be marked as final.
  1212. format.Set("full_final", HasDescriptorMethods(descriptor_->file(), options_)
  1213. ? "final"
  1214. : "");
  1215. if (HasGeneratedMethods(descriptor_->file(), options_)) {
  1216. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  1217. format(
  1218. "void CopyFrom(const ::$proto_ns$::Message& from) final;\n"
  1219. "void MergeFrom(const ::$proto_ns$::Message& from) final;\n");
  1220. } else {
  1221. format(
  1222. "void CheckTypeAndMergeFrom(const ::$proto_ns$::MessageLite& from)\n"
  1223. " final;\n");
  1224. }
  1225. format.Set("clear_final",
  1226. ShouldMarkClearAsFinal(descriptor_, options_) ? "final" : "");
  1227. format.Set(
  1228. "is_initialized_final",
  1229. ShouldMarkIsInitializedAsFinal(descriptor_, options_) ? "final" : "");
  1230. format(
  1231. "void CopyFrom(const $classname$& from);\n"
  1232. "void MergeFrom(const $classname$& from);\n"
  1233. "PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear()$ clear_final$;\n"
  1234. "bool IsInitialized() const$ is_initialized_final$;\n"
  1235. "\n"
  1236. "size_t ByteSizeLong() const final;\n"
  1237. "const char* _InternalParse(const char* ptr, "
  1238. "::$proto_ns$::internal::ParseContext* ctx) final;\n"
  1239. "$uint8$* _InternalSerialize(\n"
  1240. " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
  1241. "const final;\n");
  1242. // DiscardUnknownFields() is implemented in message.cc using reflections. We
  1243. // need to implement this function in generated code for messages.
  1244. if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
  1245. format("void DiscardUnknownFields()$ full_final$;\n");
  1246. }
  1247. }
  1248. format(
  1249. "int GetCachedSize() const final { return _cached_size_.Get(); }"
  1250. "\n\nprivate:\n"
  1251. "inline void SharedCtor();\n"
  1252. "inline void SharedDtor();\n"
  1253. "void SetCachedSize(int size) const$ full_final$;\n"
  1254. "void InternalSwap($classname$* other);\n");
  1255. format(
  1256. // Friend AnyMetadata so that it can call this FullMessageName() method.
  1257. "friend class ::$proto_ns$::internal::AnyMetadata;\n"
  1258. "static $1$ FullMessageName() {\n"
  1259. " return \"$full_name$\";\n"
  1260. "}\n",
  1261. options_.opensource_runtime ? "::PROTOBUF_NAMESPACE_ID::StringPiece"
  1262. : "::StringPiece");
  1263. if (SupportsArenas(descriptor_)) {
  1264. format(
  1265. // TODO(gerbens) Make this private! Currently people are deriving from
  1266. // protos to give access to this constructor, breaking the invariants
  1267. // we rely on.
  1268. "protected:\n"
  1269. "explicit $classname$(::$proto_ns$::Arena* arena);\n"
  1270. "private:\n"
  1271. "static void ArenaDtor(void* object);\n"
  1272. "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n");
  1273. }
  1274. format(
  1275. "public:\n"
  1276. "\n");
  1277. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  1278. format(
  1279. "::$proto_ns$::Metadata GetMetadata() const final;\n"
  1280. "private:\n"
  1281. "static ::$proto_ns$::Metadata GetMetadataStatic() {\n"
  1282. " ::$proto_ns$::internal::AssignDescriptors(&::$desc_table$);\n"
  1283. " return ::$desc_table$.file_level_metadata[kIndexInFileMessages];\n"
  1284. "}\n"
  1285. "\n"
  1286. "public:\n"
  1287. "\n");
  1288. } else {
  1289. format(
  1290. "std::string GetTypeName() const final;\n"
  1291. "\n");
  1292. }
  1293. format(
  1294. "// nested types ----------------------------------------------------\n"
  1295. "\n");
  1296. // Import all nested message classes into this class's scope with typedefs.
  1297. for (int i = 0; i < descriptor_->nested_type_count(); i++) {
  1298. const Descriptor* nested_type = descriptor_->nested_type(i);
  1299. if (!IsMapEntryMessage(nested_type)) {
  1300. format.Set("nested_full_name", ClassName(nested_type, false));
  1301. format.Set("nested_name", ResolveKeyword(nested_type->name()));
  1302. format("typedef ${1$$nested_full_name$$}$ ${1$$nested_name$$}$;\n",
  1303. nested_type);
  1304. }
  1305. }
  1306. if (descriptor_->nested_type_count() > 0) {
  1307. format("\n");
  1308. }
  1309. // Import all nested enums and their values into this class's scope with
  1310. // typedefs and constants.
  1311. for (int i = 0; i < descriptor_->enum_type_count(); i++) {
  1312. enum_generators_[i]->GenerateSymbolImports(printer);
  1313. format("\n");
  1314. }
  1315. format(
  1316. "// accessors -------------------------------------------------------\n"
  1317. "\n");
  1318. // Generate accessor methods for all fields.
  1319. GenerateFieldAccessorDeclarations(printer);
  1320. // Declare extension identifiers.
  1321. for (int i = 0; i < descriptor_->extension_count(); i++) {
  1322. extension_generators_[i]->GenerateDeclaration(printer);
  1323. }
  1324. format("// @@protoc_insertion_point(class_scope:$full_name$)\n");
  1325. // Generate private members.
  1326. format.Outdent();
  1327. format(" private:\n");
  1328. format.Indent();
  1329. // TODO(seongkim): Remove hack to track field access and remove this class.
  1330. format("class _Internal;\n");
  1331. for (auto field : FieldRange(descriptor_)) {
  1332. // set_has_***() generated in all oneofs.
  1333. if (!field->is_repeated() && !field->options().weak() &&
  1334. field->real_containing_oneof()) {
  1335. format("void set_has_$1$();\n", FieldName(field));
  1336. }
  1337. }
  1338. format("\n");
  1339. // Generate oneof function declarations
  1340. for (auto oneof : OneOfRange(descriptor_)) {
  1341. format(
  1342. "inline bool has_$1$() const;\n"
  1343. "inline void clear_has_$1$();\n\n",
  1344. oneof->name());
  1345. }
  1346. if (HasGeneratedMethods(descriptor_->file(), options_) &&
  1347. !descriptor_->options().message_set_wire_format() &&
  1348. num_required_fields_ > 1) {
  1349. format(
  1350. "// helper for ByteSizeLong()\n"
  1351. "size_t RequiredFieldsByteSizeFallback() const;\n\n");
  1352. }
  1353. // Prepare decls for _cached_size_ and _has_bits_. Their position in the
  1354. // output will be determined later.
  1355. bool need_to_emit_cached_size = true;
  1356. const std::string cached_size_decl =
  1357. "mutable ::$proto_ns$::internal::CachedSize _cached_size_;\n";
  1358. const size_t sizeof_has_bits = HasBitsSize();
  1359. const std::string has_bits_decl =
  1360. sizeof_has_bits == 0
  1361. ? ""
  1362. : StrCat("::$proto_ns$::internal::HasBits<",
  1363. sizeof_has_bits / 4, "> _has_bits_;\n");
  1364. // To minimize padding, data members are divided into three sections:
  1365. // (1) members assumed to align to 8 bytes
  1366. // (2) members corresponding to message fields, re-ordered to optimize
  1367. // alignment.
  1368. // (3) members assumed to align to 4 bytes.
  1369. // Members assumed to align to 8 bytes:
  1370. if (descriptor_->extension_range_count() > 0) {
  1371. format(
  1372. "::$proto_ns$::internal::ExtensionSet _extensions_;\n"
  1373. "\n");
  1374. }
  1375. if (SupportsArenas(descriptor_)) {
  1376. format(
  1377. "template <typename T> friend class "
  1378. "::$proto_ns$::Arena::InternalHelper;\n"
  1379. "typedef void InternalArenaConstructable_;\n"
  1380. "typedef void DestructorSkippable_;\n");
  1381. }
  1382. if (!has_bit_indices_.empty()) {
  1383. // _has_bits_ is frequently accessed, so to reduce code size and improve
  1384. // speed, it should be close to the start of the object. Placing
  1385. // _cached_size_ together with _has_bits_ improves cache locality despite
  1386. // potential alignment padding.
  1387. format(has_bits_decl.c_str());
  1388. format(cached_size_decl.c_str());
  1389. need_to_emit_cached_size = false;
  1390. }
  1391. // Field members:
  1392. // Emit some private and static members
  1393. for (auto field : optimized_order_) {
  1394. const FieldGenerator& generator = field_generators_.get(field);
  1395. generator.GenerateStaticMembers(printer);
  1396. generator.GeneratePrivateMembers(printer);
  1397. }
  1398. // For each oneof generate a union
  1399. for (auto oneof : OneOfRange(descriptor_)) {
  1400. std::string camel_oneof_name = UnderscoresToCamelCase(oneof->name(), true);
  1401. format(
  1402. "union $1$Union {\n"
  1403. // explicit empty constructor is needed when union contains
  1404. // ArenaStringPtr members for string fields.
  1405. " $1$Union() {}\n",
  1406. camel_oneof_name);
  1407. format.Indent();
  1408. for (auto field : FieldRange(oneof)) {
  1409. if (IsFieldUsed(field, options_)) {
  1410. field_generators_.get(field).GeneratePrivateMembers(printer);
  1411. }
  1412. }
  1413. format.Outdent();
  1414. format("} $1$_;\n", oneof->name());
  1415. for (auto field : FieldRange(oneof)) {
  1416. if (IsFieldUsed(field, options_)) {
  1417. field_generators_.get(field).GenerateStaticMembers(printer);
  1418. }
  1419. }
  1420. }
  1421. // Members assumed to align to 4 bytes:
  1422. if (need_to_emit_cached_size) {
  1423. format(cached_size_decl.c_str());
  1424. need_to_emit_cached_size = false;
  1425. }
  1426. // Generate _oneof_case_.
  1427. if (descriptor_->real_oneof_decl_count() > 0) {
  1428. format(
  1429. "$uint32$ _oneof_case_[$1$];\n"
  1430. "\n",
  1431. descriptor_->real_oneof_decl_count());
  1432. }
  1433. if (num_weak_fields_) {
  1434. format("::$proto_ns$::internal::WeakFieldMap _weak_field_map_;\n");
  1435. }
  1436. // Generate _any_metadata_ for the Any type.
  1437. if (IsAnyMessage(descriptor_, options_)) {
  1438. format("::$proto_ns$::internal::AnyMetadata _any_metadata_;\n");
  1439. }
  1440. // The TableStruct struct needs access to the private parts, in order to
  1441. // construct the offsets of all members.
  1442. format("friend struct ::$tablename$;\n");
  1443. format.Outdent();
  1444. format("};");
  1445. GOOGLE_DCHECK(!need_to_emit_cached_size);
  1446. } // NOLINT(readability/fn_size)
  1447. void MessageGenerator::GenerateInlineMethods(io::Printer* printer) {
  1448. if (IsMapEntryMessage(descriptor_)) return;
  1449. GenerateFieldAccessorDefinitions(printer);
  1450. // Generate oneof_case() functions.
  1451. for (auto oneof : OneOfRange(descriptor_)) {
  1452. Formatter format(printer, variables_);
  1453. format.Set("camel_oneof_name", UnderscoresToCamelCase(oneof->name(), true));
  1454. format.Set("oneof_name", oneof->name());
  1455. format.Set("oneof_index", oneof->index());
  1456. format(
  1457. "inline $classname$::$camel_oneof_name$Case $classname$::"
  1458. "${1$$oneof_name$_case$}$() const {\n"
  1459. " return $classname$::$camel_oneof_name$Case("
  1460. "_oneof_case_[$oneof_index$]);\n"
  1461. "}\n",
  1462. oneof);
  1463. }
  1464. }
  1465. void MessageGenerator::GenerateExtraDefaultFields(io::Printer* printer) {
  1466. // Generate oneof default instance and weak field instances for reflection
  1467. // usage.
  1468. Formatter format(printer, variables_);
  1469. for (auto oneof : OneOfRange(descriptor_)) {
  1470. for (auto field : FieldRange(oneof)) {
  1471. if (!IsFieldUsed(field, options_)) {
  1472. continue;
  1473. }
  1474. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
  1475. (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
  1476. EffectiveStringCType(field, options_) != FieldOptions::STRING)) {
  1477. format("const ");
  1478. }
  1479. field_generators_.get(field).GeneratePrivateMembers(printer);
  1480. }
  1481. }
  1482. for (auto field : FieldRange(descriptor_)) {
  1483. if (field->options().weak() && IsFieldUsed(field, options_)) {
  1484. format(" const ::$proto_ns$::Message* $1$_;\n", FieldName(field));
  1485. }
  1486. }
  1487. }
  1488. bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset,
  1489. size_t aux_offset) {
  1490. Formatter format(printer, variables_);
  1491. if (!table_driven_) {
  1492. format("{ nullptr, nullptr, 0, -1, -1, -1, -1, nullptr, false },\n");
  1493. return false;
  1494. }
  1495. int max_field_number = 0;
  1496. for (auto field : FieldRange(descriptor_)) {
  1497. if (max_field_number < field->number()) {
  1498. max_field_number = field->number();
  1499. }
  1500. }
  1501. format("{\n");
  1502. format.Indent();
  1503. format(
  1504. "$tablename$::entries + $1$,\n"
  1505. "$tablename$::aux + $2$,\n"
  1506. "$3$,\n",
  1507. offset, aux_offset, max_field_number);
  1508. if (has_bit_indices_.empty()) {
  1509. // If no fields have hasbits, then _has_bits_ does not exist.
  1510. format("-1,\n");
  1511. } else {
  1512. format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
  1513. }
  1514. if (descriptor_->real_oneof_decl_count() > 0) {
  1515. format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n");
  1516. } else {
  1517. format("-1, // no _oneof_case_\n");
  1518. }
  1519. if (descriptor_->extension_range_count() > 0) {
  1520. format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
  1521. } else {
  1522. format("-1, // no _extensions_\n");
  1523. }
  1524. // TODO(ckennelly): Consolidate this with the calculation for
  1525. // AuxillaryParseTableField.
  1526. format(
  1527. "PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n"
  1528. "&$package_ns$::_$classname$_default_instance_,\n");
  1529. if (UseUnknownFieldSet(descriptor_->file(), options_)) {
  1530. format("true,\n");
  1531. } else {
  1532. format("false,\n");
  1533. }
  1534. format.Outdent();
  1535. format("},\n");
  1536. return true;
  1537. }
  1538. void MessageGenerator::GenerateSchema(io::Printer* printer, int offset,
  1539. int has_offset) {
  1540. Formatter format(printer, variables_);
  1541. has_offset = !has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)
  1542. ? offset + has_offset
  1543. : -1;
  1544. format("{ $1$, $2$, sizeof($classtype$)},\n", offset, has_offset);
  1545. }
  1546. namespace {
  1547. // We need to calculate for each field what function the table driven code
  1548. // should use to serialize it. This returns the index in a lookup table.
  1549. uint32 CalcFieldNum(const FieldGenerator& generator,
  1550. const FieldDescriptor* field, const Options& options) {
  1551. bool is_a_map = IsMapEntryMessage(field->containing_type());
  1552. int type = field->type();
  1553. if (type == FieldDescriptor::TYPE_STRING ||
  1554. type == FieldDescriptor::TYPE_BYTES) {
  1555. if (generator.IsInlined()) {
  1556. type = internal::FieldMetadata::kInlinedType;
  1557. }
  1558. // string field
  1559. if (IsCord(field, options)) {
  1560. type = internal::FieldMetadata::kCordType;
  1561. } else if (IsStringPiece(field, options)) {
  1562. type = internal::FieldMetadata::kStringPieceType;
  1563. }
  1564. }
  1565. if (field->real_containing_oneof()) {
  1566. return internal::FieldMetadata::CalculateType(
  1567. type, internal::FieldMetadata::kOneOf);
  1568. } else if (field->is_packed()) {
  1569. return internal::FieldMetadata::CalculateType(
  1570. type, internal::FieldMetadata::kPacked);
  1571. } else if (field->is_repeated()) {
  1572. return internal::FieldMetadata::CalculateType(
  1573. type, internal::FieldMetadata::kRepeated);
  1574. } else if (HasHasbit(field) || field->real_containing_oneof() || is_a_map) {
  1575. return internal::FieldMetadata::CalculateType(
  1576. type, internal::FieldMetadata::kPresence);
  1577. } else {
  1578. return internal::FieldMetadata::CalculateType(
  1579. type, internal::FieldMetadata::kNoPresence);
  1580. }
  1581. }
  1582. int FindMessageIndexInFile(const Descriptor* descriptor) {
  1583. std::vector<const Descriptor*> flatten =
  1584. FlattenMessagesInFile(descriptor->file());
  1585. return std::find(flatten.begin(), flatten.end(), descriptor) -
  1586. flatten.begin();
  1587. }
  1588. } // namespace
  1589. int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
  1590. Formatter format(printer, variables_);
  1591. if (!options_.table_driven_serialization) {
  1592. return 0;
  1593. }
  1594. std::vector<const FieldDescriptor*> sorted = SortFieldsByNumber(descriptor_);
  1595. if (IsMapEntryMessage(descriptor_)) {
  1596. for (int i = 0; i < 2; i++) {
  1597. const FieldDescriptor* field = sorted[i];
  1598. const FieldGenerator& generator = field_generators_.get(field);
  1599. uint32 tag = internal::WireFormatLite::MakeTag(
  1600. field->number(), WireFormat::WireTypeForFieldType(field->type()));
  1601. std::map<std::string, std::string> vars;
  1602. vars["classtype"] = QualifiedClassName(descriptor_, options_);
  1603. vars["field_name"] = FieldName(field);
  1604. vars["tag"] = StrCat(tag);
  1605. vars["hasbit"] = StrCat(i);
  1606. vars["type"] = StrCat(CalcFieldNum(generator, field, options_));
  1607. vars["ptr"] = "nullptr";
  1608. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  1609. GOOGLE_CHECK(!IsMapEntryMessage(field->message_type()));
  1610. vars["ptr"] =
  1611. "::" + UniqueName("TableStruct", field->message_type(), options_) +
  1612. "::serialization_table + " +
  1613. StrCat(FindMessageIndexInFile(field->message_type()));
  1614. }
  1615. Formatter::SaveState saver(&format);
  1616. format.AddMap(vars);
  1617. format(
  1618. "{PROTOBUF_FIELD_OFFSET("
  1619. "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
  1620. "SuperType>, $field_name$_), $tag$,"
  1621. "PROTOBUF_FIELD_OFFSET("
  1622. "::$proto_ns$::internal::MapEntryHelper<$classtype$::"
  1623. "SuperType>, _has_bits_) * 8 + $hasbit$, $type$, "
  1624. "$ptr$},\n");
  1625. }
  1626. return 2;
  1627. }
  1628. format(
  1629. "{PROTOBUF_FIELD_OFFSET($classtype$, _cached_size_),"
  1630. " 0, 0, 0, nullptr},\n");
  1631. std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
  1632. sorted_extensions.reserve(descriptor_->extension_range_count());
  1633. for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
  1634. sorted_extensions.push_back(descriptor_->extension_range(i));
  1635. }
  1636. std::sort(sorted_extensions.begin(), sorted_extensions.end(),
  1637. ExtensionRangeSorter());
  1638. for (int i = 0, extension_idx = 0; /* no range */; i++) {
  1639. for (; extension_idx < sorted_extensions.size() &&
  1640. (i == sorted.size() ||
  1641. sorted_extensions[extension_idx]->start < sorted[i]->number());
  1642. extension_idx++) {
  1643. const Descriptor::ExtensionRange* range =
  1644. sorted_extensions[extension_idx];
  1645. format(
  1646. "{PROTOBUF_FIELD_OFFSET($classtype$, _extensions_), "
  1647. "$1$, $2$, ::$proto_ns$::internal::FieldMetadata::kSpecial, "
  1648. "reinterpret_cast<const "
  1649. "void*>(::$proto_ns$::internal::ExtensionSerializer)},\n",
  1650. range->start, range->end);
  1651. }
  1652. if (i == sorted.size()) break;
  1653. const FieldDescriptor* field = sorted[i];
  1654. uint32 tag = internal::WireFormatLite::MakeTag(
  1655. field->number(), WireFormat::WireTypeForFieldType(field->type()));
  1656. if (field->is_packed()) {
  1657. tag = internal::WireFormatLite::MakeTag(
  1658. field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
  1659. }
  1660. std::string classfieldname = FieldName(field);
  1661. if (field->real_containing_oneof()) {
  1662. classfieldname = field->containing_oneof()->name();
  1663. }
  1664. format.Set("field_name", classfieldname);
  1665. std::string ptr = "nullptr";
  1666. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  1667. if (IsMapEntryMessage(field->message_type())) {
  1668. format(
  1669. "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$, $2$, "
  1670. "::$proto_ns$::internal::FieldMetadata::kSpecial, "
  1671. "reinterpret_cast<const void*>(static_cast< "
  1672. "::$proto_ns$::internal::SpecialSerializer>("
  1673. "::$proto_ns$::internal::MapFieldSerializer< "
  1674. "::$proto_ns$::internal::MapEntryToMapField<"
  1675. "$3$>::MapFieldType, "
  1676. "$tablename$::serialization_table>))},\n",
  1677. tag, FindMessageIndexInFile(field->message_type()),
  1678. QualifiedClassName(field->message_type(), options_));
  1679. continue;
  1680. } else if (!field->message_type()->options().message_set_wire_format()) {
  1681. // message_set doesn't have the usual table and we need to
  1682. // dispatch to generated serializer, hence ptr stays zero.
  1683. ptr =
  1684. "::" + UniqueName("TableStruct", field->message_type(), options_) +
  1685. "::serialization_table + " +
  1686. StrCat(FindMessageIndexInFile(field->message_type()));
  1687. }
  1688. }
  1689. const FieldGenerator& generator = field_generators_.get(field);
  1690. int type = CalcFieldNum(generator, field, options_);
  1691. if (IsLazy(field, options_)) {
  1692. type = internal::FieldMetadata::kSpecial;
  1693. ptr = "reinterpret_cast<const void*>(::" + variables_["proto_ns"] +
  1694. "::internal::LazyFieldSerializer";
  1695. if (field->real_containing_oneof()) {
  1696. ptr += "OneOf";
  1697. } else if (!HasHasbit(field)) {
  1698. ptr += "NoPresence";
  1699. }
  1700. ptr += ")";
  1701. }
  1702. if (field->options().weak()) {
  1703. // TODO(gerbens) merge weak fields into ranges
  1704. format(
  1705. "{PROTOBUF_FIELD_OFFSET("
  1706. "$classtype$, _weak_field_map_), $1$, $1$, "
  1707. "::$proto_ns$::internal::FieldMetadata::kSpecial, "
  1708. "reinterpret_cast<const "
  1709. "void*>(::$proto_ns$::internal::WeakFieldSerializer)},\n",
  1710. tag);
  1711. } else if (field->real_containing_oneof()) {
  1712. format.Set("oneofoffset",
  1713. sizeof(uint32) * field->containing_oneof()->index());
  1714. format(
  1715. "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), $1$,"
  1716. " PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_) + "
  1717. "$oneofoffset$, $2$, $3$},\n",
  1718. tag, type, ptr);
  1719. } else if (HasHasbit(field)) {
  1720. format.Set("hasbitsoffset", has_bit_indices_[field->index()]);
  1721. format(
  1722. "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
  1723. "$1$, PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_) * 8 + "
  1724. "$hasbitsoffset$, $2$, $3$},\n",
  1725. tag, type, ptr);
  1726. } else {
  1727. format(
  1728. "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), "
  1729. "$1$, ~0u, $2$, $3$},\n",
  1730. tag, type, ptr);
  1731. }
  1732. }
  1733. int num_field_metadata = 1 + sorted.size() + sorted_extensions.size();
  1734. num_field_metadata++;
  1735. std::string serializer = UseUnknownFieldSet(descriptor_->file(), options_)
  1736. ? "UnknownFieldSetSerializer"
  1737. : "UnknownFieldSerializerLite";
  1738. format(
  1739. "{PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_), 0, ~0u, "
  1740. "::$proto_ns$::internal::FieldMetadata::kSpecial, reinterpret_cast<const "
  1741. "void*>(::$proto_ns$::internal::$1$)},\n",
  1742. serializer);
  1743. return num_field_metadata;
  1744. }
  1745. void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) {
  1746. // Construct the default instances for all fields that need one.
  1747. for (auto field : FieldRange(descriptor_)) {
  1748. field_generators_.get(field).GenerateDefaultInstanceAllocator(printer);
  1749. }
  1750. }
  1751. void MessageGenerator::GenerateDefaultInstanceInitializer(
  1752. io::Printer* printer) {
  1753. Formatter format(printer, variables_);
  1754. // The default instance needs all of its embedded message pointers
  1755. // cross-linked to other default instances. We can't do this initialization
  1756. // in the constructor because some other default instances may not have been
  1757. // constructed yet at that time.
  1758. // TODO(kenton): Maybe all message fields (even for non-default messages)
  1759. // should be initialized to point at default instances rather than NULL?
  1760. for (auto field : FieldRange(descriptor_)) {
  1761. if (!IsFieldUsed(field, options_)) {
  1762. continue;
  1763. }
  1764. Formatter::SaveState saver(&format);
  1765. if (!field->is_repeated() && !IsLazy(field, options_) &&
  1766. field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  1767. (!field->real_containing_oneof() ||
  1768. HasDescriptorMethods(descriptor_->file(), options_))) {
  1769. std::string name;
  1770. if (field->real_containing_oneof() || field->options().weak()) {
  1771. name = "_" + classname_ + "_default_instance_.";
  1772. } else {
  1773. name =
  1774. "_" + classname_ + "_default_instance_._instance.get_mutable()->";
  1775. }
  1776. name += FieldName(field);
  1777. format.Set("name", name);
  1778. if (IsWeak(field, options_)) {
  1779. format(
  1780. "$package_ns$::$name$_ = reinterpret_cast<const "
  1781. "::$proto_ns$::Message*>(&$1$);\n"
  1782. "if ($package_ns$::$name$_ == nullptr) {\n"
  1783. " $package_ns$::$name$_ = "
  1784. "::$proto_ns$::Empty::internal_default_instance();\n"
  1785. "}\n",
  1786. QualifiedDefaultInstanceName(field->message_type(),
  1787. options_)); // 1
  1788. continue;
  1789. }
  1790. if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
  1791. format(
  1792. "$package_ns$::$name$_ = reinterpret_cast<$1$*>(\n"
  1793. " $2$);\n",
  1794. FieldMessageTypeName(field, options_),
  1795. QualifiedDefaultInstancePtr(field->message_type(), options_));
  1796. } else {
  1797. format(
  1798. "$package_ns$::$name$_ = const_cast< $1$*>(\n"
  1799. " $1$::internal_default_instance());\n",
  1800. FieldMessageTypeName(field, options_));
  1801. }
  1802. } else if (field->real_containing_oneof() &&
  1803. HasDescriptorMethods(descriptor_->file(), options_)) {
  1804. field_generators_.get(field).GenerateConstructorCode(printer);
  1805. }
  1806. }
  1807. }
  1808. void MessageGenerator::GenerateClassMethods(io::Printer* printer) {
  1809. Formatter format(printer, variables_);
  1810. if (IsMapEntryMessage(descriptor_)) {
  1811. format(
  1812. "$classname$::$classname$() {}\n"
  1813. "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
  1814. " : SuperType(arena) {}\n"
  1815. "void $classname$::MergeFrom(const $classname$& other) {\n"
  1816. " MergeFromInternal(other);\n"
  1817. "}\n");
  1818. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  1819. format(
  1820. "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
  1821. " return GetMetadataStatic();\n"
  1822. "}\n");
  1823. format(
  1824. "void $classname$::MergeFrom(\n"
  1825. " const ::$proto_ns$::Message& other) {\n"
  1826. " ::$proto_ns$::Message::MergeFrom(other);\n"
  1827. "}\n"
  1828. "\n");
  1829. }
  1830. return;
  1831. }
  1832. // TODO(gerbens) Remove this function. With a little bit of cleanup and
  1833. // refactoring this is superfluous.
  1834. format("void $classname$::InitAsDefaultInstance() {\n");
  1835. format.Indent();
  1836. GenerateDefaultInstanceInitializer(printer);
  1837. format.Outdent();
  1838. format("}\n");
  1839. if (IsAnyMessage(descriptor_, options_)) {
  1840. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  1841. format(
  1842. "bool $classname$::GetAnyFieldDescriptors(\n"
  1843. " const ::$proto_ns$::Message& message,\n"
  1844. " const ::$proto_ns$::FieldDescriptor** type_url_field,\n"
  1845. " const ::$proto_ns$::FieldDescriptor** value_field) {\n"
  1846. " return ::$proto_ns$::internal::GetAnyFieldDescriptors(\n"
  1847. " message, type_url_field, value_field);\n"
  1848. "}\n");
  1849. }
  1850. format(
  1851. "bool $classname$::ParseAnyTypeUrl(const string& type_url,\n"
  1852. " std::string* full_type_name) {\n"
  1853. " return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n"
  1854. " full_type_name);\n"
  1855. "}\n"
  1856. "\n");
  1857. }
  1858. format(
  1859. "class $classname$::_Internal {\n"
  1860. " public:\n");
  1861. format.Indent();
  1862. if (!has_bit_indices_.empty()) {
  1863. format(
  1864. "using HasBits = decltype(std::declval<$classname$>()._has_bits_);\n");
  1865. }
  1866. for (auto field : FieldRange(descriptor_)) {
  1867. field_generators_.get(field).GenerateInternalAccessorDeclarations(printer);
  1868. if (!IsFieldUsed(field, options_)) {
  1869. continue;
  1870. }
  1871. if (HasHasbit(field)) {
  1872. int has_bit_index = HasBitIndex(field);
  1873. GOOGLE_CHECK_NE(has_bit_index, kNoHasbit) << field->full_name();
  1874. format(
  1875. "static void set_has_$1$(HasBits* has_bits) {\n"
  1876. " (*has_bits)[$2$] |= $3$u;\n"
  1877. "}\n",
  1878. FieldName(field), has_bit_index / 32, (1u << (has_bit_index % 32)));
  1879. }
  1880. }
  1881. if (num_required_fields_ > 0) {
  1882. const std::vector<uint32> masks_for_has_bits = RequiredFieldsBitMask();
  1883. format(
  1884. "static bool MissingRequiredFields(const HasBits& has_bits) "
  1885. "{\n"
  1886. " return $1$;\n"
  1887. "}\n",
  1888. ConditionalToCheckBitmasks(masks_for_has_bits, false, "has_bits"));
  1889. }
  1890. format.Outdent();
  1891. format("};\n\n");
  1892. for (auto field : FieldRange(descriptor_)) {
  1893. if (IsFieldUsed(field, options_)) {
  1894. field_generators_.get(field).GenerateInternalAccessorDefinitions(printer);
  1895. }
  1896. }
  1897. // Generate non-inline field definitions.
  1898. for (auto field : FieldRange(descriptor_)) {
  1899. if (!IsFieldUsed(field, options_)) {
  1900. continue;
  1901. }
  1902. field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer);
  1903. if (IsCrossFileMaybeMap(field)) {
  1904. Formatter::SaveState saver(&format);
  1905. std::map<std::string, std::string> vars;
  1906. SetCommonFieldVariables(field, &vars, options_);
  1907. if (field->real_containing_oneof()) {
  1908. SetCommonOneofFieldVariables(field, &vars);
  1909. }
  1910. format.AddMap(vars);
  1911. GenerateFieldClear(field, false, format);
  1912. }
  1913. }
  1914. GenerateStructors(printer);
  1915. format("\n");
  1916. if (descriptor_->real_oneof_decl_count() > 0) {
  1917. GenerateOneofClear(printer);
  1918. format("\n");
  1919. }
  1920. if (HasGeneratedMethods(descriptor_->file(), options_)) {
  1921. GenerateClear(printer);
  1922. format("\n");
  1923. GenerateMergeFromCodedStream(printer);
  1924. format("\n");
  1925. GenerateSerializeWithCachedSizesToArray(printer);
  1926. format("\n");
  1927. GenerateByteSize(printer);
  1928. format("\n");
  1929. GenerateMergeFrom(printer);
  1930. format("\n");
  1931. GenerateClassSpecificMergeFrom(printer);
  1932. format("\n");
  1933. GenerateCopyFrom(printer);
  1934. format("\n");
  1935. GenerateIsInitialized(printer);
  1936. format("\n");
  1937. }
  1938. GenerateSwap(printer);
  1939. format("\n");
  1940. if (options_.table_driven_serialization) {
  1941. format(
  1942. "const void* $classname$::InternalGetTable() const {\n"
  1943. " return ::$tablename$::serialization_table + $1$;\n"
  1944. "}\n"
  1945. "\n",
  1946. index_in_file_messages_);
  1947. }
  1948. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  1949. format(
  1950. "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n"
  1951. " return GetMetadataStatic();\n"
  1952. "}\n"
  1953. "\n");
  1954. } else {
  1955. format(
  1956. "std::string $classname$::GetTypeName() const {\n"
  1957. " return \"$full_name$\";\n"
  1958. "}\n"
  1959. "\n");
  1960. }
  1961. }
  1962. size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) {
  1963. Formatter format(printer, variables_);
  1964. if (!table_driven_) {
  1965. return 0;
  1966. }
  1967. // Field "0" is special: We use it in our switch statement of processing
  1968. // types to handle the successful end tag case.
  1969. format("{0, 0, 0, ::$proto_ns$::internal::kInvalidMask, 0, 0},\n");
  1970. int last_field_number = 1;
  1971. std::vector<const FieldDescriptor*> ordered_fields =
  1972. SortFieldsByNumber(descriptor_);
  1973. for (auto field : ordered_fields) {
  1974. Formatter::SaveState saver(&format);
  1975. GOOGLE_CHECK_GE(field->number(), last_field_number);
  1976. for (; last_field_number < field->number(); last_field_number++) {
  1977. format(
  1978. "{ 0, 0, ::$proto_ns$::internal::kInvalidMask,\n"
  1979. " ::$proto_ns$::internal::kInvalidMask, 0, 0 },\n");
  1980. }
  1981. last_field_number++;
  1982. unsigned char normal_wiretype, packed_wiretype, processing_type;
  1983. normal_wiretype = WireFormat::WireTypeForFieldType(field->type());
  1984. if (field->is_packable()) {
  1985. packed_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
  1986. } else {
  1987. packed_wiretype = internal::kNotPackedMask;
  1988. }
  1989. processing_type = static_cast<unsigned>(field->type());
  1990. const FieldGenerator& generator = field_generators_.get(field);
  1991. if (field->type() == FieldDescriptor::TYPE_STRING) {
  1992. switch (EffectiveStringCType(field, options_)) {
  1993. case FieldOptions::STRING:
  1994. if (generator.IsInlined()) {
  1995. processing_type = internal::TYPE_STRING_INLINED;
  1996. break;
  1997. }
  1998. break;
  1999. case FieldOptions::CORD:
  2000. processing_type = internal::TYPE_STRING_CORD;
  2001. break;
  2002. case FieldOptions::STRING_PIECE:
  2003. processing_type = internal::TYPE_STRING_STRING_PIECE;
  2004. break;
  2005. }
  2006. } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
  2007. switch (EffectiveStringCType(field, options_)) {
  2008. case FieldOptions::STRING:
  2009. if (generator.IsInlined()) {
  2010. processing_type = internal::TYPE_BYTES_INLINED;
  2011. break;
  2012. }
  2013. break;
  2014. case FieldOptions::CORD:
  2015. processing_type = internal::TYPE_BYTES_CORD;
  2016. break;
  2017. case FieldOptions::STRING_PIECE:
  2018. processing_type = internal::TYPE_BYTES_STRING_PIECE;
  2019. break;
  2020. }
  2021. }
  2022. processing_type |= static_cast<unsigned>(
  2023. field->is_repeated() ? internal::kRepeatedMask : 0);
  2024. processing_type |= static_cast<unsigned>(
  2025. field->real_containing_oneof() ? internal::kOneofMask : 0);
  2026. if (field->is_map()) {
  2027. processing_type = internal::TYPE_MAP;
  2028. }
  2029. const unsigned char tag_size =
  2030. WireFormat::TagSize(field->number(), field->type());
  2031. std::map<std::string, std::string> vars;
  2032. if (field->real_containing_oneof()) {
  2033. vars["name"] = field->containing_oneof()->name();
  2034. vars["presence"] = StrCat(field->containing_oneof()->index());
  2035. } else {
  2036. vars["name"] = FieldName(field);
  2037. vars["presence"] = StrCat(has_bit_indices_[field->index()]);
  2038. }
  2039. vars["nwtype"] = StrCat(normal_wiretype);
  2040. vars["pwtype"] = StrCat(packed_wiretype);
  2041. vars["ptype"] = StrCat(processing_type);
  2042. vars["tag_size"] = StrCat(tag_size);
  2043. format.AddMap(vars);
  2044. format(
  2045. "{\n"
  2046. " PROTOBUF_FIELD_OFFSET($classtype$, $name$_),\n"
  2047. " static_cast<$uint32$>($presence$),\n"
  2048. " $nwtype$, $pwtype$, $ptype$, $tag_size$\n"
  2049. "},\n");
  2050. }
  2051. return last_field_number;
  2052. }
  2053. size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) {
  2054. Formatter format(printer, variables_);
  2055. if (!table_driven_) {
  2056. return 0;
  2057. }
  2058. std::vector<const FieldDescriptor*> ordered_fields =
  2059. SortFieldsByNumber(descriptor_);
  2060. format("::$proto_ns$::internal::AuxillaryParseTableField(),\n");
  2061. int last_field_number = 1;
  2062. for (auto field : ordered_fields) {
  2063. Formatter::SaveState saver(&format);
  2064. GOOGLE_CHECK_GE(field->number(), last_field_number);
  2065. for (; last_field_number < field->number(); last_field_number++) {
  2066. format("::$proto_ns$::internal::AuxillaryParseTableField(),\n");
  2067. }
  2068. std::map<std::string, std::string> vars;
  2069. SetCommonFieldVariables(field, &vars, options_);
  2070. format.AddMap(vars);
  2071. switch (field->cpp_type()) {
  2072. case FieldDescriptor::CPPTYPE_ENUM:
  2073. if (HasPreservingUnknownEnumSemantics(field)) {
  2074. format(
  2075. "{::$proto_ns$::internal::AuxillaryParseTableField::enum_aux{"
  2076. "nullptr}},\n");
  2077. } else {
  2078. format(
  2079. "{::$proto_ns$::internal::AuxillaryParseTableField::enum_aux{"
  2080. "$1$_IsValid}},\n",
  2081. ClassName(field->enum_type(), true));
  2082. }
  2083. last_field_number++;
  2084. break;
  2085. case FieldDescriptor::CPPTYPE_MESSAGE: {
  2086. if (field->is_map()) {
  2087. format(
  2088. "{::$proto_ns$::internal::AuxillaryParseTableField::map_"
  2089. "aux{&::$proto_ns$::internal::ParseMap<$1$>}},\n",
  2090. QualifiedClassName(field->message_type(), options_));
  2091. last_field_number++;
  2092. break;
  2093. }
  2094. format.Set("field_classname", ClassName(field->message_type(), false));
  2095. format.Set("default_instance", QualifiedDefaultInstanceName(
  2096. field->message_type(), options_));
  2097. format(
  2098. "{::$proto_ns$::internal::AuxillaryParseTableField::message_aux{\n"
  2099. " &$default_instance$}},\n");
  2100. last_field_number++;
  2101. break;
  2102. }
  2103. case FieldDescriptor::CPPTYPE_STRING: {
  2104. std::string default_val;
  2105. switch (EffectiveStringCType(field, options_)) {
  2106. case FieldOptions::STRING:
  2107. default_val = field->default_value_string().empty()
  2108. ? "&::" + variables_["proto_ns"] +
  2109. "::internal::fixed_address_empty_string"
  2110. : "&" +
  2111. QualifiedClassName(descriptor_, options_) +
  2112. "::" + MakeDefaultName(field);
  2113. break;
  2114. case FieldOptions::CORD:
  2115. case FieldOptions::STRING_PIECE:
  2116. default_val =
  2117. "\"" + CEscape(field->default_value_string()) + "\"";
  2118. break;
  2119. }
  2120. format(
  2121. "{::$proto_ns$::internal::AuxillaryParseTableField::string_aux{\n"
  2122. " $1$,\n"
  2123. " \"$2$\"\n"
  2124. "}},\n",
  2125. default_val, field->full_name());
  2126. last_field_number++;
  2127. break;
  2128. }
  2129. default:
  2130. break;
  2131. }
  2132. }
  2133. return last_field_number;
  2134. }
  2135. std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
  2136. io::Printer* printer) {
  2137. Formatter format(printer, variables_);
  2138. if (!has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)) {
  2139. format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n");
  2140. } else {
  2141. format("~0u, // no _has_bits_\n");
  2142. }
  2143. format("PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n");
  2144. if (descriptor_->extension_range_count() > 0) {
  2145. format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n");
  2146. } else {
  2147. format("~0u, // no _extensions_\n");
  2148. }
  2149. if (descriptor_->real_oneof_decl_count() > 0) {
  2150. format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n");
  2151. } else {
  2152. format("~0u, // no _oneof_case_\n");
  2153. }
  2154. if (num_weak_fields_ > 0) {
  2155. format("PROTOBUF_FIELD_OFFSET($classtype$, _weak_field_map_),\n");
  2156. } else {
  2157. format("~0u, // no _weak_field_map_\n");
  2158. }
  2159. const int kNumGenericOffsets = 5; // the number of fixed offsets above
  2160. const size_t offsets = kNumGenericOffsets + descriptor_->field_count() +
  2161. descriptor_->real_oneof_decl_count();
  2162. size_t entries = offsets;
  2163. for (auto field : FieldRange(descriptor_)) {
  2164. if (!IsFieldUsed(field, options_)) {
  2165. format("~0u, // stripped\n");
  2166. continue;
  2167. }
  2168. if (field->real_containing_oneof() || field->options().weak()) {
  2169. format("offsetof($classtype$DefaultTypeInternal, $1$_)",
  2170. FieldName(field));
  2171. } else {
  2172. format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field));
  2173. }
  2174. uint32 tag = field_generators_.get(field).CalculateFieldTag();
  2175. if (tag != 0) {
  2176. format(" | $1$", tag);
  2177. }
  2178. format(",\n");
  2179. }
  2180. int count = 0;
  2181. for (auto oneof : OneOfRange(descriptor_)) {
  2182. format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_),\n", oneof->name());
  2183. count++;
  2184. }
  2185. GOOGLE_CHECK_EQ(count, descriptor_->real_oneof_decl_count());
  2186. if (IsMapEntryMessage(descriptor_)) {
  2187. entries += 2;
  2188. format(
  2189. "0,\n"
  2190. "1,\n");
  2191. } else if (!has_bit_indices_.empty()) {
  2192. entries += has_bit_indices_.size();
  2193. for (int i = 0; i < has_bit_indices_.size(); i++) {
  2194. const std::string index =
  2195. has_bit_indices_[i] >= 0 ? StrCat(has_bit_indices_[i]) : "~0u";
  2196. format("$1$,\n", index);
  2197. }
  2198. }
  2199. return std::make_pair(entries, offsets);
  2200. }
  2201. void MessageGenerator::GenerateSharedConstructorCode(io::Printer* printer) {
  2202. Formatter format(printer, variables_);
  2203. format("void $classname$::SharedCtor() {\n");
  2204. if (scc_analyzer_->GetSCCAnalysis(scc_analyzer_->GetSCC(descriptor_))
  2205. .constructor_requires_initialization) {
  2206. format(" ::$proto_ns$::internal::InitSCC(&$scc_info$.base);\n");
  2207. }
  2208. format.Indent();
  2209. std::vector<bool> processed(optimized_order_.size(), false);
  2210. GenerateConstructorBody(printer, processed, false);
  2211. for (auto oneof : OneOfRange(descriptor_)) {
  2212. format("clear_has_$1$();\n", oneof->name());
  2213. }
  2214. format.Outdent();
  2215. format("}\n\n");
  2216. }
  2217. void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) {
  2218. Formatter format(printer, variables_);
  2219. format("void $classname$::SharedDtor() {\n");
  2220. format.Indent();
  2221. if (SupportsArenas(descriptor_)) {
  2222. format("$DCHK$(GetArena() == nullptr);\n");
  2223. }
  2224. // Write the destructors for each field except oneof members.
  2225. // optimized_order_ does not contain oneof fields.
  2226. for (auto field : optimized_order_) {
  2227. field_generators_.get(field).GenerateDestructorCode(printer);
  2228. }
  2229. // Generate code to destruct oneofs. Clearing should do the work.
  2230. for (auto oneof : OneOfRange(descriptor_)) {
  2231. format(
  2232. "if (has_$1$()) {\n"
  2233. " clear_$1$();\n"
  2234. "}\n",
  2235. oneof->name());
  2236. }
  2237. if (num_weak_fields_) {
  2238. format("_weak_field_map_.ClearAll();\n");
  2239. }
  2240. format.Outdent();
  2241. format(
  2242. "}\n"
  2243. "\n");
  2244. }
  2245. void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) {
  2246. Formatter format(printer, variables_);
  2247. // Generate the ArenaDtor() method. Track whether any fields actually produced
  2248. // code that needs to be called.
  2249. format("void $classname$::ArenaDtor(void* object) {\n");
  2250. format.Indent();
  2251. // This code is placed inside a static method, rather than an ordinary one,
  2252. // since that simplifies Arena's destructor list (ordinary function pointers
  2253. // rather than member function pointers). _this is the object being
  2254. // destructed.
  2255. format(
  2256. "$classname$* _this = reinterpret_cast< $classname$* >(object);\n"
  2257. // avoid an "unused variable" warning in case no fields have dtor code.
  2258. "(void)_this;\n");
  2259. bool need_registration = false;
  2260. // Process non-oneof fields first.
  2261. for (auto field : optimized_order_) {
  2262. if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
  2263. need_registration = true;
  2264. }
  2265. }
  2266. // Process oneof fields.
  2267. //
  2268. // Note: As of 10/5/2016, GenerateArenaDestructorCode does not emit anything
  2269. // and returns false for oneof fields.
  2270. for (auto oneof : OneOfRange(descriptor_)) {
  2271. for (auto field : FieldRange(oneof)) {
  2272. if (IsFieldUsed(field, options_) &&
  2273. field_generators_.get(field).GenerateArenaDestructorCode(printer)) {
  2274. need_registration = true;
  2275. }
  2276. }
  2277. }
  2278. if (num_weak_fields_) {
  2279. // _this is the object being destructed (we are inside a static method
  2280. // here).
  2281. format("_this->_weak_field_map_.ClearAll();\n");
  2282. need_registration = true;
  2283. }
  2284. format.Outdent();
  2285. format("}\n");
  2286. if (need_registration) {
  2287. format(
  2288. "inline void $classname$::RegisterArenaDtor(::$proto_ns$::Arena* "
  2289. "arena) {\n"
  2290. " if (arena != nullptr) {\n"
  2291. " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n"
  2292. " }\n"
  2293. "}\n");
  2294. } else {
  2295. format(
  2296. "void $classname$::RegisterArenaDtor(::$proto_ns$::Arena*) {\n"
  2297. "}\n");
  2298. }
  2299. }
  2300. void MessageGenerator::GenerateConstructorBody(io::Printer* printer,
  2301. std::vector<bool> processed,
  2302. bool copy_constructor) const {
  2303. Formatter format(printer, variables_);
  2304. const RunMap runs = FindRuns(
  2305. optimized_order_, [copy_constructor, this](const FieldDescriptor* field) {
  2306. return (copy_constructor && IsPOD(field)) ||
  2307. (!copy_constructor &&
  2308. CanBeManipulatedAsRawBytes(field, options_));
  2309. });
  2310. std::string pod_template;
  2311. if (copy_constructor) {
  2312. pod_template =
  2313. "::memcpy(&$first$_, &from.$first$_,\n"
  2314. " static_cast<size_t>(reinterpret_cast<char*>(&$last$_) -\n"
  2315. " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
  2316. } else {
  2317. pod_template =
  2318. "::memset(&$first$_, 0, static_cast<size_t>(\n"
  2319. " reinterpret_cast<char*>(&$last$_) -\n"
  2320. " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
  2321. }
  2322. for (int i = 0; i < optimized_order_.size(); ++i) {
  2323. if (processed[i]) {
  2324. continue;
  2325. }
  2326. const FieldDescriptor* field = optimized_order_[i];
  2327. const auto it = runs.find(field);
  2328. // We only apply the memset technique to runs of more than one field, as
  2329. // assignment is better than memset for generated code clarity.
  2330. if (it != runs.end() && it->second > 1) {
  2331. // Use a memset, then skip run_length fields.
  2332. const size_t run_length = it->second;
  2333. const std::string first_field_name = FieldName(field);
  2334. const std::string last_field_name =
  2335. FieldName(optimized_order_[i + run_length - 1]);
  2336. format.Set("first", first_field_name);
  2337. format.Set("last", last_field_name);
  2338. format(pod_template.c_str());
  2339. i += run_length - 1;
  2340. // ++i at the top of the loop.
  2341. } else {
  2342. if (copy_constructor) {
  2343. field_generators_.get(field).GenerateCopyConstructorCode(printer);
  2344. } else {
  2345. field_generators_.get(field).GenerateConstructorCode(printer);
  2346. }
  2347. }
  2348. }
  2349. }
  2350. void MessageGenerator::GenerateStructors(io::Printer* printer) {
  2351. Formatter format(printer, variables_);
  2352. std::string superclass;
  2353. superclass = SuperClassName(descriptor_, options_);
  2354. std::string initializer_with_arena = superclass + "(arena)";
  2355. if (descriptor_->extension_range_count() > 0) {
  2356. initializer_with_arena += ",\n _extensions_(arena)";
  2357. }
  2358. // Initialize member variables with arena constructor.
  2359. for (auto field : optimized_order_) {
  2360. GOOGLE_DCHECK(IsFieldUsed(field, options_));
  2361. bool has_arena_constructor = field->is_repeated();
  2362. if (!field->real_containing_oneof() &&
  2363. (IsLazy(field, options_) || IsStringPiece(field, options_))) {
  2364. has_arena_constructor = true;
  2365. }
  2366. if (has_arena_constructor) {
  2367. initializer_with_arena +=
  2368. std::string(",\n ") + FieldName(field) + std::string("_(arena)");
  2369. }
  2370. }
  2371. if (IsAnyMessage(descriptor_, options_)) {
  2372. initializer_with_arena += ",\n _any_metadata_(&type_url_, &value_)";
  2373. }
  2374. if (num_weak_fields_ > 0) {
  2375. initializer_with_arena += ", _weak_field_map_(arena)";
  2376. }
  2377. std::string initializer_null = superclass + "()";
  2378. if (IsAnyMessage(descriptor_, options_)) {
  2379. initializer_null += ", _any_metadata_(&type_url_, &value_)";
  2380. }
  2381. if (num_weak_fields_ > 0) {
  2382. initializer_null += ", _weak_field_map_(nullptr)";
  2383. }
  2384. if (SupportsArenas(descriptor_)) {
  2385. format(
  2386. "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
  2387. " : $1$ {\n"
  2388. " SharedCtor();\n"
  2389. " RegisterArenaDtor(arena);\n"
  2390. " // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
  2391. "}\n",
  2392. initializer_with_arena);
  2393. } else {
  2394. format(
  2395. "$classname$::$classname$()\n"
  2396. " : $1$ {\n"
  2397. " SharedCtor();\n"
  2398. " // @@protoc_insertion_point(constructor:$full_name$)\n"
  2399. "}\n",
  2400. initializer_null);
  2401. }
  2402. std::map<std::string, std::string> vars;
  2403. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2404. format.AddMap(vars);
  2405. // Generate the copy constructor.
  2406. if (UsingImplicitWeakFields(descriptor_->file(), options_)) {
  2407. // If we are in lite mode and using implicit weak fields, we generate a
  2408. // one-liner copy constructor that delegates to MergeFrom. This saves some
  2409. // code size and also cuts down on the complexity of implicit weak fields.
  2410. // We might eventually want to do this for all lite protos.
  2411. format(
  2412. "$classname$::$classname$(const $classname$& from)\n"
  2413. " : $classname$() {\n"
  2414. " MergeFrom(from);\n"
  2415. "}\n");
  2416. } else {
  2417. format(
  2418. "$classname$::$classname$(const $classname$& from)\n"
  2419. " : $superclass$()");
  2420. format.Indent();
  2421. format.Indent();
  2422. format.Indent();
  2423. if (!has_bit_indices_.empty()) {
  2424. format(",\n_has_bits_(from._has_bits_)");
  2425. }
  2426. std::vector<bool> processed(optimized_order_.size(), false);
  2427. for (int i = 0; i < optimized_order_.size(); i++) {
  2428. auto field = optimized_order_[i];
  2429. if (!(field->is_repeated() && !(field->is_map())) &&
  2430. !IsCord(field, options_)) {
  2431. continue;
  2432. }
  2433. processed[i] = true;
  2434. format(",\n$1$_(from.$1$_)", FieldName(field));
  2435. }
  2436. if (IsAnyMessage(descriptor_, options_)) {
  2437. format(",\n_any_metadata_(&type_url_, &value_)");
  2438. }
  2439. if (num_weak_fields_ > 0) {
  2440. format(",\n_weak_field_map_(from._weak_field_map_)");
  2441. }
  2442. format.Outdent();
  2443. format.Outdent();
  2444. format(" {\n");
  2445. format(
  2446. "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
  2447. "metadata_);\n");
  2448. if (descriptor_->extension_range_count() > 0) {
  2449. format("_extensions_.MergeFrom(from._extensions_);\n");
  2450. }
  2451. GenerateConstructorBody(printer, processed, true);
  2452. // Copy oneof fields. Oneof field requires oneof case check.
  2453. for (auto oneof : OneOfRange(descriptor_)) {
  2454. format(
  2455. "clear_has_$1$();\n"
  2456. "switch (from.$1$_case()) {\n",
  2457. oneof->name());
  2458. format.Indent();
  2459. for (auto field : FieldRange(oneof)) {
  2460. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  2461. format.Indent();
  2462. if (IsFieldUsed(field, options_)) {
  2463. field_generators_.get(field).GenerateMergingCode(printer);
  2464. }
  2465. format("break;\n");
  2466. format.Outdent();
  2467. format("}\n");
  2468. }
  2469. format(
  2470. "case $1$_NOT_SET: {\n"
  2471. " break;\n"
  2472. "}\n",
  2473. ToUpper(oneof->name()));
  2474. format.Outdent();
  2475. format("}\n");
  2476. }
  2477. format.Outdent();
  2478. format(
  2479. " // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
  2480. "}\n"
  2481. "\n");
  2482. }
  2483. // Generate the shared constructor code.
  2484. GenerateSharedConstructorCode(printer);
  2485. // Generate the destructor.
  2486. format(
  2487. "$classname$::~$classname$() {\n"
  2488. " // @@protoc_insertion_point(destructor:$full_name$)\n"
  2489. " SharedDtor();\n"
  2490. " _internal_metadata_.Delete<$unknown_fields_type$>();\n"
  2491. "}\n"
  2492. "\n");
  2493. // Generate the shared destructor code.
  2494. GenerateSharedDestructorCode(printer);
  2495. // Generate the arena-specific destructor code.
  2496. if (SupportsArenas(descriptor_)) {
  2497. GenerateArenaDestructorCode(printer);
  2498. }
  2499. // Generate SetCachedSize.
  2500. format(
  2501. "void $classname$::SetCachedSize(int size) const {\n"
  2502. " _cached_size_.Set(size);\n"
  2503. "}\n");
  2504. format(
  2505. "const $classname$& $classname$::default_instance() {\n"
  2506. " "
  2507. "::$proto_ns$::internal::InitSCC(&::$scc_info$.base)"
  2508. ";\n"
  2509. " return *internal_default_instance();\n"
  2510. "}\n\n");
  2511. }
  2512. void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) {
  2513. Formatter format(printer, variables_);
  2514. format(
  2515. "template<> "
  2516. "PROTOBUF_NOINLINE "
  2517. "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
  2518. " return Arena::$1$Internal< $classtype$ >(arena);\n"
  2519. "}\n",
  2520. MessageCreateFunction(descriptor_));
  2521. }
  2522. void MessageGenerator::GenerateClear(io::Printer* printer) {
  2523. Formatter format(printer, variables_);
  2524. // The maximum number of bytes we will memset to zero without checking their
  2525. // hasbit to see if a zero-init is necessary.
  2526. const int kMaxUnconditionalPrimitiveBytesClear = 4;
  2527. format(
  2528. "void $classname$::Clear() {\n"
  2529. "// @@protoc_insertion_point(message_clear_start:$full_name$)\n");
  2530. format.Indent();
  2531. format(
  2532. // TODO(jwb): It would be better to avoid emitting this if it is not used,
  2533. // rather than emitting a workaround for the resulting warning.
  2534. "$uint32$ cached_has_bits = 0;\n"
  2535. "// Prevent compiler warnings about cached_has_bits being unused\n"
  2536. "(void) cached_has_bits;\n\n");
  2537. if (descriptor_->extension_range_count() > 0) {
  2538. format("_extensions_.Clear();\n");
  2539. }
  2540. // Collect fields into chunks. Each chunk may have an if() condition that
  2541. // checks all hasbits in the chunk and skips it if none are set.
  2542. int zero_init_bytes = 0;
  2543. for (const auto& field : optimized_order_) {
  2544. if (CanInitializeByZeroing(field)) {
  2545. zero_init_bytes += EstimateAlignmentSize(field);
  2546. }
  2547. }
  2548. bool merge_zero_init = zero_init_bytes > kMaxUnconditionalPrimitiveBytesClear;
  2549. int chunk_count = 0;
  2550. std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
  2551. optimized_order_,
  2552. [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
  2553. chunk_count++;
  2554. // This predicate guarantees that there is only a single zero-init
  2555. // (memset) per chunk, and if present it will be at the beginning.
  2556. bool same = HasByteIndex(a) == HasByteIndex(b) &&
  2557. a->is_repeated() == b->is_repeated() &&
  2558. (CanInitializeByZeroing(a) == CanInitializeByZeroing(b) ||
  2559. (CanInitializeByZeroing(a) &&
  2560. (chunk_count == 1 || merge_zero_init)));
  2561. if (!same) chunk_count = 0;
  2562. return same;
  2563. });
  2564. ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
  2565. int cached_has_word_index = -1;
  2566. for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
  2567. std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
  2568. cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer);
  2569. const FieldDescriptor* memset_start = nullptr;
  2570. const FieldDescriptor* memset_end = nullptr;
  2571. bool saw_non_zero_init = false;
  2572. for (const auto& field : chunk) {
  2573. if (CanInitializeByZeroing(field)) {
  2574. GOOGLE_CHECK(!saw_non_zero_init);
  2575. if (!memset_start) memset_start = field;
  2576. memset_end = field;
  2577. } else {
  2578. saw_non_zero_init = true;
  2579. }
  2580. }
  2581. // Whether we wrap this chunk in:
  2582. // if (cached_has_bits & <chunk hasbits) { /* chunk. */ }
  2583. // We can omit the if() for chunk size 1, or if our fields do not have
  2584. // hasbits. I don't understand the rationale for the last part of the
  2585. // condition, but it matches the old logic.
  2586. const bool have_outer_if = HasBitIndex(chunk.front()) != kNoHasbit &&
  2587. chunk.size() > 1 &&
  2588. (memset_end != chunk.back() || merge_zero_init);
  2589. if (have_outer_if) {
  2590. // Emit an if() that will let us skip the whole chunk if none are set.
  2591. uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_);
  2592. std::string chunk_mask_str =
  2593. StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
  2594. // Check (up to) 8 has_bits at a time if we have more than one field in
  2595. // this chunk. Due to field layout ordering, we may check
  2596. // _has_bits_[last_chunk * 8 / 32] multiple times.
  2597. GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
  2598. GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
  2599. if (cached_has_word_index != HasWordIndex(chunk.front())) {
  2600. cached_has_word_index = HasWordIndex(chunk.front());
  2601. format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
  2602. }
  2603. format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
  2604. format.Indent();
  2605. }
  2606. if (memset_start) {
  2607. if (memset_start == memset_end) {
  2608. // For clarity, do not memset a single field.
  2609. field_generators_.get(memset_start)
  2610. .GenerateMessageClearingCode(printer);
  2611. } else {
  2612. format(
  2613. "::memset(&$1$_, 0, static_cast<size_t>(\n"
  2614. " reinterpret_cast<char*>(&$2$_) -\n"
  2615. " reinterpret_cast<char*>(&$1$_)) + sizeof($2$_));\n",
  2616. FieldName(memset_start), FieldName(memset_end));
  2617. }
  2618. }
  2619. // Clear all non-zero-initializable fields in the chunk.
  2620. for (const auto& field : chunk) {
  2621. if (CanInitializeByZeroing(field)) continue;
  2622. // It's faster to just overwrite primitive types, but we should only
  2623. // clear strings and messages if they were set.
  2624. //
  2625. // TODO(kenton): Let the CppFieldGenerator decide this somehow.
  2626. bool have_enclosing_if =
  2627. HasBitIndex(field) != kNoHasbit &&
  2628. (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
  2629. field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
  2630. if (have_enclosing_if) {
  2631. PrintPresenceCheck(format, field, has_bit_indices_, printer,
  2632. &cached_has_word_index);
  2633. }
  2634. field_generators_.get(field).GenerateMessageClearingCode(printer);
  2635. if (have_enclosing_if) {
  2636. format.Outdent();
  2637. format("}\n");
  2638. }
  2639. }
  2640. if (have_outer_if) {
  2641. format.Outdent();
  2642. format("}\n");
  2643. }
  2644. if (cold_skipper.OnEndChunk(chunk_index, printer)) {
  2645. // Reset here as it may have been updated in just closed if statement.
  2646. cached_has_word_index = -1;
  2647. }
  2648. }
  2649. // Step 4: Unions.
  2650. for (auto oneof : OneOfRange(descriptor_)) {
  2651. format("clear_$1$();\n", oneof->name());
  2652. }
  2653. if (num_weak_fields_) {
  2654. format("_weak_field_map_.ClearAll();\n");
  2655. }
  2656. if (!has_bit_indices_.empty()) {
  2657. // Step 5: Everything else.
  2658. format("_has_bits_.Clear();\n");
  2659. }
  2660. std::map<std::string, std::string> vars;
  2661. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2662. format.AddMap(vars);
  2663. format("_internal_metadata_.Clear<$unknown_fields_type$>();\n");
  2664. format.Outdent();
  2665. format("}\n");
  2666. }
  2667. void MessageGenerator::GenerateOneofClear(io::Printer* printer) {
  2668. // Generated function clears the active field and union case (e.g. foo_case_).
  2669. int i = 0;
  2670. for (auto oneof : OneOfRange(descriptor_)) {
  2671. Formatter format(printer, variables_);
  2672. format.Set("oneofname", oneof->name());
  2673. format(
  2674. "void $classname$::clear_$oneofname$() {\n"
  2675. "// @@protoc_insertion_point(one_of_clear_start:$full_name$)\n");
  2676. format.Indent();
  2677. format("switch ($oneofname$_case()) {\n");
  2678. format.Indent();
  2679. for (auto field : FieldRange(oneof)) {
  2680. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  2681. format.Indent();
  2682. // We clear only allocated objects in oneofs
  2683. if (!IsStringOrMessage(field) || !IsFieldUsed(field, options_)) {
  2684. format("// No need to clear\n");
  2685. } else {
  2686. field_generators_.get(field).GenerateClearingCode(printer);
  2687. }
  2688. format("break;\n");
  2689. format.Outdent();
  2690. format("}\n");
  2691. }
  2692. format(
  2693. "case $1$_NOT_SET: {\n"
  2694. " break;\n"
  2695. "}\n",
  2696. ToUpper(oneof->name()));
  2697. format.Outdent();
  2698. format(
  2699. "}\n"
  2700. "_oneof_case_[$1$] = $2$_NOT_SET;\n",
  2701. i, ToUpper(oneof->name()));
  2702. format.Outdent();
  2703. format(
  2704. "}\n"
  2705. "\n");
  2706. i++;
  2707. }
  2708. }
  2709. void MessageGenerator::GenerateSwap(io::Printer* printer) {
  2710. Formatter format(printer, variables_);
  2711. format("void $classname$::InternalSwap($classname$* other) {\n");
  2712. format.Indent();
  2713. format("using std::swap;\n");
  2714. if (HasGeneratedMethods(descriptor_->file(), options_)) {
  2715. if (descriptor_->extension_range_count() > 0) {
  2716. format("_extensions_.Swap(&other->_extensions_);\n");
  2717. }
  2718. std::map<std::string, std::string> vars;
  2719. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2720. format.AddMap(vars);
  2721. format(
  2722. "_internal_metadata_.Swap<$unknown_fields_type$>(&other->_internal_"
  2723. "metadata_);\n");
  2724. if (!has_bit_indices_.empty()) {
  2725. for (int i = 0; i < HasBitsSize() / 4; ++i) {
  2726. format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i);
  2727. }
  2728. }
  2729. // If possible, we swap several fields at once, including padding.
  2730. const RunMap runs =
  2731. FindRuns(optimized_order_, [this](const FieldDescriptor* field) {
  2732. return CanBeManipulatedAsRawBytes(field, options_);
  2733. });
  2734. for (int i = 0; i < optimized_order_.size(); ++i) {
  2735. const FieldDescriptor* field = optimized_order_[i];
  2736. const auto it = runs.find(field);
  2737. // We only apply the memswap technique to runs of more than one field, as
  2738. // `swap(field_, other.field_)` is better than
  2739. // `memswap<...>(&field_, &other.field_)` for generated code readability.
  2740. if (it != runs.end() && it->second > 1) {
  2741. // Use a memswap, then skip run_length fields.
  2742. const size_t run_length = it->second;
  2743. const std::string first_field_name = FieldName(field);
  2744. const std::string last_field_name =
  2745. FieldName(optimized_order_[i + run_length - 1]);
  2746. format.Set("first", first_field_name);
  2747. format.Set("last", last_field_name);
  2748. format(
  2749. "::PROTOBUF_NAMESPACE_ID::internal::memswap<\n"
  2750. " PROTOBUF_FIELD_OFFSET($classname$, $last$_)\n"
  2751. " + sizeof($classname$::$last$_)\n"
  2752. " - PROTOBUF_FIELD_OFFSET($classname$, $first$_)>(\n"
  2753. " reinterpret_cast<char*>(&$first$_),\n"
  2754. " reinterpret_cast<char*>(&other->$first$_));\n");
  2755. i += run_length - 1;
  2756. // ++i at the top of the loop.
  2757. } else {
  2758. field_generators_.get(field).GenerateSwappingCode(printer);
  2759. }
  2760. }
  2761. for (auto oneof : OneOfRange(descriptor_)) {
  2762. format("swap($1$_, other->$1$_);\n", oneof->name());
  2763. }
  2764. for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
  2765. format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i);
  2766. }
  2767. if (num_weak_fields_) {
  2768. format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n");
  2769. }
  2770. } else {
  2771. format("GetReflection()->Swap(this, other);");
  2772. }
  2773. format.Outdent();
  2774. format("}\n");
  2775. }
  2776. void MessageGenerator::GenerateMergeFrom(io::Printer* printer) {
  2777. Formatter format(printer, variables_);
  2778. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  2779. // Generate the generalized MergeFrom (aka that which takes in the Message
  2780. // base class as a parameter).
  2781. format(
  2782. "void $classname$::MergeFrom(const ::$proto_ns$::Message& from) {\n"
  2783. "// @@protoc_insertion_point(generalized_merge_from_start:"
  2784. "$full_name$)\n"
  2785. " $DCHK$_NE(&from, this);\n");
  2786. format.Indent();
  2787. // Cast the message to the proper type. If we find that the message is
  2788. // *not* of the proper type, we can still call Merge via the reflection
  2789. // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
  2790. // for each message.
  2791. format(
  2792. "const $classname$* source =\n"
  2793. " ::$proto_ns$::DynamicCastToGenerated<$classname$>(\n"
  2794. " &from);\n"
  2795. "if (source == nullptr) {\n"
  2796. "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
  2797. "$full_name$)\n"
  2798. " ::$proto_ns$::internal::ReflectionOps::Merge(from, this);\n"
  2799. "} else {\n"
  2800. "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
  2801. "$full_name$)\n"
  2802. " MergeFrom(*source);\n"
  2803. "}\n");
  2804. format.Outdent();
  2805. format("}\n");
  2806. } else {
  2807. // Generate CheckTypeAndMergeFrom().
  2808. format(
  2809. "void $classname$::CheckTypeAndMergeFrom(\n"
  2810. " const ::$proto_ns$::MessageLite& from) {\n"
  2811. " MergeFrom(*::$proto_ns$::internal::DownCast<const $classname$*>(\n"
  2812. " &from));\n"
  2813. "}\n");
  2814. }
  2815. }
  2816. void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
  2817. // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
  2818. Formatter format(printer, variables_);
  2819. format(
  2820. "void $classname$::MergeFrom(const $classname$& from) {\n"
  2821. "// @@protoc_insertion_point(class_specific_merge_from_start:"
  2822. "$full_name$)\n"
  2823. " $DCHK$_NE(&from, this);\n");
  2824. format.Indent();
  2825. if (descriptor_->extension_range_count() > 0) {
  2826. format("_extensions_.MergeFrom(from._extensions_);\n");
  2827. }
  2828. std::map<std::string, std::string> vars;
  2829. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2830. format.AddMap(vars);
  2831. format(
  2832. "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
  2833. "metadata_);\n"
  2834. "$uint32$ cached_has_bits = 0;\n"
  2835. "(void) cached_has_bits;\n\n");
  2836. std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
  2837. optimized_order_,
  2838. [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
  2839. return HasByteIndex(a) == HasByteIndex(b);
  2840. });
  2841. ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
  2842. // cached_has_word_index maintains that:
  2843. // cached_has_bits = from._has_bits_[cached_has_word_index]
  2844. // for cached_has_word_index >= 0
  2845. int cached_has_word_index = -1;
  2846. for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
  2847. const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
  2848. bool have_outer_if =
  2849. chunk.size() > 1 && HasByteIndex(chunk.front()) != kNoHasbit;
  2850. cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "from.",
  2851. printer);
  2852. if (have_outer_if) {
  2853. // Emit an if() that will let us skip the whole chunk if none are set.
  2854. uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_);
  2855. std::string chunk_mask_str =
  2856. StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
  2857. // Check (up to) 8 has_bits at a time if we have more than one field in
  2858. // this chunk. Due to field layout ordering, we may check
  2859. // _has_bits_[last_chunk * 8 / 32] multiple times.
  2860. GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
  2861. GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
  2862. if (cached_has_word_index != HasWordIndex(chunk.front())) {
  2863. cached_has_word_index = HasWordIndex(chunk.front());
  2864. format("cached_has_bits = from._has_bits_[$1$];\n",
  2865. cached_has_word_index);
  2866. }
  2867. format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
  2868. format.Indent();
  2869. }
  2870. // Go back and emit merging code for each of the fields we processed.
  2871. bool deferred_has_bit_changes = false;
  2872. for (const auto field : chunk) {
  2873. const FieldGenerator& generator = field_generators_.get(field);
  2874. if (field->is_repeated()) {
  2875. generator.GenerateMergingCode(printer);
  2876. } else if (field->is_optional() && !HasHasbit(field)) {
  2877. // Merge semantics without true field presence: primitive fields are
  2878. // merged only if non-zero (numeric) or non-empty (string).
  2879. bool have_enclosing_if =
  2880. EmitFieldNonDefaultCondition(printer, "from.", field);
  2881. generator.GenerateMergingCode(printer);
  2882. if (have_enclosing_if) {
  2883. format.Outdent();
  2884. format("}\n");
  2885. }
  2886. } else if (field->options().weak() ||
  2887. cached_has_word_index != HasWordIndex(field)) {
  2888. // Check hasbit, not using cached bits.
  2889. GOOGLE_CHECK(HasHasbit(field));
  2890. format("if (from._internal_has_$1$()) {\n", FieldName(field));
  2891. format.Indent();
  2892. generator.GenerateMergingCode(printer);
  2893. format.Outdent();
  2894. format("}\n");
  2895. } else {
  2896. // Check hasbit, using cached bits.
  2897. GOOGLE_CHECK(HasHasbit(field));
  2898. int has_bit_index = has_bit_indices_[field->index()];
  2899. const std::string mask = StrCat(
  2900. strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  2901. format("if (cached_has_bits & 0x$1$u) {\n", mask);
  2902. format.Indent();
  2903. if (have_outer_if && IsPOD(field)) {
  2904. // Defer hasbit modification until the end of chunk.
  2905. // This can reduce the number of loads/stores by up to 7 per 8 fields.
  2906. deferred_has_bit_changes = true;
  2907. generator.GenerateCopyConstructorCode(printer);
  2908. } else {
  2909. generator.GenerateMergingCode(printer);
  2910. }
  2911. format.Outdent();
  2912. format("}\n");
  2913. }
  2914. }
  2915. if (have_outer_if) {
  2916. if (deferred_has_bit_changes) {
  2917. // Flush the has bits for the primitives we deferred.
  2918. GOOGLE_CHECK_LE(0, cached_has_word_index);
  2919. format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index);
  2920. }
  2921. format.Outdent();
  2922. format("}\n");
  2923. }
  2924. if (cold_skipper.OnEndChunk(chunk_index, printer)) {
  2925. // Reset here as it may have been updated in just closed if statement.
  2926. cached_has_word_index = -1;
  2927. }
  2928. }
  2929. // Merge oneof fields. Oneof field requires oneof case check.
  2930. for (auto oneof : OneOfRange(descriptor_)) {
  2931. format("switch (from.$1$_case()) {\n", oneof->name());
  2932. format.Indent();
  2933. for (auto field : FieldRange(oneof)) {
  2934. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  2935. format.Indent();
  2936. if (IsFieldUsed(field, options_)) {
  2937. field_generators_.get(field).GenerateMergingCode(printer);
  2938. }
  2939. format("break;\n");
  2940. format.Outdent();
  2941. format("}\n");
  2942. }
  2943. format(
  2944. "case $1$_NOT_SET: {\n"
  2945. " break;\n"
  2946. "}\n",
  2947. ToUpper(oneof->name()));
  2948. format.Outdent();
  2949. format("}\n");
  2950. }
  2951. if (num_weak_fields_) {
  2952. format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
  2953. }
  2954. format.Outdent();
  2955. format("}\n");
  2956. }
  2957. void MessageGenerator::GenerateCopyFrom(io::Printer* printer) {
  2958. Formatter format(printer, variables_);
  2959. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  2960. // Generate the generalized CopyFrom (aka that which takes in the Message
  2961. // base class as a parameter).
  2962. format(
  2963. "void $classname$::CopyFrom(const ::$proto_ns$::Message& from) {\n"
  2964. "// @@protoc_insertion_point(generalized_copy_from_start:"
  2965. "$full_name$)\n");
  2966. format.Indent();
  2967. format("if (&from == this) return;\n");
  2968. if (!options_.opensource_runtime) {
  2969. // This check is disabled in the opensource release because we're
  2970. // concerned that many users do not define NDEBUG in their release
  2971. // builds.
  2972. format(
  2973. "#ifndef NDEBUG\n"
  2974. "size_t from_size = from.ByteSizeLong();\n"
  2975. "#endif\n"
  2976. "Clear();\n"
  2977. "#ifndef NDEBUG\n"
  2978. "$CHK$_EQ(from_size, from.ByteSizeLong())\n"
  2979. " << \"Source of CopyFrom changed when clearing target. Either \"\n"
  2980. " << \"source is a nested message in target (not allowed), or \"\n"
  2981. " << \"another thread is modifying the source.\";\n"
  2982. "#endif\n");
  2983. } else {
  2984. format("Clear();\n");
  2985. }
  2986. format("MergeFrom(from);\n");
  2987. format.Outdent();
  2988. format("}\n\n");
  2989. }
  2990. // Generate the class-specific CopyFrom.
  2991. format(
  2992. "void $classname$::CopyFrom(const $classname$& from) {\n"
  2993. "// @@protoc_insertion_point(class_specific_copy_from_start:"
  2994. "$full_name$)\n");
  2995. format.Indent();
  2996. format("if (&from == this) return;\n");
  2997. if (!options_.opensource_runtime) {
  2998. // This check is disabled in the opensource release because we're
  2999. // concerned that many users do not define NDEBUG in their release builds.
  3000. format(
  3001. "#ifndef NDEBUG\n"
  3002. "size_t from_size = from.ByteSizeLong();\n"
  3003. "#endif\n"
  3004. "Clear();\n"
  3005. "#ifndef NDEBUG\n"
  3006. "$CHK$_EQ(from_size, from.ByteSizeLong())\n"
  3007. " << \"Source of CopyFrom changed when clearing target. Either \"\n"
  3008. " << \"source is a nested message in target (not allowed), or \"\n"
  3009. " << \"another thread is modifying the source.\";\n"
  3010. "#endif\n");
  3011. } else {
  3012. format("Clear();\n");
  3013. }
  3014. format("MergeFrom(from);\n");
  3015. format.Outdent();
  3016. format("}\n");
  3017. }
  3018. void MessageGenerator::GenerateMergeFromCodedStream(io::Printer* printer) {
  3019. std::map<std::string, std::string> vars = variables_;
  3020. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3021. Formatter format(printer, vars);
  3022. if (descriptor_->options().message_set_wire_format()) {
  3023. // Special-case MessageSet.
  3024. format(
  3025. "const char* $classname$::_InternalParse(const char* ptr,\n"
  3026. " ::$proto_ns$::internal::ParseContext* ctx) {\n"
  3027. " return _extensions_.ParseMessageSet(ptr, \n"
  3028. " internal_default_instance(), &_internal_metadata_, ctx);\n"
  3029. "}\n");
  3030. return;
  3031. }
  3032. GenerateParserLoop(descriptor_, max_has_bit_index_, options_, scc_analyzer_,
  3033. printer);
  3034. }
  3035. void MessageGenerator::GenerateSerializeOneofFields(
  3036. io::Printer* printer, const std::vector<const FieldDescriptor*>& fields) {
  3037. Formatter format(printer, variables_);
  3038. GOOGLE_CHECK(!fields.empty());
  3039. if (fields.size() == 1) {
  3040. GenerateSerializeOneField(printer, fields[0], -1);
  3041. return;
  3042. }
  3043. // We have multiple mutually exclusive choices. Emit a switch statement.
  3044. const OneofDescriptor* oneof = fields[0]->containing_oneof();
  3045. format("switch ($1$_case()) {\n", oneof->name());
  3046. format.Indent();
  3047. for (auto field : fields) {
  3048. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  3049. format.Indent();
  3050. field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
  3051. printer);
  3052. format("break;\n");
  3053. format.Outdent();
  3054. format("}\n");
  3055. }
  3056. format.Outdent();
  3057. // Doing nothing is an option.
  3058. format(
  3059. " default: ;\n"
  3060. "}\n");
  3061. }
  3062. void MessageGenerator::GenerateSerializeOneField(io::Printer* printer,
  3063. const FieldDescriptor* field,
  3064. int cached_has_bits_index) {
  3065. Formatter format(printer, variables_);
  3066. if (!field->options().weak()) {
  3067. // For weakfields, PrintFieldComment is called during iteration.
  3068. PrintFieldComment(format, field);
  3069. }
  3070. bool have_enclosing_if = false;
  3071. if (field->options().weak()) {
  3072. } else if (HasHasbit(field)) {
  3073. // Attempt to use the state of cached_has_bits, if possible.
  3074. int has_bit_index = HasBitIndex(field);
  3075. if (cached_has_bits_index == has_bit_index / 32) {
  3076. const std::string mask =
  3077. StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  3078. format("if (cached_has_bits & 0x$1$u) {\n", mask);
  3079. } else {
  3080. format("if (_internal_has_$1$()) {\n", FieldName(field));
  3081. }
  3082. format.Indent();
  3083. have_enclosing_if = true;
  3084. } else if (field->is_optional() && !HasHasbit(field)) {
  3085. have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field);
  3086. }
  3087. field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(printer);
  3088. if (have_enclosing_if) {
  3089. format.Outdent();
  3090. format("}\n");
  3091. }
  3092. format("\n");
  3093. }
  3094. void MessageGenerator::GenerateSerializeOneExtensionRange(
  3095. io::Printer* printer, const Descriptor::ExtensionRange* range) {
  3096. std::map<std::string, std::string> vars = variables_;
  3097. vars["start"] = StrCat(range->start);
  3098. vars["end"] = StrCat(range->end);
  3099. Formatter format(printer, vars);
  3100. format("// Extension range [$start$, $end$)\n");
  3101. format(
  3102. "target = _extensions_._InternalSerialize(\n"
  3103. " $start$, $end$, target, stream);\n\n");
  3104. }
  3105. void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
  3106. io::Printer* printer) {
  3107. Formatter format(printer, variables_);
  3108. if (descriptor_->options().message_set_wire_format()) {
  3109. // Special-case MessageSet.
  3110. format(
  3111. "$uint8$* $classname$::_InternalSerialize(\n"
  3112. " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
  3113. "const {\n"
  3114. " target = _extensions_."
  3115. "InternalSerializeMessageSetWithCachedSizesToArray(target, stream);\n");
  3116. std::map<std::string, std::string> vars;
  3117. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3118. format.AddMap(vars);
  3119. format(
  3120. " target = ::$proto_ns$::internal::"
  3121. "InternalSerializeUnknownMessageSetItemsToArray(\n"
  3122. " $unknown_fields$, target, stream);\n");
  3123. format(
  3124. " return target;\n"
  3125. "}\n");
  3126. return;
  3127. }
  3128. format(
  3129. "$uint8$* $classname$::_InternalSerialize(\n"
  3130. " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
  3131. "const {\n");
  3132. format.Indent();
  3133. format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n");
  3134. GenerateSerializeWithCachedSizesBody(printer);
  3135. format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n");
  3136. format.Outdent();
  3137. format(
  3138. " return target;\n"
  3139. "}\n");
  3140. }
  3141. void MessageGenerator::GenerateSerializeWithCachedSizesBody(
  3142. io::Printer* printer) {
  3143. Formatter format(printer, variables_);
  3144. // If there are multiple fields in a row from the same oneof then we
  3145. // coalesce them and emit a switch statement. This is more efficient
  3146. // because it lets the C++ compiler know this is a "at most one can happen"
  3147. // situation. If we emitted "if (has_x()) ...; if (has_y()) ..." the C++
  3148. // compiler's emitted code might check has_y() even when has_x() is true.
  3149. class LazySerializerEmitter {
  3150. public:
  3151. LazySerializerEmitter(MessageGenerator* mg, io::Printer* printer)
  3152. : mg_(mg),
  3153. format_(printer),
  3154. eager_(!HasFieldPresence(mg->descriptor_->file())),
  3155. cached_has_bit_index_(kNoHasbit) {}
  3156. ~LazySerializerEmitter() { Flush(); }
  3157. // If conditions allow, try to accumulate a run of fields from the same
  3158. // oneof, and handle them at the next Flush().
  3159. void Emit(const FieldDescriptor* field) {
  3160. if (eager_ || MustFlush(field)) {
  3161. Flush();
  3162. }
  3163. if (!field->real_containing_oneof()) {
  3164. // TODO(ckennelly): Defer non-oneof fields similarly to oneof fields.
  3165. if (!field->options().weak() && !field->is_repeated() && !eager_) {
  3166. // We speculatively load the entire _has_bits_[index] contents, even
  3167. // if it is for only one field. Deferring non-oneof emitting would
  3168. // allow us to determine whether this is going to be useful.
  3169. int has_bit_index = mg_->has_bit_indices_[field->index()];
  3170. if (cached_has_bit_index_ != has_bit_index / 32) {
  3171. // Reload.
  3172. int new_index = has_bit_index / 32;
  3173. format_("cached_has_bits = _has_bits_[$1$];\n", new_index);
  3174. cached_has_bit_index_ = new_index;
  3175. }
  3176. }
  3177. mg_->GenerateSerializeOneField(format_.printer(), field,
  3178. cached_has_bit_index_);
  3179. } else {
  3180. v_.push_back(field);
  3181. }
  3182. }
  3183. void Flush() {
  3184. if (!v_.empty()) {
  3185. mg_->GenerateSerializeOneofFields(format_.printer(), v_);
  3186. v_.clear();
  3187. }
  3188. }
  3189. private:
  3190. // If we have multiple fields in v_ then they all must be from the same
  3191. // oneof. Would adding field to v_ break that invariant?
  3192. bool MustFlush(const FieldDescriptor* field) {
  3193. return !v_.empty() &&
  3194. v_[0]->containing_oneof() != field->containing_oneof();
  3195. }
  3196. MessageGenerator* mg_;
  3197. Formatter format_;
  3198. const bool eager_;
  3199. std::vector<const FieldDescriptor*> v_;
  3200. // cached_has_bit_index_ maintains that:
  3201. // cached_has_bits = from._has_bits_[cached_has_bit_index_]
  3202. // for cached_has_bit_index_ >= 0
  3203. int cached_has_bit_index_;
  3204. };
  3205. std::vector<const FieldDescriptor*> ordered_fields =
  3206. SortFieldsByNumber(descriptor_);
  3207. std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
  3208. sorted_extensions.reserve(descriptor_->extension_range_count());
  3209. for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
  3210. sorted_extensions.push_back(descriptor_->extension_range(i));
  3211. }
  3212. std::sort(sorted_extensions.begin(), sorted_extensions.end(),
  3213. ExtensionRangeSorter());
  3214. if (num_weak_fields_) {
  3215. format(
  3216. "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
  3217. "_weak_field_map_);\n");
  3218. }
  3219. format(
  3220. "$uint32$ cached_has_bits = 0;\n"
  3221. "(void) cached_has_bits;\n\n");
  3222. // Merge the fields and the extension ranges, both sorted by field number.
  3223. {
  3224. LazySerializerEmitter e(this, printer);
  3225. const FieldDescriptor* last_weak_field = nullptr;
  3226. int i, j;
  3227. for (i = 0, j = 0;
  3228. i < ordered_fields.size() || j < sorted_extensions.size();) {
  3229. if ((j == sorted_extensions.size()) ||
  3230. (i < descriptor_->field_count() &&
  3231. ordered_fields[i]->number() < sorted_extensions[j]->start)) {
  3232. const FieldDescriptor* field = ordered_fields[i++];
  3233. if (!IsFieldUsed(field, options_)) {
  3234. continue;
  3235. }
  3236. if (field->options().weak()) {
  3237. last_weak_field = field;
  3238. PrintFieldComment(format, field);
  3239. } else {
  3240. if (last_weak_field != nullptr) {
  3241. e.Emit(last_weak_field);
  3242. last_weak_field = nullptr;
  3243. }
  3244. e.Emit(field);
  3245. }
  3246. } else {
  3247. if (last_weak_field != nullptr) {
  3248. e.Emit(last_weak_field);
  3249. last_weak_field = nullptr;
  3250. }
  3251. e.Flush();
  3252. GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
  3253. }
  3254. }
  3255. if (last_weak_field != nullptr) {
  3256. e.Emit(last_weak_field);
  3257. }
  3258. }
  3259. std::map<std::string, std::string> vars;
  3260. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3261. format.AddMap(vars);
  3262. format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
  3263. format.Indent();
  3264. if (UseUnknownFieldSet(descriptor_->file(), options_)) {
  3265. format(
  3266. "target = "
  3267. "::$proto_ns$::internal::WireFormat::"
  3268. "InternalSerializeUnknownFieldsToArray(\n"
  3269. " $unknown_fields$, target, stream);\n");
  3270. } else {
  3271. format(
  3272. "target = stream->WriteRaw($unknown_fields$.data(),\n"
  3273. " static_cast<int>($unknown_fields$.size()), target);\n");
  3274. }
  3275. format.Outdent();
  3276. format("}\n");
  3277. }
  3278. std::vector<uint32> MessageGenerator::RequiredFieldsBitMask() const {
  3279. const int array_size = HasBitsSize();
  3280. std::vector<uint32> masks(array_size, 0);
  3281. for (auto field : FieldRange(descriptor_)) {
  3282. if (!field->is_required()) {
  3283. continue;
  3284. }
  3285. const int has_bit_index = has_bit_indices_[field->index()];
  3286. masks[has_bit_index / 32] |= static_cast<uint32>(1) << (has_bit_index % 32);
  3287. }
  3288. return masks;
  3289. }
  3290. void MessageGenerator::GenerateByteSize(io::Printer* printer) {
  3291. Formatter format(printer, variables_);
  3292. if (descriptor_->options().message_set_wire_format()) {
  3293. // Special-case MessageSet.
  3294. std::map<std::string, std::string> vars;
  3295. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3296. format.AddMap(vars);
  3297. format(
  3298. "size_t $classname$::ByteSizeLong() const {\n"
  3299. "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
  3300. " size_t total_size = _extensions_.MessageSetByteSize();\n"
  3301. " if ($have_unknown_fields$) {\n"
  3302. " total_size += ::$proto_ns$::internal::\n"
  3303. " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n"
  3304. " }\n"
  3305. " int cached_size = "
  3306. "::$proto_ns$::internal::ToCachedSize(total_size);\n"
  3307. " SetCachedSize(cached_size);\n"
  3308. " return total_size;\n"
  3309. "}\n");
  3310. return;
  3311. }
  3312. if (num_required_fields_ > 1) {
  3313. // Emit a function (rarely used, we hope) that handles the required fields
  3314. // by checking for each one individually.
  3315. format(
  3316. "size_t $classname$::RequiredFieldsByteSizeFallback() const {\n"
  3317. "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
  3318. "$full_name$)\n");
  3319. format.Indent();
  3320. format("size_t total_size = 0;\n");
  3321. for (auto field : optimized_order_) {
  3322. if (field->is_required()) {
  3323. format(
  3324. "\n"
  3325. "if (_internal_has_$1$()) {\n",
  3326. FieldName(field));
  3327. format.Indent();
  3328. PrintFieldComment(format, field);
  3329. field_generators_.get(field).GenerateByteSize(printer);
  3330. format.Outdent();
  3331. format("}\n");
  3332. }
  3333. }
  3334. format(
  3335. "\n"
  3336. "return total_size;\n");
  3337. format.Outdent();
  3338. format("}\n");
  3339. }
  3340. format(
  3341. "size_t $classname$::ByteSizeLong() const {\n"
  3342. "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n");
  3343. format.Indent();
  3344. format(
  3345. "size_t total_size = 0;\n"
  3346. "\n");
  3347. if (descriptor_->extension_range_count() > 0) {
  3348. format(
  3349. "total_size += _extensions_.ByteSize();\n"
  3350. "\n");
  3351. }
  3352. std::map<std::string, std::string> vars;
  3353. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3354. format.AddMap(vars);
  3355. // Handle required fields (if any). We expect all of them to be
  3356. // present, so emit one conditional that checks for that. If they are all
  3357. // present then the fast path executes; otherwise the slow path executes.
  3358. if (num_required_fields_ > 1) {
  3359. // The fast path works if all required fields are present.
  3360. const std::vector<uint32> masks_for_has_bits = RequiredFieldsBitMask();
  3361. format("if ($1$) { // All required fields are present.\n",
  3362. ConditionalToCheckBitmasks(masks_for_has_bits));
  3363. format.Indent();
  3364. // Oneof fields cannot be required, so optimized_order_ contains all of the
  3365. // fields that we need to potentially emit.
  3366. for (auto field : optimized_order_) {
  3367. if (!field->is_required()) continue;
  3368. PrintFieldComment(format, field);
  3369. field_generators_.get(field).GenerateByteSize(printer);
  3370. format("\n");
  3371. }
  3372. format.Outdent();
  3373. format(
  3374. "} else {\n" // the slow path
  3375. " total_size += RequiredFieldsByteSizeFallback();\n"
  3376. "}\n");
  3377. } else {
  3378. // num_required_fields_ <= 1: no need to be tricky
  3379. for (auto field : optimized_order_) {
  3380. if (!field->is_required()) continue;
  3381. PrintFieldComment(format, field);
  3382. format("if (_internal_has_$1$()) {\n", FieldName(field));
  3383. format.Indent();
  3384. field_generators_.get(field).GenerateByteSize(printer);
  3385. format.Outdent();
  3386. format("}\n");
  3387. }
  3388. }
  3389. std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
  3390. optimized_order_,
  3391. [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
  3392. return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b);
  3393. });
  3394. // Remove chunks with required fields.
  3395. chunks.erase(std::remove_if(chunks.begin(), chunks.end(), IsRequired),
  3396. chunks.end());
  3397. ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
  3398. int cached_has_word_index = -1;
  3399. format(
  3400. "$uint32$ cached_has_bits = 0;\n"
  3401. "// Prevent compiler warnings about cached_has_bits being unused\n"
  3402. "(void) cached_has_bits;\n\n");
  3403. for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
  3404. const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
  3405. const bool have_outer_if =
  3406. chunk.size() > 1 && HasWordIndex(chunk[0]) != kNoHasbit;
  3407. cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer);
  3408. if (have_outer_if) {
  3409. // Emit an if() that will let us skip the whole chunk if none are set.
  3410. uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_);
  3411. std::string chunk_mask_str =
  3412. StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
  3413. // Check (up to) 8 has_bits at a time if we have more than one field in
  3414. // this chunk. Due to field layout ordering, we may check
  3415. // _has_bits_[last_chunk * 8 / 32] multiple times.
  3416. GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
  3417. GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
  3418. if (cached_has_word_index != HasWordIndex(chunk.front())) {
  3419. cached_has_word_index = HasWordIndex(chunk.front());
  3420. format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
  3421. }
  3422. format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
  3423. format.Indent();
  3424. }
  3425. // Go back and emit checks for each of the fields we processed.
  3426. for (int j = 0; j < chunk.size(); j++) {
  3427. const FieldDescriptor* field = chunk[j];
  3428. const FieldGenerator& generator = field_generators_.get(field);
  3429. bool have_enclosing_if = false;
  3430. bool need_extra_newline = false;
  3431. PrintFieldComment(format, field);
  3432. if (field->is_repeated()) {
  3433. // No presence check is required.
  3434. need_extra_newline = true;
  3435. } else if (HasHasbit(field)) {
  3436. PrintPresenceCheck(format, field, has_bit_indices_, printer,
  3437. &cached_has_word_index);
  3438. have_enclosing_if = true;
  3439. } else {
  3440. // Without field presence: field is serialized only if it has a
  3441. // non-default value.
  3442. have_enclosing_if =
  3443. EmitFieldNonDefaultCondition(printer, "this->", field);
  3444. }
  3445. generator.GenerateByteSize(printer);
  3446. if (have_enclosing_if) {
  3447. format.Outdent();
  3448. format(
  3449. "}\n"
  3450. "\n");
  3451. }
  3452. if (need_extra_newline) {
  3453. format("\n");
  3454. }
  3455. }
  3456. if (have_outer_if) {
  3457. format.Outdent();
  3458. format("}\n");
  3459. }
  3460. if (cold_skipper.OnEndChunk(chunk_index, printer)) {
  3461. // Reset here as it may have been updated in just closed if statement.
  3462. cached_has_word_index = -1;
  3463. }
  3464. }
  3465. // Fields inside a oneof don't use _has_bits_ so we count them in a separate
  3466. // pass.
  3467. for (auto oneof : OneOfRange(descriptor_)) {
  3468. format("switch ($1$_case()) {\n", oneof->name());
  3469. format.Indent();
  3470. for (auto field : FieldRange(oneof)) {
  3471. PrintFieldComment(format, field);
  3472. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  3473. format.Indent();
  3474. if (IsFieldUsed(field, options_)) {
  3475. field_generators_.get(field).GenerateByteSize(printer);
  3476. }
  3477. format("break;\n");
  3478. format.Outdent();
  3479. format("}\n");
  3480. }
  3481. format(
  3482. "case $1$_NOT_SET: {\n"
  3483. " break;\n"
  3484. "}\n",
  3485. ToUpper(oneof->name()));
  3486. format.Outdent();
  3487. format("}\n");
  3488. }
  3489. if (num_weak_fields_) {
  3490. // TagSize + MessageSize
  3491. format("total_size += _weak_field_map_.ByteSizeLong();\n");
  3492. }
  3493. format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
  3494. if (UseUnknownFieldSet(descriptor_->file(), options_)) {
  3495. // We go out of our way to put the computation of the uncommon path of
  3496. // unknown fields in tail position. This allows for better code generation
  3497. // of this function for simple protos.
  3498. format(
  3499. " return ::$proto_ns$::internal::ComputeUnknownFieldsSize(\n"
  3500. " _internal_metadata_, total_size, &_cached_size_);\n");
  3501. } else {
  3502. format(" total_size += $unknown_fields$.size();\n");
  3503. }
  3504. format("}\n");
  3505. // We update _cached_size_ even though this is a const method. Because
  3506. // const methods might be called concurrently this needs to be atomic
  3507. // operations or the program is undefined. In practice, since any concurrent
  3508. // writes will be writing the exact same value, normal writes will work on
  3509. // all common processors. We use a dedicated wrapper class to abstract away
  3510. // the underlying atomic. This makes it easier on platforms where even relaxed
  3511. // memory order might have perf impact to replace it with ordinary loads and
  3512. // stores.
  3513. format(
  3514. "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n"
  3515. "SetCachedSize(cached_size);\n"
  3516. "return total_size;\n");
  3517. format.Outdent();
  3518. format("}\n");
  3519. }
  3520. void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
  3521. Formatter format(printer, variables_);
  3522. format("bool $classname$::IsInitialized() const {\n");
  3523. format.Indent();
  3524. if (descriptor_->extension_range_count() > 0) {
  3525. format(
  3526. "if (!_extensions_.IsInitialized()) {\n"
  3527. " return false;\n"
  3528. "}\n\n");
  3529. }
  3530. if (num_required_fields_ > 0) {
  3531. format(
  3532. "if (_Internal::MissingRequiredFields(_has_bits_))"
  3533. " return false;\n");
  3534. }
  3535. // Now check that all non-oneof embedded messages are initialized.
  3536. for (auto field : optimized_order_) {
  3537. // TODO(ckennelly): Push this down into a generator?
  3538. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  3539. !ShouldIgnoreRequiredFieldCheck(field, options_) &&
  3540. scc_analyzer_->HasRequiredFields(field->message_type())) {
  3541. if (field->is_repeated()) {
  3542. if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
  3543. format(
  3544. "if "
  3545. "(!::$proto_ns$::internal::AllAreInitializedWeak($1$_.weak)"
  3546. ")"
  3547. " return false;\n",
  3548. FieldName(field));
  3549. } else {
  3550. format(
  3551. "if (!::$proto_ns$::internal::AllAreInitialized($1$_))"
  3552. " return false;\n",
  3553. FieldName(field));
  3554. }
  3555. } else if (field->options().weak()) {
  3556. continue;
  3557. } else {
  3558. GOOGLE_CHECK(!field->real_containing_oneof());
  3559. format(
  3560. "if (_internal_has_$1$()) {\n"
  3561. " if (!$1$_->IsInitialized()) return false;\n"
  3562. "}\n",
  3563. FieldName(field));
  3564. }
  3565. }
  3566. }
  3567. if (num_weak_fields_) {
  3568. // For Weak fields.
  3569. format("if (!_weak_field_map_.IsInitialized()) return false;\n");
  3570. }
  3571. // Go through the oneof fields, emitting a switch if any might have required
  3572. // fields.
  3573. for (auto oneof : OneOfRange(descriptor_)) {
  3574. bool has_required_fields = false;
  3575. for (auto field : FieldRange(oneof)) {
  3576. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  3577. !ShouldIgnoreRequiredFieldCheck(field, options_) &&
  3578. scc_analyzer_->HasRequiredFields(field->message_type())) {
  3579. has_required_fields = true;
  3580. break;
  3581. }
  3582. }
  3583. if (!has_required_fields) {
  3584. continue;
  3585. }
  3586. format("switch ($1$_case()) {\n", oneof->name());
  3587. format.Indent();
  3588. for (auto field : FieldRange(oneof)) {
  3589. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  3590. format.Indent();
  3591. if (IsFieldUsed(field, options_) &&
  3592. field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  3593. !ShouldIgnoreRequiredFieldCheck(field, options_) &&
  3594. scc_analyzer_->HasRequiredFields(field->message_type())) {
  3595. GOOGLE_CHECK(!(field->options().weak() || !field->real_containing_oneof()));
  3596. if (field->options().weak()) {
  3597. // Just skip.
  3598. } else {
  3599. format(
  3600. "if (has_$1$()) {\n"
  3601. " if (!this->$1$().IsInitialized()) return false;\n"
  3602. "}\n",
  3603. FieldName(field));
  3604. }
  3605. }
  3606. format("break;\n");
  3607. format.Outdent();
  3608. format("}\n");
  3609. }
  3610. format(
  3611. "case $1$_NOT_SET: {\n"
  3612. " break;\n"
  3613. "}\n",
  3614. ToUpper(oneof->name()));
  3615. format.Outdent();
  3616. format("}\n");
  3617. }
  3618. format.Outdent();
  3619. format(
  3620. " return true;\n"
  3621. "}\n");
  3622. }
  3623. } // namespace cpp
  3624. } // namespace compiler
  3625. } // namespace protobuf
  3626. } // namespace google