cpp_message.cc 137 KB

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