cpp_message.cc 137 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064
  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. static std::set<std::string> exclusions{
  281. };
  282. const std::string name = ClassName(descriptor, true);
  283. return exclusions.find(name) == exclusions.end() ||
  284. options.opensource_runtime;
  285. }
  286. // Returns true to make the message serialize in order, decided by the following
  287. // factors in the order of precedence.
  288. // --options().message_set_wire_format() == true
  289. // --the message is in the allowlist (true)
  290. // --GOOGLE_PROTOBUF_SHUFFLE_SERIALIZE is defined (false)
  291. // --a ranage of message names that are allowed to stay in order (true)
  292. bool ShouldSerializeInOrder(const Descriptor* descriptor,
  293. const Options& options) {
  294. return true;
  295. }
  296. bool TableDrivenParsingEnabled(const Descriptor* descriptor,
  297. const Options& options) {
  298. if (!options.table_driven_parsing) {
  299. return false;
  300. }
  301. // Consider table-driven parsing. We only do this if:
  302. // - We have has_bits for fields. This avoids a check on every field we set
  303. // when are present (the common case).
  304. bool has_hasbit = false;
  305. for (int i = 0; i < descriptor->field_count(); i++) {
  306. if (HasHasbit(descriptor->field(i))) {
  307. has_hasbit = true;
  308. break;
  309. }
  310. }
  311. if (!has_hasbit) return false;
  312. const double table_sparseness = 0.5;
  313. int max_field_number = 0;
  314. for (auto field : FieldRange(descriptor)) {
  315. if (max_field_number < field->number()) {
  316. max_field_number = field->number();
  317. }
  318. // - There are no weak fields.
  319. if (IsWeak(field, options)) {
  320. return false;
  321. }
  322. // - There are no lazy fields (they require the non-lite library).
  323. if (IsLazy(field, options)) {
  324. return false;
  325. }
  326. }
  327. // - There range of field numbers is "small"
  328. if (max_field_number >= (2 << 14)) {
  329. return false;
  330. }
  331. // - Field numbers are relatively dense within the actual number of fields.
  332. // We check for strictly greater than in the case where there are no fields
  333. // (only extensions) so max_field_number == descriptor->field_count() == 0.
  334. if (max_field_number * table_sparseness > descriptor->field_count()) {
  335. return false;
  336. }
  337. // - This is not a MapEntryMessage.
  338. if (IsMapEntryMessage(descriptor)) {
  339. return false;
  340. }
  341. return true;
  342. }
  343. bool IsCrossFileMapField(const FieldDescriptor* field) {
  344. if (!field->is_map()) {
  345. return false;
  346. }
  347. const Descriptor* d = field->message_type();
  348. const FieldDescriptor* value = d->FindFieldByNumber(2);
  349. return IsCrossFileMessage(value);
  350. }
  351. bool IsCrossFileMaybeMap(const FieldDescriptor* field) {
  352. if (IsCrossFileMapField(field)) {
  353. return true;
  354. }
  355. return IsCrossFileMessage(field);
  356. }
  357. bool IsRequired(const std::vector<const FieldDescriptor*>& v) {
  358. return v.front()->is_required();
  359. }
  360. // Collects neighboring fields based on a given criteria (equivalent predicate).
  361. template <typename Predicate>
  362. std::vector<std::vector<const FieldDescriptor*>> CollectFields(
  363. const std::vector<const FieldDescriptor*>& fields,
  364. const Predicate& equivalent) {
  365. std::vector<std::vector<const FieldDescriptor*>> chunks;
  366. for (auto field : fields) {
  367. if (chunks.empty() || !equivalent(chunks.back().back(), field)) {
  368. chunks.emplace_back();
  369. }
  370. chunks.back().push_back(field);
  371. }
  372. return chunks;
  373. }
  374. // Returns a bit mask based on has_bit index of "fields" that are typically on
  375. // the same chunk. It is used in a group presence check where _has_bits_ is
  376. // masked to tell if any thing in "fields" is present.
  377. uint32 GenChunkMask(const std::vector<const FieldDescriptor*>& fields,
  378. const std::vector<int>& has_bit_indices) {
  379. GOOGLE_CHECK(!fields.empty());
  380. int first_index_offset = has_bit_indices[fields.front()->index()] / 32;
  381. uint32 chunk_mask = 0;
  382. for (auto field : fields) {
  383. // "index" defines where in the _has_bits_ the field appears.
  384. int index = has_bit_indices[field->index()];
  385. GOOGLE_CHECK_EQ(first_index_offset, index / 32);
  386. chunk_mask |= static_cast<uint32>(1) << (index % 32);
  387. }
  388. GOOGLE_CHECK_NE(0, chunk_mask);
  389. return chunk_mask;
  390. }
  391. // Return the number of bits set in n, a non-negative integer.
  392. static int popcnt(uint32 n) {
  393. int result = 0;
  394. while (n != 0) {
  395. result += (n & 1);
  396. n = n / 2;
  397. }
  398. return result;
  399. }
  400. // For a run of cold chunks, opens and closes an external if statement that
  401. // checks multiple has_bits words to skip bulk of cold fields.
  402. class ColdChunkSkipper {
  403. public:
  404. ColdChunkSkipper(
  405. const Options& options,
  406. const std::vector<std::vector<const FieldDescriptor*>>& chunks,
  407. const std::vector<int>& has_bit_indices, const double cold_threshold)
  408. : chunks_(chunks),
  409. has_bit_indices_(has_bit_indices),
  410. access_info_map_(options.access_info_map),
  411. cold_threshold_(cold_threshold) {
  412. SetCommonVars(options, &variables_);
  413. }
  414. // May open an external if check for a batch of cold fields. "from" is the
  415. // prefix to _has_bits_ to allow MergeFrom to use "from._has_bits_".
  416. // Otherwise, it should be "".
  417. void OnStartChunk(int chunk, int cached_has_word_index,
  418. const std::string& from, io::Printer* printer);
  419. bool OnEndChunk(int chunk, io::Printer* printer);
  420. private:
  421. bool IsColdChunk(int chunk);
  422. int HasbitWord(int chunk, int offset) {
  423. return has_bit_indices_[chunks_[chunk][offset]->index()] / 32;
  424. }
  425. const std::vector<std::vector<const FieldDescriptor*>>& chunks_;
  426. const std::vector<int>& has_bit_indices_;
  427. const AccessInfoMap* access_info_map_;
  428. const double cold_threshold_;
  429. std::map<std::string, std::string> variables_;
  430. int limit_chunk_ = -1;
  431. };
  432. // Tuning parameters for ColdChunkSkipper.
  433. const double kColdRatio = 0.005;
  434. bool ColdChunkSkipper::IsColdChunk(int chunk) {
  435. // Mark this variable as used until it is actually used
  436. (void)cold_threshold_;
  437. return false;
  438. }
  439. void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_word_index,
  440. const std::string& from,
  441. io::Printer* printer) {
  442. Formatter format(printer, variables_);
  443. if (!access_info_map_) {
  444. return;
  445. } else if (chunk < limit_chunk_) {
  446. // We are already inside a run of cold chunks.
  447. return;
  448. } else if (!IsColdChunk(chunk)) {
  449. // We can't start a run of cold chunks.
  450. return;
  451. }
  452. // Find the end of consecutive cold chunks.
  453. limit_chunk_ = chunk;
  454. while (limit_chunk_ < chunks_.size() && IsColdChunk(limit_chunk_)) {
  455. limit_chunk_++;
  456. }
  457. if (limit_chunk_ <= chunk + 1) {
  458. // Require at least two chunks to emit external has_bit checks.
  459. limit_chunk_ = -1;
  460. return;
  461. }
  462. // Emit has_bit check for each has_bit_dword index.
  463. format("if (PROTOBUF_PREDICT_FALSE(");
  464. int first_word = HasbitWord(chunk, 0);
  465. while (chunk < limit_chunk_) {
  466. uint32 mask = 0;
  467. int this_word = HasbitWord(chunk, 0);
  468. // Generate mask for chunks on the same word.
  469. for (; chunk < limit_chunk_ && HasbitWord(chunk, 0) == this_word; chunk++) {
  470. for (auto field : chunks_[chunk]) {
  471. int hasbit_index = has_bit_indices_[field->index()];
  472. // Fields on a chunk must be in the same word.
  473. GOOGLE_CHECK_EQ(this_word, hasbit_index / 32);
  474. mask |= 1 << (hasbit_index % 32);
  475. }
  476. }
  477. if (this_word != first_word) {
  478. format(" ||\n ");
  479. }
  480. format.Set("mask", strings::Hex(mask, strings::ZERO_PAD_8));
  481. if (this_word == cached_has_word_index) {
  482. format("(cached_has_bits & 0x$mask$u) != 0");
  483. } else {
  484. format("($1$_has_bits_[$2$] & 0x$mask$u) != 0", from, this_word);
  485. }
  486. }
  487. format(")) {\n");
  488. format.Indent();
  489. }
  490. bool ColdChunkSkipper::OnEndChunk(int chunk, io::Printer* printer) {
  491. Formatter format(printer, variables_);
  492. if (chunk != limit_chunk_ - 1) {
  493. return false;
  494. }
  495. format.Outdent();
  496. format("}\n");
  497. return true;
  498. }
  499. } // anonymous namespace
  500. // ===================================================================
  501. MessageGenerator::MessageGenerator(
  502. const Descriptor* descriptor,
  503. const std::map<std::string, std::string>& vars, int index_in_file_messages,
  504. const Options& options, MessageSCCAnalyzer* scc_analyzer)
  505. : descriptor_(descriptor),
  506. index_in_file_messages_(index_in_file_messages),
  507. classname_(ClassName(descriptor, false)),
  508. options_(options),
  509. field_generators_(descriptor, options, scc_analyzer),
  510. max_has_bit_index_(0),
  511. num_weak_fields_(0),
  512. scc_analyzer_(scc_analyzer),
  513. variables_(vars) {
  514. if (!message_layout_helper_) {
  515. message_layout_helper_.reset(new PaddingOptimizer());
  516. }
  517. // Variables that apply to this class
  518. variables_["classname"] = classname_;
  519. variables_["classtype"] = QualifiedClassName(descriptor_, options);
  520. variables_["scc_info"] =
  521. SccInfoSymbol(scc_analyzer_->GetSCC(descriptor_), options_);
  522. variables_["full_name"] = descriptor_->full_name();
  523. variables_["superclass"] = SuperClassName(descriptor_, options_);
  524. // Compute optimized field order to be used for layout and initialization
  525. // purposes.
  526. for (auto field : FieldRange(descriptor_)) {
  527. if (IsFieldStripped(field, options_)) {
  528. continue;
  529. }
  530. if (IsWeak(field, options_)) {
  531. num_weak_fields_++;
  532. } else if (!field->real_containing_oneof()) {
  533. optimized_order_.push_back(field);
  534. }
  535. }
  536. message_layout_helper_->OptimizeLayout(&optimized_order_, options_);
  537. // This message has hasbits iff one or more fields need one.
  538. for (auto field : optimized_order_) {
  539. if (HasHasbit(field)) {
  540. if (has_bit_indices_.empty()) {
  541. has_bit_indices_.resize(descriptor_->field_count(), kNoHasbit);
  542. }
  543. has_bit_indices_[field->index()] = max_has_bit_index_++;
  544. }
  545. }
  546. if (!has_bit_indices_.empty()) {
  547. field_generators_.SetHasBitIndices(has_bit_indices_);
  548. }
  549. num_required_fields_ = 0;
  550. for (int i = 0; i < descriptor->field_count(); i++) {
  551. if (descriptor->field(i)->is_required()) {
  552. ++num_required_fields_;
  553. }
  554. }
  555. table_driven_ = TableDrivenParsingEnabled(descriptor_, options_);
  556. }
  557. MessageGenerator::~MessageGenerator() = default;
  558. size_t MessageGenerator::HasBitsSize() const {
  559. return (max_has_bit_index_ + 31) / 32;
  560. }
  561. int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const {
  562. return has_bit_indices_.empty() ? kNoHasbit
  563. : has_bit_indices_[field->index()];
  564. }
  565. int MessageGenerator::HasByteIndex(const FieldDescriptor* field) const {
  566. int hasbit = HasBitIndex(field);
  567. return hasbit == kNoHasbit ? kNoHasbit : hasbit / 8;
  568. }
  569. int MessageGenerator::HasWordIndex(const FieldDescriptor* field) const {
  570. int hasbit = HasBitIndex(field);
  571. return hasbit == kNoHasbit ? kNoHasbit : hasbit / 32;
  572. }
  573. void MessageGenerator::AddGenerators(
  574. std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
  575. std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators) {
  576. for (int i = 0; i < descriptor_->enum_type_count(); i++) {
  577. enum_generators->emplace_back(
  578. new EnumGenerator(descriptor_->enum_type(i), variables_, options_));
  579. enum_generators_.push_back(enum_generators->back().get());
  580. }
  581. for (int i = 0; i < descriptor_->extension_count(); i++) {
  582. extension_generators->emplace_back(
  583. new ExtensionGenerator(descriptor_->extension(i), options_));
  584. extension_generators_.push_back(extension_generators->back().get());
  585. }
  586. }
  587. void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) {
  588. Formatter format(printer, variables_);
  589. // optimized_fields_ does not contain fields where
  590. // field->real_containing_oneof()
  591. // so we need to iterate over those as well.
  592. //
  593. // We place the non-oneof fields in optimized_order_, as that controls the
  594. // order of the _has_bits_ entries and we want GDB's pretty printers to be
  595. // able to infer these indices from the k[FIELDNAME]FieldNumber order.
  596. std::vector<const FieldDescriptor*> ordered_fields;
  597. ordered_fields.reserve(descriptor_->field_count());
  598. ordered_fields.insert(ordered_fields.begin(), optimized_order_.begin(),
  599. optimized_order_.end());
  600. for (auto field : FieldRange(descriptor_)) {
  601. if (!field->real_containing_oneof() && !field->options().weak() &&
  602. !IsFieldStripped(field, options_)) {
  603. continue;
  604. }
  605. ordered_fields.push_back(field);
  606. }
  607. if (!ordered_fields.empty()) {
  608. format("enum : int {\n");
  609. for (auto field : ordered_fields) {
  610. Formatter::SaveState save(&format);
  611. std::map<std::string, std::string> vars;
  612. SetCommonFieldVariables(field, &vars, options_);
  613. format.AddMap(vars);
  614. format(" ${1$$2$$}$ = $number$,\n", field, FieldConstantName(field));
  615. }
  616. format("};\n");
  617. }
  618. for (auto field : ordered_fields) {
  619. PrintFieldComment(format, field);
  620. Formatter::SaveState save(&format);
  621. std::map<std::string, std::string> vars;
  622. SetCommonFieldVariables(field, &vars, options_);
  623. format.AddMap(vars);
  624. if (field->is_repeated()) {
  625. format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field,
  626. !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}");
  627. if (!IsFieldStripped(field, options_)) {
  628. format(
  629. "private:\n"
  630. "int ${1$_internal_$name$_size$}$() const;\n"
  631. "public:\n",
  632. field);
  633. }
  634. } else if (HasHasMethod(field)) {
  635. format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field,
  636. !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}");
  637. if (!IsFieldStripped(field, options_)) {
  638. format(
  639. "private:\n"
  640. "bool _internal_has_$name$() const;\n"
  641. "public:\n");
  642. }
  643. } else if (HasPrivateHasMethod(field)) {
  644. if (!IsFieldStripped(field, options_)) {
  645. format(
  646. "private:\n"
  647. "bool ${1$_internal_has_$name$$}$() const;\n"
  648. "public:\n",
  649. field);
  650. }
  651. }
  652. format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field,
  653. !IsFieldStripped(field, options_) ? ";" : "{__builtin_trap();}");
  654. // Generate type-specific accessor declarations.
  655. field_generators_.get(field).GenerateAccessorDeclarations(printer);
  656. format("\n");
  657. }
  658. if (descriptor_->extension_range_count() > 0) {
  659. // Generate accessors for extensions. We just call a macro located in
  660. // extension_set.h since the accessors about 80 lines of static code.
  661. format("$GOOGLE_PROTOBUF$_EXTENSION_ACCESSORS($classname$)\n");
  662. // Generate MessageSet specific APIs for proto2 MessageSet.
  663. // For testing purposes we don't check for bridge.MessageSet, so
  664. // we don't use IsProto2MessageSet
  665. if (descriptor_->options().message_set_wire_format() &&
  666. !options_.opensource_runtime && !options_.lite_implicit_weak_fields) {
  667. // Special-case MessageSet
  668. format("GOOGLE_PROTOBUF_EXTENSION_MESSAGE_SET_ACCESSORS($classname$)\n");
  669. }
  670. }
  671. for (auto oneof : OneOfRange(descriptor_)) {
  672. Formatter::SaveState saver(&format);
  673. format.Set("oneof_name", oneof->name());
  674. format.Set("camel_oneof_name", UnderscoresToCamelCase(oneof->name(), true));
  675. format(
  676. "void ${1$clear_$oneof_name$$}$();\n"
  677. "$camel_oneof_name$Case $oneof_name$_case() const;\n",
  678. oneof);
  679. }
  680. }
  681. void MessageGenerator::GenerateSingularFieldHasBits(
  682. const FieldDescriptor* field, Formatter format) {
  683. if (IsFieldStripped(field, options_)) {
  684. format(
  685. "inline bool $classname$::has_$name$() const { "
  686. "__builtin_trap(); }\n");
  687. return;
  688. }
  689. if (field->options().weak()) {
  690. format(
  691. "inline bool $classname$::has_$name$() const {\n"
  692. "$annotate_accessor$"
  693. " return _weak_field_map_.Has($number$);\n"
  694. "}\n");
  695. return;
  696. }
  697. if (HasHasbit(field)) {
  698. int has_bit_index = HasBitIndex(field);
  699. GOOGLE_CHECK_NE(has_bit_index, kNoHasbit);
  700. format.Set("has_array_index", has_bit_index / 32);
  701. format.Set("has_mask",
  702. strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  703. format(
  704. "inline bool $classname$::_internal_has_$name$() const {\n"
  705. " bool value = "
  706. "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n");
  707. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  708. !IsLazy(field, options_)) {
  709. // We maintain the invariant that for a submessage x, has_x() returning
  710. // true implies that x_ is not null. By giving this information to the
  711. // compiler, we allow it to eliminate unnecessary null checks later on.
  712. format(" PROTOBUF_ASSUME(!value || $name$_ != nullptr);\n");
  713. }
  714. format(
  715. " return value;\n"
  716. "}\n"
  717. "inline bool $classname$::has_$name$() const {\n"
  718. "$annotate_accessor$"
  719. " return _internal_has_$name$();\n"
  720. "}\n");
  721. } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  722. // Message fields have a has_$name$() method.
  723. if (IsLazy(field, options_)) {
  724. format(
  725. "inline bool $classname$::_internal_has_$name$() const {\n"
  726. " return !$name$_.IsCleared();\n"
  727. "}\n");
  728. } else {
  729. format(
  730. "inline bool $classname$::_internal_has_$name$() const {\n"
  731. " return this != internal_default_instance() "
  732. "&& $name$_ != nullptr;\n"
  733. "}\n");
  734. }
  735. format(
  736. "inline bool $classname$::has_$name$() const {\n"
  737. "$annotate_accessor$"
  738. " return _internal_has_$name$();\n"
  739. "}\n");
  740. }
  741. }
  742. void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) {
  743. Formatter format(printer, variables_);
  744. for (auto oneof : OneOfRange(descriptor_)) {
  745. format.Set("oneof_name", oneof->name());
  746. format.Set("oneof_index", oneof->index());
  747. format.Set("cap_oneof_name", ToUpper(oneof->name()));
  748. format(
  749. "inline bool $classname$::has_$oneof_name$() const {\n"
  750. " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
  751. "}\n"
  752. "inline void $classname$::clear_has_$oneof_name$() {\n"
  753. " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
  754. "}\n");
  755. }
  756. }
  757. void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field,
  758. const Formatter& format) {
  759. if (IsFieldStripped(field, options_)) {
  760. if (HasHasMethod(field)) {
  761. format(
  762. "inline bool $classname$::has_$name$() const { "
  763. "__builtin_trap(); }\n");
  764. }
  765. format(
  766. "inline void $classname$::set_has_$name$() { __builtin_trap(); "
  767. "}\n");
  768. return;
  769. }
  770. // Singular field in a oneof
  771. // N.B.: Without field presence, we do not use has-bits or generate
  772. // has_$name$() methods, but oneofs still have set_has_$name$().
  773. // Oneofs also have has_$name$() but only as a private helper
  774. // method, so that generated code is slightly cleaner (vs. comparing
  775. // _oneof_case_[index] against a constant everywhere).
  776. //
  777. // If has_$name$() is private, there is no need to add an internal accessor.
  778. // Only annotate public accessors.
  779. if (HasHasMethod(field)) {
  780. format(
  781. "inline bool $classname$::_internal_has_$name$() const {\n"
  782. " return $oneof_name$_case() == k$field_name$;\n"
  783. "}\n"
  784. "inline bool $classname$::has_$name$() const {\n"
  785. "$annotate_accessor$"
  786. " return _internal_has_$name$();\n"
  787. "}\n");
  788. } else if (HasPrivateHasMethod(field)) {
  789. format(
  790. "inline bool $classname$::_internal_has_$name$() const {\n"
  791. " return $oneof_name$_case() == k$field_name$;\n"
  792. "}\n");
  793. }
  794. // set_has_$name$() for oneof fields is always private; hence should not be
  795. // annotated.
  796. format(
  797. "inline void $classname$::set_has_$name$() {\n"
  798. " _oneof_case_[$oneof_index$] = k$field_name$;\n"
  799. "}\n");
  800. }
  801. void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field,
  802. bool is_inline, Formatter format) {
  803. if (IsFieldStripped(field, options_)) {
  804. format("void $classname$::clear_$name$() { __builtin_trap(); }\n");
  805. return;
  806. }
  807. // Generate clear_$name$().
  808. if (is_inline) {
  809. format("inline ");
  810. }
  811. format(
  812. "void $classname$::clear_$name$() {\n"
  813. "$annotate_accessor$");
  814. format.Indent();
  815. if (field->real_containing_oneof()) {
  816. // Clear this field only if it is the active field in this oneof,
  817. // otherwise ignore
  818. format("if (_internal_has_$name$()) {\n");
  819. format.Indent();
  820. field_generators_.get(field).GenerateClearingCode(format.printer());
  821. format("clear_has_$oneof_name$();\n");
  822. format.Outdent();
  823. format("}\n");
  824. } else {
  825. field_generators_.get(field).GenerateClearingCode(format.printer());
  826. if (HasHasbit(field)) {
  827. int has_bit_index = HasBitIndex(field);
  828. format.Set("has_array_index", has_bit_index / 32);
  829. format.Set("has_mask",
  830. strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  831. format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n");
  832. }
  833. }
  834. format.Outdent();
  835. format("}\n");
  836. }
  837. void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
  838. Formatter format(printer, variables_);
  839. format("// $classname$\n\n");
  840. for (auto field : FieldRange(descriptor_)) {
  841. PrintFieldComment(format, field);
  842. if (IsFieldStripped(field, options_)) {
  843. continue;
  844. }
  845. std::map<std::string, std::string> vars;
  846. SetCommonFieldVariables(field, &vars, options_);
  847. Formatter::SaveState saver(&format);
  848. format.AddMap(vars);
  849. // Generate has_$name$() or $name$_size().
  850. if (field->is_repeated()) {
  851. if (IsFieldStripped(field, options_)) {
  852. format(
  853. "inline int $classname$::$name$_size() const { "
  854. "__builtin_trap(); }\n");
  855. } else {
  856. format(
  857. "inline int $classname$::_internal_$name$_size() const {\n"
  858. " return $name$_$1$.size();\n"
  859. "}\n"
  860. "inline int $classname$::$name$_size() const {\n"
  861. "$annotate_accessor$"
  862. " return _internal_$name$_size();\n"
  863. "}\n",
  864. IsImplicitWeakField(field, options_, scc_analyzer_) &&
  865. field->message_type()
  866. ? ".weak"
  867. : "");
  868. }
  869. } else if (field->real_containing_oneof()) {
  870. format.Set("field_name", UnderscoresToCamelCase(field->name(), true));
  871. format.Set("oneof_name", field->containing_oneof()->name());
  872. format.Set("oneof_index",
  873. StrCat(field->containing_oneof()->index()));
  874. GenerateOneofMemberHasBits(field, format);
  875. } else {
  876. // Singular field.
  877. GenerateSingularFieldHasBits(field, format);
  878. }
  879. if (!IsCrossFileMaybeMap(field)) {
  880. GenerateFieldClear(field, true, format);
  881. }
  882. // Generate type-specific accessors.
  883. if (!IsFieldStripped(field, options_)) {
  884. field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
  885. }
  886. format("\n");
  887. }
  888. // Generate has_$name$() and clear_has_$name$() functions for oneofs.
  889. GenerateOneofHasBits(printer);
  890. }
  891. void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
  892. Formatter format(printer, variables_);
  893. format.Set("class_final", ShouldMarkClassAsFinal(descriptor_, options_)
  894. ? "PROTOBUF_FINAL"
  895. : "");
  896. if (IsMapEntryMessage(descriptor_)) {
  897. std::map<std::string, std::string> vars;
  898. CollectMapInfo(options_, descriptor_, &vars);
  899. vars["lite"] =
  900. HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite";
  901. format.AddMap(vars);
  902. format(
  903. "class $classname$ : public "
  904. "::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
  905. " $key_cpp$, $val_cpp$,\n"
  906. " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
  907. " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> {\n"
  908. "public:\n"
  909. " typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n"
  910. " $key_cpp$, $val_cpp$,\n"
  911. " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
  912. " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
  913. "SuperType;\n"
  914. " $classname$();\n"
  915. " explicit $classname$(::$proto_ns$::Arena* arena);\n"
  916. " void MergeFrom(const $classname$& other);\n"
  917. " static const $classname$* internal_default_instance() { return "
  918. "reinterpret_cast<const "
  919. "$classname$*>(&_$classname$_default_instance_); }\n");
  920. auto utf8_check = GetUtf8CheckMode(descriptor_->field(0), options_);
  921. if (descriptor_->field(0)->type() == FieldDescriptor::TYPE_STRING &&
  922. utf8_check != NONE) {
  923. if (utf8_check == STRICT) {
  924. format(
  925. " static bool ValidateKey(std::string* s) {\n"
  926. " return ::$proto_ns$::internal::WireFormatLite::"
  927. "VerifyUtf8String(s->data(), static_cast<int>(s->size()), "
  928. "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n"
  929. " }\n",
  930. descriptor_->field(0)->full_name());
  931. } else {
  932. GOOGLE_CHECK(utf8_check == VERIFY);
  933. format(
  934. " static bool ValidateKey(std::string* s) {\n"
  935. "#ifndef NDEBUG\n"
  936. " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
  937. " s->data(), static_cast<int>(s->size()), "
  938. "::$proto_ns$::internal::"
  939. "WireFormatLite::PARSE, \"$1$\");\n"
  940. "#endif\n"
  941. " return true;\n"
  942. " }\n",
  943. descriptor_->field(0)->full_name());
  944. }
  945. } else {
  946. format(" static bool ValidateKey(void*) { return true; }\n");
  947. }
  948. if (descriptor_->field(1)->type() == FieldDescriptor::TYPE_STRING &&
  949. utf8_check != NONE) {
  950. if (utf8_check == STRICT) {
  951. format(
  952. " static bool ValidateValue(std::string* s) {\n"
  953. " return ::$proto_ns$::internal::WireFormatLite::"
  954. "VerifyUtf8String(s->data(), static_cast<int>(s->size()), "
  955. "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n"
  956. " }\n",
  957. descriptor_->field(1)->full_name());
  958. } else {
  959. GOOGLE_CHECK(utf8_check = VERIFY);
  960. format(
  961. " static bool ValidateValue(std::string* s) {\n"
  962. "#ifndef NDEBUG\n"
  963. " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n"
  964. " s->data(), static_cast<int>(s->size()), "
  965. "::$proto_ns$::internal::"
  966. "WireFormatLite::PARSE, \"$1$\");\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. "void PackFrom(const ::$proto_ns$::Message& message) {\n"
  1105. " _any_metadata_.PackFrom(message);\n"
  1106. "}\n"
  1107. "void PackFrom(const ::$proto_ns$::Message& message,\n"
  1108. " ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
  1109. "type_url_prefix) {\n"
  1110. " _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. "void PackFrom(const T& message) {\n"
  1123. " _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. "void PackFrom(const T& message,\n"
  1129. " ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
  1130. "type_url_prefix) {\n"
  1131. " _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. "void PackFrom(const T& message) {\n"
  1143. " _any_metadata_.PackFrom(message);\n"
  1144. "}\n"
  1145. "template <typename T>\n"
  1146. "void PackFrom(const T& message,\n"
  1147. " ::PROTOBUF_NAMESPACE_ID::ConstStringParam "
  1148. "type_url_prefix) {\n"
  1149. " _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(&$first$_, 0, static_cast<size_t>(\n"
  2195. " reinterpret_cast<char*>(&$last$_) -\n"
  2196. " reinterpret_cast<char*>(&$first$_)) + sizeof($last$_));\n";
  2197. }
  2198. for (int i = 0; i < optimized_order_.size(); ++i) {
  2199. if (processed[i]) {
  2200. continue;
  2201. }
  2202. const FieldDescriptor* field = optimized_order_[i];
  2203. const auto it = runs.find(field);
  2204. // We only apply the memset technique to runs of more than one field, as
  2205. // assignment is better than memset for generated code clarity.
  2206. if (it != runs.end() && it->second > 1) {
  2207. // Use a memset, then skip run_length fields.
  2208. const size_t run_length = it->second;
  2209. const std::string first_field_name = FieldName(field);
  2210. const std::string last_field_name =
  2211. FieldName(optimized_order_[i + run_length - 1]);
  2212. format.Set("first", first_field_name);
  2213. format.Set("last", last_field_name);
  2214. format(pod_template.c_str());
  2215. i += run_length - 1;
  2216. // ++i at the top of the loop.
  2217. } else {
  2218. if (copy_constructor) {
  2219. field_generators_.get(field).GenerateCopyConstructorCode(printer);
  2220. } else {
  2221. field_generators_.get(field).GenerateConstructorCode(printer);
  2222. }
  2223. }
  2224. }
  2225. }
  2226. void MessageGenerator::GenerateStructors(io::Printer* printer) {
  2227. Formatter format(printer, variables_);
  2228. std::string superclass;
  2229. superclass = SuperClassName(descriptor_, options_);
  2230. std::string initializer_with_arena = superclass + "(arena)";
  2231. if (descriptor_->extension_range_count() > 0) {
  2232. initializer_with_arena += ",\n _extensions_(arena)";
  2233. }
  2234. // Initialize member variables with arena constructor.
  2235. for (auto field : optimized_order_) {
  2236. GOOGLE_DCHECK(!IsFieldStripped(field, options_));
  2237. bool has_arena_constructor = field->is_repeated();
  2238. if (!field->real_containing_oneof() &&
  2239. (IsLazy(field, options_) || IsStringPiece(field, options_))) {
  2240. has_arena_constructor = true;
  2241. }
  2242. if (has_arena_constructor) {
  2243. initializer_with_arena +=
  2244. std::string(",\n ") + FieldName(field) + std::string("_(arena)");
  2245. }
  2246. }
  2247. if (IsAnyMessage(descriptor_, options_)) {
  2248. initializer_with_arena += ",\n _any_metadata_(&type_url_, &value_)";
  2249. }
  2250. if (num_weak_fields_ > 0) {
  2251. initializer_with_arena += ", _weak_field_map_(arena)";
  2252. }
  2253. std::string initializer_null = superclass + "()";
  2254. if (IsAnyMessage(descriptor_, options_)) {
  2255. initializer_null += ", _any_metadata_(&type_url_, &value_)";
  2256. }
  2257. if (num_weak_fields_ > 0) {
  2258. initializer_null += ", _weak_field_map_(nullptr)";
  2259. }
  2260. format(
  2261. "$classname$::$classname$(::$proto_ns$::Arena* arena)\n"
  2262. " : $1$ {\n"
  2263. " SharedCtor();\n"
  2264. " RegisterArenaDtor(arena);\n"
  2265. " // @@protoc_insertion_point(arena_constructor:$full_name$)\n"
  2266. "}\n",
  2267. initializer_with_arena);
  2268. std::map<std::string, std::string> vars;
  2269. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2270. format.AddMap(vars);
  2271. // Generate the copy constructor.
  2272. if (UsingImplicitWeakFields(descriptor_->file(), options_)) {
  2273. // If we are in lite mode and using implicit weak fields, we generate a
  2274. // one-liner copy constructor that delegates to MergeFrom. This saves some
  2275. // code size and also cuts down on the complexity of implicit weak fields.
  2276. // We might eventually want to do this for all lite protos.
  2277. format(
  2278. "$classname$::$classname$(const $classname$& from)\n"
  2279. " : $classname$() {\n"
  2280. " MergeFrom(from);\n"
  2281. "}\n");
  2282. } else {
  2283. format(
  2284. "$classname$::$classname$(const $classname$& from)\n"
  2285. " : $superclass$()");
  2286. format.Indent();
  2287. format.Indent();
  2288. format.Indent();
  2289. if (!has_bit_indices_.empty()) {
  2290. format(",\n_has_bits_(from._has_bits_)");
  2291. }
  2292. std::vector<bool> processed(optimized_order_.size(), false);
  2293. for (int i = 0; i < optimized_order_.size(); i++) {
  2294. auto field = optimized_order_[i];
  2295. if (!(field->is_repeated() && !(field->is_map())) &&
  2296. !IsCord(field, options_)) {
  2297. continue;
  2298. }
  2299. processed[i] = true;
  2300. format(",\n$1$_(from.$1$_)", FieldName(field));
  2301. }
  2302. if (IsAnyMessage(descriptor_, options_)) {
  2303. format(",\n_any_metadata_(&type_url_, &value_)");
  2304. }
  2305. if (num_weak_fields_ > 0) {
  2306. format(",\n_weak_field_map_(from._weak_field_map_)");
  2307. }
  2308. format.Outdent();
  2309. format.Outdent();
  2310. format(" {\n");
  2311. format(
  2312. "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
  2313. "metadata_);\n");
  2314. if (descriptor_->extension_range_count() > 0) {
  2315. format("_extensions_.MergeFrom(from._extensions_);\n");
  2316. }
  2317. GenerateConstructorBody(printer, processed, true);
  2318. // Copy oneof fields. Oneof field requires oneof case check.
  2319. for (auto oneof : OneOfRange(descriptor_)) {
  2320. format(
  2321. "clear_has_$1$();\n"
  2322. "switch (from.$1$_case()) {\n",
  2323. oneof->name());
  2324. format.Indent();
  2325. for (auto field : FieldRange(oneof)) {
  2326. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  2327. format.Indent();
  2328. if (!IsFieldStripped(field, options_)) {
  2329. field_generators_.get(field).GenerateMergingCode(printer);
  2330. }
  2331. format("break;\n");
  2332. format.Outdent();
  2333. format("}\n");
  2334. }
  2335. format(
  2336. "case $1$_NOT_SET: {\n"
  2337. " break;\n"
  2338. "}\n",
  2339. ToUpper(oneof->name()));
  2340. format.Outdent();
  2341. format("}\n");
  2342. }
  2343. format.Outdent();
  2344. format(
  2345. " // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
  2346. "}\n"
  2347. "\n");
  2348. }
  2349. // Generate the shared constructor code.
  2350. GenerateSharedConstructorCode(printer);
  2351. // Generate the destructor.
  2352. format(
  2353. "$classname$::~$classname$() {\n"
  2354. " // @@protoc_insertion_point(destructor:$full_name$)\n"
  2355. " SharedDtor();\n"
  2356. " _internal_metadata_.Delete<$unknown_fields_type$>();\n"
  2357. "}\n"
  2358. "\n");
  2359. // Generate the shared destructor code.
  2360. GenerateSharedDestructorCode(printer);
  2361. // Generate the arena-specific destructor code.
  2362. GenerateArenaDestructorCode(printer);
  2363. // Generate SetCachedSize.
  2364. format(
  2365. "void $classname$::SetCachedSize(int size) const {\n"
  2366. " _cached_size_.Set(size);\n"
  2367. "}\n");
  2368. format(
  2369. "const $classname$& $classname$::default_instance() {\n"
  2370. " "
  2371. "::$proto_ns$::internal::InitSCC(&::$scc_info$.base)"
  2372. ";\n"
  2373. " return *internal_default_instance();\n"
  2374. "}\n\n");
  2375. }
  2376. void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) {
  2377. Formatter format(printer, variables_);
  2378. format(
  2379. "template<> "
  2380. "PROTOBUF_NOINLINE "
  2381. "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n"
  2382. " return Arena::CreateMessageInternal< $classtype$ >(arena);\n"
  2383. "}\n");
  2384. }
  2385. void MessageGenerator::GenerateClear(io::Printer* printer) {
  2386. Formatter format(printer, variables_);
  2387. // The maximum number of bytes we will memset to zero without checking their
  2388. // hasbit to see if a zero-init is necessary.
  2389. const int kMaxUnconditionalPrimitiveBytesClear = 4;
  2390. format(
  2391. "void $classname$::Clear() {\n"
  2392. "// @@protoc_insertion_point(message_clear_start:$full_name$)\n");
  2393. format.Indent();
  2394. format(
  2395. // TODO(jwb): It would be better to avoid emitting this if it is not used,
  2396. // rather than emitting a workaround for the resulting warning.
  2397. "$uint32$ cached_has_bits = 0;\n"
  2398. "// Prevent compiler warnings about cached_has_bits being unused\n"
  2399. "(void) cached_has_bits;\n\n");
  2400. if (descriptor_->extension_range_count() > 0) {
  2401. format("_extensions_.Clear();\n");
  2402. }
  2403. // Collect fields into chunks. Each chunk may have an if() condition that
  2404. // checks all hasbits in the chunk and skips it if none are set.
  2405. int zero_init_bytes = 0;
  2406. for (const auto& field : optimized_order_) {
  2407. if (CanInitializeByZeroing(field)) {
  2408. zero_init_bytes += EstimateAlignmentSize(field);
  2409. }
  2410. }
  2411. bool merge_zero_init = zero_init_bytes > kMaxUnconditionalPrimitiveBytesClear;
  2412. int chunk_count = 0;
  2413. std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
  2414. optimized_order_,
  2415. [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
  2416. chunk_count++;
  2417. // This predicate guarantees that there is only a single zero-init
  2418. // (memset) per chunk, and if present it will be at the beginning.
  2419. bool same = HasByteIndex(a) == HasByteIndex(b) &&
  2420. a->is_repeated() == b->is_repeated() &&
  2421. (CanInitializeByZeroing(a) == CanInitializeByZeroing(b) ||
  2422. (CanInitializeByZeroing(a) &&
  2423. (chunk_count == 1 || merge_zero_init)));
  2424. if (!same) chunk_count = 0;
  2425. return same;
  2426. });
  2427. ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
  2428. int cached_has_word_index = -1;
  2429. for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
  2430. std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
  2431. cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer);
  2432. const FieldDescriptor* memset_start = nullptr;
  2433. const FieldDescriptor* memset_end = nullptr;
  2434. bool saw_non_zero_init = false;
  2435. for (const auto& field : chunk) {
  2436. if (CanInitializeByZeroing(field)) {
  2437. GOOGLE_CHECK(!saw_non_zero_init);
  2438. if (!memset_start) memset_start = field;
  2439. memset_end = field;
  2440. } else {
  2441. saw_non_zero_init = true;
  2442. }
  2443. }
  2444. // Whether we wrap this chunk in:
  2445. // if (cached_has_bits & <chunk hasbits) { /* chunk. */ }
  2446. // We can omit the if() for chunk size 1, or if our fields do not have
  2447. // hasbits. I don't understand the rationale for the last part of the
  2448. // condition, but it matches the old logic.
  2449. const bool have_outer_if = HasBitIndex(chunk.front()) != kNoHasbit &&
  2450. chunk.size() > 1 &&
  2451. (memset_end != chunk.back() || merge_zero_init);
  2452. if (have_outer_if) {
  2453. // Emit an if() that will let us skip the whole chunk if none are set.
  2454. uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_);
  2455. std::string chunk_mask_str =
  2456. StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
  2457. // Check (up to) 8 has_bits at a time if we have more than one field in
  2458. // this chunk. Due to field layout ordering, we may check
  2459. // _has_bits_[last_chunk * 8 / 32] multiple times.
  2460. GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
  2461. GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
  2462. if (cached_has_word_index != HasWordIndex(chunk.front())) {
  2463. cached_has_word_index = HasWordIndex(chunk.front());
  2464. format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
  2465. }
  2466. format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
  2467. format.Indent();
  2468. }
  2469. if (memset_start) {
  2470. if (memset_start == memset_end) {
  2471. // For clarity, do not memset a single field.
  2472. field_generators_.get(memset_start)
  2473. .GenerateMessageClearingCode(printer);
  2474. } else {
  2475. format(
  2476. "::memset(&$1$_, 0, static_cast<size_t>(\n"
  2477. " reinterpret_cast<char*>(&$2$_) -\n"
  2478. " reinterpret_cast<char*>(&$1$_)) + sizeof($2$_));\n",
  2479. FieldName(memset_start), FieldName(memset_end));
  2480. }
  2481. }
  2482. // Clear all non-zero-initializable fields in the chunk.
  2483. for (const auto& field : chunk) {
  2484. if (CanInitializeByZeroing(field)) continue;
  2485. // It's faster to just overwrite primitive types, but we should only
  2486. // clear strings and messages if they were set.
  2487. //
  2488. // TODO(kenton): Let the CppFieldGenerator decide this somehow.
  2489. bool have_enclosing_if =
  2490. HasBitIndex(field) != kNoHasbit &&
  2491. (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
  2492. field->cpp_type() == FieldDescriptor::CPPTYPE_STRING);
  2493. if (have_enclosing_if) {
  2494. PrintPresenceCheck(format, field, has_bit_indices_, printer,
  2495. &cached_has_word_index);
  2496. }
  2497. field_generators_.get(field).GenerateMessageClearingCode(printer);
  2498. if (have_enclosing_if) {
  2499. format.Outdent();
  2500. format("}\n");
  2501. }
  2502. }
  2503. if (have_outer_if) {
  2504. format.Outdent();
  2505. format("}\n");
  2506. }
  2507. if (cold_skipper.OnEndChunk(chunk_index, printer)) {
  2508. // Reset here as it may have been updated in just closed if statement.
  2509. cached_has_word_index = -1;
  2510. }
  2511. }
  2512. // Step 4: Unions.
  2513. for (auto oneof : OneOfRange(descriptor_)) {
  2514. format("clear_$1$();\n", oneof->name());
  2515. }
  2516. if (num_weak_fields_) {
  2517. format("_weak_field_map_.ClearAll();\n");
  2518. }
  2519. if (!has_bit_indices_.empty()) {
  2520. // Step 5: Everything else.
  2521. format("_has_bits_.Clear();\n");
  2522. }
  2523. std::map<std::string, std::string> vars;
  2524. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2525. format.AddMap(vars);
  2526. format("_internal_metadata_.Clear<$unknown_fields_type$>();\n");
  2527. format.Outdent();
  2528. format("}\n");
  2529. }
  2530. void MessageGenerator::GenerateOneofClear(io::Printer* printer) {
  2531. // Generated function clears the active field and union case (e.g. foo_case_).
  2532. int i = 0;
  2533. for (auto oneof : OneOfRange(descriptor_)) {
  2534. Formatter format(printer, variables_);
  2535. format.Set("oneofname", oneof->name());
  2536. format(
  2537. "void $classname$::clear_$oneofname$() {\n"
  2538. "// @@protoc_insertion_point(one_of_clear_start:$full_name$)\n");
  2539. format.Indent();
  2540. format("switch ($oneofname$_case()) {\n");
  2541. format.Indent();
  2542. for (auto field : FieldRange(oneof)) {
  2543. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  2544. format.Indent();
  2545. // We clear only allocated objects in oneofs
  2546. if (!IsStringOrMessage(field) || IsFieldStripped(field, options_)) {
  2547. format("// No need to clear\n");
  2548. } else {
  2549. field_generators_.get(field).GenerateClearingCode(printer);
  2550. }
  2551. format("break;\n");
  2552. format.Outdent();
  2553. format("}\n");
  2554. }
  2555. format(
  2556. "case $1$_NOT_SET: {\n"
  2557. " break;\n"
  2558. "}\n",
  2559. ToUpper(oneof->name()));
  2560. format.Outdent();
  2561. format(
  2562. "}\n"
  2563. "_oneof_case_[$1$] = $2$_NOT_SET;\n",
  2564. i, ToUpper(oneof->name()));
  2565. format.Outdent();
  2566. format(
  2567. "}\n"
  2568. "\n");
  2569. i++;
  2570. }
  2571. }
  2572. void MessageGenerator::GenerateSwap(io::Printer* printer) {
  2573. Formatter format(printer, variables_);
  2574. format("void $classname$::InternalSwap($classname$* other) {\n");
  2575. format.Indent();
  2576. format("using std::swap;\n");
  2577. if (HasGeneratedMethods(descriptor_->file(), options_)) {
  2578. if (descriptor_->extension_range_count() > 0) {
  2579. format("_extensions_.Swap(&other->_extensions_);\n");
  2580. }
  2581. std::map<std::string, std::string> vars;
  2582. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2583. format.AddMap(vars);
  2584. format(
  2585. "_internal_metadata_.Swap<$unknown_fields_type$>(&other->_internal_"
  2586. "metadata_);\n");
  2587. if (!has_bit_indices_.empty()) {
  2588. for (int i = 0; i < HasBitsSize(); ++i) {
  2589. format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i);
  2590. }
  2591. }
  2592. // If possible, we swap several fields at once, including padding.
  2593. const RunMap runs =
  2594. FindRuns(optimized_order_, [this](const FieldDescriptor* field) {
  2595. return CanBeManipulatedAsRawBytes(field, options_);
  2596. });
  2597. for (int i = 0; i < optimized_order_.size(); ++i) {
  2598. const FieldDescriptor* field = optimized_order_[i];
  2599. const auto it = runs.find(field);
  2600. // We only apply the memswap technique to runs of more than one field, as
  2601. // `swap(field_, other.field_)` is better than
  2602. // `memswap<...>(&field_, &other.field_)` for generated code readability.
  2603. if (it != runs.end() && it->second > 1) {
  2604. // Use a memswap, then skip run_length fields.
  2605. const size_t run_length = it->second;
  2606. const std::string first_field_name = FieldName(field);
  2607. const std::string last_field_name =
  2608. FieldName(optimized_order_[i + run_length - 1]);
  2609. format.Set("first", first_field_name);
  2610. format.Set("last", last_field_name);
  2611. format(
  2612. "::PROTOBUF_NAMESPACE_ID::internal::memswap<\n"
  2613. " PROTOBUF_FIELD_OFFSET($classname$, $last$_)\n"
  2614. " + sizeof($classname$::$last$_)\n"
  2615. " - PROTOBUF_FIELD_OFFSET($classname$, $first$_)>(\n"
  2616. " reinterpret_cast<char*>(&$first$_),\n"
  2617. " reinterpret_cast<char*>(&other->$first$_));\n");
  2618. i += run_length - 1;
  2619. // ++i at the top of the loop.
  2620. } else {
  2621. field_generators_.get(field).GenerateSwappingCode(printer);
  2622. }
  2623. }
  2624. for (auto oneof : OneOfRange(descriptor_)) {
  2625. format("swap($1$_, other->$1$_);\n", oneof->name());
  2626. }
  2627. for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
  2628. format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i);
  2629. }
  2630. if (num_weak_fields_) {
  2631. format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n");
  2632. }
  2633. } else {
  2634. format("GetReflection()->Swap(this, other);");
  2635. }
  2636. format.Outdent();
  2637. format("}\n");
  2638. }
  2639. void MessageGenerator::GenerateMergeFrom(io::Printer* printer) {
  2640. Formatter format(printer, variables_);
  2641. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  2642. // Generate the generalized MergeFrom (aka that which takes in the Message
  2643. // base class as a parameter).
  2644. format(
  2645. "void $classname$::MergeFrom(const ::$proto_ns$::Message& from) {\n"
  2646. "// @@protoc_insertion_point(generalized_merge_from_start:"
  2647. "$full_name$)\n"
  2648. " $DCHK$_NE(&from, this);\n");
  2649. format.Indent();
  2650. // Cast the message to the proper type. If we find that the message is
  2651. // *not* of the proper type, we can still call Merge via the reflection
  2652. // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
  2653. // for each message.
  2654. format(
  2655. "const $classname$* source =\n"
  2656. " ::$proto_ns$::DynamicCastToGenerated<$classname$>(\n"
  2657. " &from);\n"
  2658. "if (source == nullptr) {\n"
  2659. "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
  2660. "$full_name$)\n"
  2661. " ::$proto_ns$::internal::ReflectionOps::Merge(from, this);\n"
  2662. "} else {\n"
  2663. "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
  2664. "$full_name$)\n"
  2665. " MergeFrom(*source);\n"
  2666. "}\n");
  2667. format.Outdent();
  2668. format("}\n");
  2669. } else {
  2670. // Generate CheckTypeAndMergeFrom().
  2671. format(
  2672. "void $classname$::CheckTypeAndMergeFrom(\n"
  2673. " const ::$proto_ns$::MessageLite& from) {\n"
  2674. " MergeFrom(*::$proto_ns$::internal::DownCast<const $classname$*>(\n"
  2675. " &from));\n"
  2676. "}\n");
  2677. }
  2678. }
  2679. void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) {
  2680. // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
  2681. Formatter format(printer, variables_);
  2682. format(
  2683. "void $classname$::MergeFrom(const $classname$& from) {\n"
  2684. "// @@protoc_insertion_point(class_specific_merge_from_start:"
  2685. "$full_name$)\n"
  2686. " $DCHK$_NE(&from, this);\n");
  2687. format.Indent();
  2688. if (descriptor_->extension_range_count() > 0) {
  2689. format("_extensions_.MergeFrom(from._extensions_);\n");
  2690. }
  2691. std::map<std::string, std::string> vars;
  2692. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2693. format.AddMap(vars);
  2694. format(
  2695. "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_"
  2696. "metadata_);\n"
  2697. "$uint32$ cached_has_bits = 0;\n"
  2698. "(void) cached_has_bits;\n\n");
  2699. std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
  2700. optimized_order_,
  2701. [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
  2702. return HasByteIndex(a) == HasByteIndex(b);
  2703. });
  2704. ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
  2705. // cached_has_word_index maintains that:
  2706. // cached_has_bits = from._has_bits_[cached_has_word_index]
  2707. // for cached_has_word_index >= 0
  2708. int cached_has_word_index = -1;
  2709. for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
  2710. const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
  2711. bool have_outer_if =
  2712. chunk.size() > 1 && HasByteIndex(chunk.front()) != kNoHasbit;
  2713. cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "from.",
  2714. printer);
  2715. if (have_outer_if) {
  2716. // Emit an if() that will let us skip the whole chunk if none are set.
  2717. uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_);
  2718. std::string chunk_mask_str =
  2719. StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
  2720. // Check (up to) 8 has_bits at a time if we have more than one field in
  2721. // this chunk. Due to field layout ordering, we may check
  2722. // _has_bits_[last_chunk * 8 / 32] multiple times.
  2723. GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
  2724. GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
  2725. if (cached_has_word_index != HasWordIndex(chunk.front())) {
  2726. cached_has_word_index = HasWordIndex(chunk.front());
  2727. format("cached_has_bits = from._has_bits_[$1$];\n",
  2728. cached_has_word_index);
  2729. }
  2730. format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
  2731. format.Indent();
  2732. }
  2733. // Go back and emit merging code for each of the fields we processed.
  2734. bool deferred_has_bit_changes = false;
  2735. for (const auto field : chunk) {
  2736. const FieldGenerator& generator = field_generators_.get(field);
  2737. if (field->is_repeated()) {
  2738. generator.GenerateMergingCode(printer);
  2739. } else if (field->is_optional() && !HasHasbit(field)) {
  2740. // Merge semantics without true field presence: primitive fields are
  2741. // merged only if non-zero (numeric) or non-empty (string).
  2742. bool have_enclosing_if =
  2743. EmitFieldNonDefaultCondition(printer, "from.", field);
  2744. generator.GenerateMergingCode(printer);
  2745. if (have_enclosing_if) {
  2746. format.Outdent();
  2747. format("}\n");
  2748. }
  2749. } else if (field->options().weak() ||
  2750. cached_has_word_index != HasWordIndex(field)) {
  2751. // Check hasbit, not using cached bits.
  2752. GOOGLE_CHECK(HasHasbit(field));
  2753. format("if (from._internal_has_$1$()) {\n", FieldName(field));
  2754. format.Indent();
  2755. generator.GenerateMergingCode(printer);
  2756. format.Outdent();
  2757. format("}\n");
  2758. } else {
  2759. // Check hasbit, using cached bits.
  2760. GOOGLE_CHECK(HasHasbit(field));
  2761. int has_bit_index = has_bit_indices_[field->index()];
  2762. const std::string mask = StrCat(
  2763. strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  2764. format("if (cached_has_bits & 0x$1$u) {\n", mask);
  2765. format.Indent();
  2766. if (have_outer_if && IsPOD(field)) {
  2767. // Defer hasbit modification until the end of chunk.
  2768. // This can reduce the number of loads/stores by up to 7 per 8 fields.
  2769. deferred_has_bit_changes = true;
  2770. generator.GenerateCopyConstructorCode(printer);
  2771. } else {
  2772. generator.GenerateMergingCode(printer);
  2773. }
  2774. format.Outdent();
  2775. format("}\n");
  2776. }
  2777. }
  2778. if (have_outer_if) {
  2779. if (deferred_has_bit_changes) {
  2780. // Flush the has bits for the primitives we deferred.
  2781. GOOGLE_CHECK_LE(0, cached_has_word_index);
  2782. format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index);
  2783. }
  2784. format.Outdent();
  2785. format("}\n");
  2786. }
  2787. if (cold_skipper.OnEndChunk(chunk_index, printer)) {
  2788. // Reset here as it may have been updated in just closed if statement.
  2789. cached_has_word_index = -1;
  2790. }
  2791. }
  2792. // Merge oneof fields. Oneof field requires oneof case check.
  2793. for (auto oneof : OneOfRange(descriptor_)) {
  2794. format("switch (from.$1$_case()) {\n", oneof->name());
  2795. format.Indent();
  2796. for (auto field : FieldRange(oneof)) {
  2797. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  2798. format.Indent();
  2799. if (!IsFieldStripped(field, options_)) {
  2800. field_generators_.get(field).GenerateMergingCode(printer);
  2801. }
  2802. format("break;\n");
  2803. format.Outdent();
  2804. format("}\n");
  2805. }
  2806. format(
  2807. "case $1$_NOT_SET: {\n"
  2808. " break;\n"
  2809. "}\n",
  2810. ToUpper(oneof->name()));
  2811. format.Outdent();
  2812. format("}\n");
  2813. }
  2814. if (num_weak_fields_) {
  2815. format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n");
  2816. }
  2817. format.Outdent();
  2818. format("}\n");
  2819. }
  2820. void MessageGenerator::GenerateCopyFrom(io::Printer* printer) {
  2821. Formatter format(printer, variables_);
  2822. if (HasDescriptorMethods(descriptor_->file(), options_)) {
  2823. // Generate the generalized CopyFrom (aka that which takes in the Message
  2824. // base class as a parameter).
  2825. format(
  2826. "void $classname$::CopyFrom(const ::$proto_ns$::Message& from) {\n"
  2827. "// @@protoc_insertion_point(generalized_copy_from_start:"
  2828. "$full_name$)\n");
  2829. format.Indent();
  2830. format("if (&from == this) return;\n");
  2831. if (!options_.opensource_runtime) {
  2832. // This check is disabled in the opensource release because we're
  2833. // concerned that many users do not define NDEBUG in their release
  2834. // builds.
  2835. format(
  2836. "#ifndef NDEBUG\n"
  2837. "size_t from_size = from.ByteSizeLong();\n"
  2838. "#endif\n"
  2839. "Clear();\n"
  2840. "#ifndef NDEBUG\n"
  2841. "$CHK$_EQ(from_size, from.ByteSizeLong())\n"
  2842. " << \"Source of CopyFrom changed when clearing target. Either \"\n"
  2843. " << \"source is a nested message in target (not allowed), or \"\n"
  2844. " << \"another thread is modifying the source.\";\n"
  2845. "#endif\n");
  2846. } else {
  2847. format("Clear();\n");
  2848. }
  2849. format("MergeFrom(from);\n");
  2850. format.Outdent();
  2851. format("}\n\n");
  2852. }
  2853. // Generate the class-specific CopyFrom.
  2854. format(
  2855. "void $classname$::CopyFrom(const $classname$& from) {\n"
  2856. "// @@protoc_insertion_point(class_specific_copy_from_start:"
  2857. "$full_name$)\n");
  2858. format.Indent();
  2859. format("if (&from == this) return;\n");
  2860. if (!options_.opensource_runtime) {
  2861. // This check is disabled in the opensource release because we're
  2862. // concerned that many users do not define NDEBUG in their release builds.
  2863. format(
  2864. "#ifndef NDEBUG\n"
  2865. "size_t from_size = from.ByteSizeLong();\n"
  2866. "#endif\n"
  2867. "Clear();\n"
  2868. "#ifndef NDEBUG\n"
  2869. "$CHK$_EQ(from_size, from.ByteSizeLong())\n"
  2870. " << \"Source of CopyFrom changed when clearing target. Either \"\n"
  2871. " << \"source is a nested message in target (not allowed), or \"\n"
  2872. " << \"another thread is modifying the source.\";\n"
  2873. "#endif\n");
  2874. } else {
  2875. format("Clear();\n");
  2876. }
  2877. format("MergeFrom(from);\n");
  2878. format.Outdent();
  2879. format("}\n");
  2880. }
  2881. void MessageGenerator::GenerateMergeFromCodedStream(io::Printer* printer) {
  2882. std::map<std::string, std::string> vars = variables_;
  2883. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2884. Formatter format(printer, vars);
  2885. if (descriptor_->options().message_set_wire_format()) {
  2886. // Special-case MessageSet.
  2887. format(
  2888. "const char* $classname$::_InternalParse(const char* ptr,\n"
  2889. " ::$proto_ns$::internal::ParseContext* ctx) {\n"
  2890. " return _extensions_.ParseMessageSet(ptr, \n"
  2891. " internal_default_instance(), &_internal_metadata_, ctx);\n"
  2892. "}\n");
  2893. return;
  2894. }
  2895. GenerateParserLoop(descriptor_, max_has_bit_index_, options_, scc_analyzer_,
  2896. printer);
  2897. }
  2898. void MessageGenerator::GenerateSerializeOneofFields(
  2899. io::Printer* printer, const std::vector<const FieldDescriptor*>& fields) {
  2900. Formatter format(printer, variables_);
  2901. GOOGLE_CHECK(!fields.empty());
  2902. if (fields.size() == 1) {
  2903. GenerateSerializeOneField(printer, fields[0], -1);
  2904. return;
  2905. }
  2906. // We have multiple mutually exclusive choices. Emit a switch statement.
  2907. const OneofDescriptor* oneof = fields[0]->containing_oneof();
  2908. format("switch ($1$_case()) {\n", oneof->name());
  2909. format.Indent();
  2910. for (auto field : fields) {
  2911. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  2912. format.Indent();
  2913. field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
  2914. printer);
  2915. format("break;\n");
  2916. format.Outdent();
  2917. format("}\n");
  2918. }
  2919. format.Outdent();
  2920. // Doing nothing is an option.
  2921. format(
  2922. " default: ;\n"
  2923. "}\n");
  2924. }
  2925. void MessageGenerator::GenerateSerializeOneField(io::Printer* printer,
  2926. const FieldDescriptor* field,
  2927. int cached_has_bits_index) {
  2928. Formatter format(printer, variables_);
  2929. if (!field->options().weak()) {
  2930. // For weakfields, PrintFieldComment is called during iteration.
  2931. PrintFieldComment(format, field);
  2932. }
  2933. bool have_enclosing_if = false;
  2934. if (field->options().weak()) {
  2935. } else if (HasHasbit(field)) {
  2936. // Attempt to use the state of cached_has_bits, if possible.
  2937. int has_bit_index = HasBitIndex(field);
  2938. if (cached_has_bits_index == has_bit_index / 32) {
  2939. const std::string mask =
  2940. StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8));
  2941. format("if (cached_has_bits & 0x$1$u) {\n", mask);
  2942. } else {
  2943. format("if (_internal_has_$1$()) {\n", FieldName(field));
  2944. }
  2945. format.Indent();
  2946. have_enclosing_if = true;
  2947. } else if (field->is_optional() && !HasHasbit(field)) {
  2948. have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field);
  2949. }
  2950. field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(printer);
  2951. if (have_enclosing_if) {
  2952. format.Outdent();
  2953. format("}\n");
  2954. }
  2955. format("\n");
  2956. }
  2957. void MessageGenerator::GenerateSerializeOneExtensionRange(
  2958. io::Printer* printer, const Descriptor::ExtensionRange* range) {
  2959. std::map<std::string, std::string> vars = variables_;
  2960. vars["start"] = StrCat(range->start);
  2961. vars["end"] = StrCat(range->end);
  2962. Formatter format(printer, vars);
  2963. format("// Extension range [$start$, $end$)\n");
  2964. format(
  2965. "target = _extensions_._InternalSerialize(\n"
  2966. " $start$, $end$, target, stream);\n\n");
  2967. }
  2968. void MessageGenerator::GenerateSerializeWithCachedSizesToArray(
  2969. io::Printer* printer) {
  2970. Formatter format(printer, variables_);
  2971. if (descriptor_->options().message_set_wire_format()) {
  2972. // Special-case MessageSet.
  2973. format(
  2974. "$uint8$* $classname$::_InternalSerialize(\n"
  2975. " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
  2976. "const {\n"
  2977. " target = _extensions_."
  2978. "InternalSerializeMessageSetWithCachedSizesToArray(target, stream);\n");
  2979. std::map<std::string, std::string> vars;
  2980. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  2981. format.AddMap(vars);
  2982. format(
  2983. " target = ::$proto_ns$::internal::"
  2984. "InternalSerializeUnknownMessageSetItemsToArray(\n"
  2985. " $unknown_fields$, target, stream);\n");
  2986. format(
  2987. " return target;\n"
  2988. "}\n");
  2989. return;
  2990. }
  2991. format(
  2992. "$uint8$* $classname$::_InternalSerialize(\n"
  2993. " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) "
  2994. "const {\n");
  2995. format.Indent();
  2996. format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n");
  2997. if (!ShouldSerializeInOrder(descriptor_, options_)) {
  2998. format.Outdent();
  2999. format("#ifdef NDEBUG\n");
  3000. format.Indent();
  3001. }
  3002. GenerateSerializeWithCachedSizesBody(printer);
  3003. if (!ShouldSerializeInOrder(descriptor_, options_)) {
  3004. format.Outdent();
  3005. format("#else // NDEBUG\n");
  3006. format.Indent();
  3007. GenerateSerializeWithCachedSizesBodyShuffled(printer);
  3008. format.Outdent();
  3009. format("#endif // !NDEBUG\n");
  3010. format.Indent();
  3011. }
  3012. format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n");
  3013. format.Outdent();
  3014. format(
  3015. " return target;\n"
  3016. "}\n");
  3017. }
  3018. void MessageGenerator::GenerateSerializeWithCachedSizesBody(
  3019. io::Printer* printer) {
  3020. Formatter format(printer, variables_);
  3021. // If there are multiple fields in a row from the same oneof then we
  3022. // coalesce them and emit a switch statement. This is more efficient
  3023. // because it lets the C++ compiler know this is a "at most one can happen"
  3024. // situation. If we emitted "if (has_x()) ...; if (has_y()) ..." the C++
  3025. // compiler's emitted code might check has_y() even when has_x() is true.
  3026. class LazySerializerEmitter {
  3027. public:
  3028. LazySerializerEmitter(MessageGenerator* mg, io::Printer* printer)
  3029. : mg_(mg),
  3030. format_(printer),
  3031. eager_(!HasFieldPresence(mg->descriptor_->file())),
  3032. cached_has_bit_index_(kNoHasbit) {}
  3033. ~LazySerializerEmitter() { Flush(); }
  3034. // If conditions allow, try to accumulate a run of fields from the same
  3035. // oneof, and handle them at the next Flush().
  3036. void Emit(const FieldDescriptor* field) {
  3037. if (eager_ || MustFlush(field)) {
  3038. Flush();
  3039. }
  3040. if (!field->real_containing_oneof()) {
  3041. // TODO(ckennelly): Defer non-oneof fields similarly to oneof fields.
  3042. if (!field->options().weak() && !field->is_repeated() && !eager_) {
  3043. // We speculatively load the entire _has_bits_[index] contents, even
  3044. // if it is for only one field. Deferring non-oneof emitting would
  3045. // allow us to determine whether this is going to be useful.
  3046. int has_bit_index = mg_->has_bit_indices_[field->index()];
  3047. if (cached_has_bit_index_ != has_bit_index / 32) {
  3048. // Reload.
  3049. int new_index = has_bit_index / 32;
  3050. format_("cached_has_bits = _has_bits_[$1$];\n", new_index);
  3051. cached_has_bit_index_ = new_index;
  3052. }
  3053. }
  3054. mg_->GenerateSerializeOneField(format_.printer(), field,
  3055. cached_has_bit_index_);
  3056. } else {
  3057. v_.push_back(field);
  3058. }
  3059. }
  3060. void Flush() {
  3061. if (!v_.empty()) {
  3062. mg_->GenerateSerializeOneofFields(format_.printer(), v_);
  3063. v_.clear();
  3064. }
  3065. }
  3066. private:
  3067. // If we have multiple fields in v_ then they all must be from the same
  3068. // oneof. Would adding field to v_ break that invariant?
  3069. bool MustFlush(const FieldDescriptor* field) {
  3070. return !v_.empty() &&
  3071. v_[0]->containing_oneof() != field->containing_oneof();
  3072. }
  3073. MessageGenerator* mg_;
  3074. Formatter format_;
  3075. const bool eager_;
  3076. std::vector<const FieldDescriptor*> v_;
  3077. // cached_has_bit_index_ maintains that:
  3078. // cached_has_bits = from._has_bits_[cached_has_bit_index_]
  3079. // for cached_has_bit_index_ >= 0
  3080. int cached_has_bit_index_;
  3081. };
  3082. std::vector<const FieldDescriptor*> ordered_fields =
  3083. SortFieldsByNumber(descriptor_);
  3084. std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
  3085. sorted_extensions.reserve(descriptor_->extension_range_count());
  3086. for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
  3087. sorted_extensions.push_back(descriptor_->extension_range(i));
  3088. }
  3089. std::sort(sorted_extensions.begin(), sorted_extensions.end(),
  3090. ExtensionRangeSorter());
  3091. if (num_weak_fields_) {
  3092. format(
  3093. "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
  3094. "_weak_field_map_);\n");
  3095. }
  3096. format(
  3097. "$uint32$ cached_has_bits = 0;\n"
  3098. "(void) cached_has_bits;\n\n");
  3099. // Merge the fields and the extension ranges, both sorted by field number.
  3100. {
  3101. LazySerializerEmitter e(this, printer);
  3102. const FieldDescriptor* last_weak_field = nullptr;
  3103. int i, j;
  3104. for (i = 0, j = 0;
  3105. i < ordered_fields.size() || j < sorted_extensions.size();) {
  3106. if ((j == sorted_extensions.size()) ||
  3107. (i < descriptor_->field_count() &&
  3108. ordered_fields[i]->number() < sorted_extensions[j]->start)) {
  3109. const FieldDescriptor* field = ordered_fields[i++];
  3110. if (IsFieldStripped(field, options_)) {
  3111. continue;
  3112. }
  3113. if (field->options().weak()) {
  3114. if (last_weak_field == nullptr ||
  3115. last_weak_field->number() < field->number()) {
  3116. last_weak_field = field;
  3117. }
  3118. PrintFieldComment(format, field);
  3119. } else {
  3120. if (last_weak_field != nullptr) {
  3121. e.Emit(last_weak_field);
  3122. last_weak_field = nullptr;
  3123. }
  3124. e.Emit(field);
  3125. }
  3126. } else {
  3127. if (last_weak_field != nullptr) {
  3128. e.Emit(last_weak_field);
  3129. last_weak_field = nullptr;
  3130. }
  3131. e.Flush();
  3132. GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
  3133. }
  3134. }
  3135. if (last_weak_field != nullptr) {
  3136. e.Emit(last_weak_field);
  3137. }
  3138. }
  3139. std::map<std::string, std::string> vars;
  3140. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3141. format.AddMap(vars);
  3142. format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
  3143. format.Indent();
  3144. if (UseUnknownFieldSet(descriptor_->file(), options_)) {
  3145. format(
  3146. "target = "
  3147. "::$proto_ns$::internal::WireFormat::"
  3148. "InternalSerializeUnknownFieldsToArray(\n"
  3149. " $unknown_fields$, target, stream);\n");
  3150. } else {
  3151. format(
  3152. "target = stream->WriteRaw($unknown_fields$.data(),\n"
  3153. " static_cast<int>($unknown_fields$.size()), target);\n");
  3154. }
  3155. format.Outdent();
  3156. format("}\n");
  3157. }
  3158. void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled(
  3159. io::Printer* printer) {
  3160. Formatter format(printer, variables_);
  3161. std::vector<const FieldDescriptor*> ordered_fields =
  3162. SortFieldsByNumber(descriptor_);
  3163. ordered_fields.erase(
  3164. std::remove_if(ordered_fields.begin(), ordered_fields.end(),
  3165. [this](const FieldDescriptor* f) {
  3166. return !IsFieldUsed(f, options_);
  3167. }),
  3168. ordered_fields.end());
  3169. std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
  3170. sorted_extensions.reserve(descriptor_->extension_range_count());
  3171. for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
  3172. sorted_extensions.push_back(descriptor_->extension_range(i));
  3173. }
  3174. std::sort(sorted_extensions.begin(), sorted_extensions.end(),
  3175. ExtensionRangeSorter());
  3176. int num_fields = ordered_fields.size() + sorted_extensions.size();
  3177. constexpr int kLargePrime = 1000003;
  3178. GOOGLE_CHECK_LT(num_fields, kLargePrime)
  3179. << "Prime offset must be greater than the number of fields to ensure "
  3180. "those are coprime.";
  3181. if (num_weak_fields_) {
  3182. format(
  3183. "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer("
  3184. "_weak_field_map_);\n");
  3185. }
  3186. format(
  3187. "static const int kStart = GetInvariantPerBuild($1$UL) % $2$;\n"
  3188. "bool first_pass = true;\n"
  3189. "for (int i = kStart; i != kStart || first_pass; i = ((i + $3$) % $2$)) "
  3190. "{\n",
  3191. 0,
  3192. num_fields, kLargePrime);
  3193. format.Indent();
  3194. format("switch(i) {\n");
  3195. format.Indent();
  3196. bool first_pass_set = false;
  3197. int index = 0;
  3198. for (const auto* f : ordered_fields) {
  3199. format("case $1$: {\n", index++);
  3200. format.Indent();
  3201. if (!first_pass_set) {
  3202. first_pass_set = true;
  3203. format("first_pass = false;\n");
  3204. }
  3205. GenerateSerializeOneField(printer, f, -1);
  3206. format("break;\n");
  3207. format.Outdent();
  3208. format("}\n");
  3209. }
  3210. for (const auto* r : sorted_extensions) {
  3211. format("case $1$: {\n", index++);
  3212. format.Indent();
  3213. if (!first_pass_set) {
  3214. first_pass_set = true;
  3215. format("first_pass = false;\n");
  3216. }
  3217. GenerateSerializeOneExtensionRange(printer, r);
  3218. format("break;\n");
  3219. format.Outdent();
  3220. format("}\n");
  3221. }
  3222. format(
  3223. "default: {\n"
  3224. " $DCHK$(false) << \"Unexpected index: \" << i;\n"
  3225. "}\n");
  3226. format.Outdent();
  3227. format("}\n");
  3228. format.Outdent();
  3229. format("}\n");
  3230. std::map<std::string, std::string> vars;
  3231. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3232. format.AddMap(vars);
  3233. format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
  3234. format.Indent();
  3235. if (UseUnknownFieldSet(descriptor_->file(), options_)) {
  3236. format(
  3237. "target = "
  3238. "::$proto_ns$::internal::WireFormat::"
  3239. "InternalSerializeUnknownFieldsToArray(\n"
  3240. " $unknown_fields$, target, stream);\n");
  3241. } else {
  3242. format(
  3243. "target = stream->WriteRaw($unknown_fields$.data(),\n"
  3244. " static_cast<int>($unknown_fields$.size()), target);\n");
  3245. }
  3246. format.Outdent();
  3247. format("}\n");
  3248. }
  3249. std::vector<uint32> MessageGenerator::RequiredFieldsBitMask() const {
  3250. const int array_size = HasBitsSize();
  3251. std::vector<uint32> masks(array_size, 0);
  3252. for (auto field : FieldRange(descriptor_)) {
  3253. if (!field->is_required()) {
  3254. continue;
  3255. }
  3256. const int has_bit_index = has_bit_indices_[field->index()];
  3257. masks[has_bit_index / 32] |= static_cast<uint32>(1) << (has_bit_index % 32);
  3258. }
  3259. return masks;
  3260. }
  3261. void MessageGenerator::GenerateByteSize(io::Printer* printer) {
  3262. Formatter format(printer, variables_);
  3263. if (descriptor_->options().message_set_wire_format()) {
  3264. // Special-case MessageSet.
  3265. std::map<std::string, std::string> vars;
  3266. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3267. format.AddMap(vars);
  3268. format(
  3269. "size_t $classname$::ByteSizeLong() const {\n"
  3270. "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
  3271. " size_t total_size = _extensions_.MessageSetByteSize();\n"
  3272. " if ($have_unknown_fields$) {\n"
  3273. " total_size += ::$proto_ns$::internal::\n"
  3274. " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n"
  3275. " }\n"
  3276. " int cached_size = "
  3277. "::$proto_ns$::internal::ToCachedSize(total_size);\n"
  3278. " SetCachedSize(cached_size);\n"
  3279. " return total_size;\n"
  3280. "}\n");
  3281. return;
  3282. }
  3283. if (num_required_fields_ > 1) {
  3284. // Emit a function (rarely used, we hope) that handles the required fields
  3285. // by checking for each one individually.
  3286. format(
  3287. "size_t $classname$::RequiredFieldsByteSizeFallback() const {\n"
  3288. "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
  3289. "$full_name$)\n");
  3290. format.Indent();
  3291. format("size_t total_size = 0;\n");
  3292. for (auto field : optimized_order_) {
  3293. if (field->is_required()) {
  3294. format(
  3295. "\n"
  3296. "if (_internal_has_$1$()) {\n",
  3297. FieldName(field));
  3298. format.Indent();
  3299. PrintFieldComment(format, field);
  3300. field_generators_.get(field).GenerateByteSize(printer);
  3301. format.Outdent();
  3302. format("}\n");
  3303. }
  3304. }
  3305. format(
  3306. "\n"
  3307. "return total_size;\n");
  3308. format.Outdent();
  3309. format("}\n");
  3310. }
  3311. format(
  3312. "size_t $classname$::ByteSizeLong() const {\n"
  3313. "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n");
  3314. format.Indent();
  3315. format(
  3316. "size_t total_size = 0;\n"
  3317. "\n");
  3318. if (descriptor_->extension_range_count() > 0) {
  3319. format(
  3320. "total_size += _extensions_.ByteSize();\n"
  3321. "\n");
  3322. }
  3323. std::map<std::string, std::string> vars;
  3324. SetUnknkownFieldsVariable(descriptor_, options_, &vars);
  3325. format.AddMap(vars);
  3326. // Handle required fields (if any). We expect all of them to be
  3327. // present, so emit one conditional that checks for that. If they are all
  3328. // present then the fast path executes; otherwise the slow path executes.
  3329. if (num_required_fields_ > 1) {
  3330. // The fast path works if all required fields are present.
  3331. const std::vector<uint32> masks_for_has_bits = RequiredFieldsBitMask();
  3332. format("if ($1$) { // All required fields are present.\n",
  3333. ConditionalToCheckBitmasks(masks_for_has_bits));
  3334. format.Indent();
  3335. // Oneof fields cannot be required, so optimized_order_ contains all of the
  3336. // fields that we need to potentially emit.
  3337. for (auto field : optimized_order_) {
  3338. if (!field->is_required()) continue;
  3339. PrintFieldComment(format, field);
  3340. field_generators_.get(field).GenerateByteSize(printer);
  3341. format("\n");
  3342. }
  3343. format.Outdent();
  3344. format(
  3345. "} else {\n" // the slow path
  3346. " total_size += RequiredFieldsByteSizeFallback();\n"
  3347. "}\n");
  3348. } else {
  3349. // num_required_fields_ <= 1: no need to be tricky
  3350. for (auto field : optimized_order_) {
  3351. if (!field->is_required()) continue;
  3352. PrintFieldComment(format, field);
  3353. format("if (_internal_has_$1$()) {\n", FieldName(field));
  3354. format.Indent();
  3355. field_generators_.get(field).GenerateByteSize(printer);
  3356. format.Outdent();
  3357. format("}\n");
  3358. }
  3359. }
  3360. std::vector<std::vector<const FieldDescriptor*>> chunks = CollectFields(
  3361. optimized_order_,
  3362. [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool {
  3363. return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b);
  3364. });
  3365. // Remove chunks with required fields.
  3366. chunks.erase(std::remove_if(chunks.begin(), chunks.end(), IsRequired),
  3367. chunks.end());
  3368. ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio);
  3369. int cached_has_word_index = -1;
  3370. format(
  3371. "$uint32$ cached_has_bits = 0;\n"
  3372. "// Prevent compiler warnings about cached_has_bits being unused\n"
  3373. "(void) cached_has_bits;\n\n");
  3374. for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) {
  3375. const std::vector<const FieldDescriptor*>& chunk = chunks[chunk_index];
  3376. const bool have_outer_if =
  3377. chunk.size() > 1 && HasWordIndex(chunk[0]) != kNoHasbit;
  3378. cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer);
  3379. if (have_outer_if) {
  3380. // Emit an if() that will let us skip the whole chunk if none are set.
  3381. uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_);
  3382. std::string chunk_mask_str =
  3383. StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8));
  3384. // Check (up to) 8 has_bits at a time if we have more than one field in
  3385. // this chunk. Due to field layout ordering, we may check
  3386. // _has_bits_[last_chunk * 8 / 32] multiple times.
  3387. GOOGLE_DCHECK_LE(2, popcnt(chunk_mask));
  3388. GOOGLE_DCHECK_GE(8, popcnt(chunk_mask));
  3389. if (cached_has_word_index != HasWordIndex(chunk.front())) {
  3390. cached_has_word_index = HasWordIndex(chunk.front());
  3391. format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index);
  3392. }
  3393. format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str);
  3394. format.Indent();
  3395. }
  3396. // Go back and emit checks for each of the fields we processed.
  3397. for (int j = 0; j < chunk.size(); j++) {
  3398. const FieldDescriptor* field = chunk[j];
  3399. const FieldGenerator& generator = field_generators_.get(field);
  3400. bool have_enclosing_if = false;
  3401. bool need_extra_newline = false;
  3402. PrintFieldComment(format, field);
  3403. if (field->is_repeated()) {
  3404. // No presence check is required.
  3405. need_extra_newline = true;
  3406. } else if (HasHasbit(field)) {
  3407. PrintPresenceCheck(format, field, has_bit_indices_, printer,
  3408. &cached_has_word_index);
  3409. have_enclosing_if = true;
  3410. } else {
  3411. // Without field presence: field is serialized only if it has a
  3412. // non-default value.
  3413. have_enclosing_if =
  3414. EmitFieldNonDefaultCondition(printer, "this->", field);
  3415. }
  3416. generator.GenerateByteSize(printer);
  3417. if (have_enclosing_if) {
  3418. format.Outdent();
  3419. format(
  3420. "}\n"
  3421. "\n");
  3422. }
  3423. if (need_extra_newline) {
  3424. format("\n");
  3425. }
  3426. }
  3427. if (have_outer_if) {
  3428. format.Outdent();
  3429. format("}\n");
  3430. }
  3431. if (cold_skipper.OnEndChunk(chunk_index, printer)) {
  3432. // Reset here as it may have been updated in just closed if statement.
  3433. cached_has_word_index = -1;
  3434. }
  3435. }
  3436. // Fields inside a oneof don't use _has_bits_ so we count them in a separate
  3437. // pass.
  3438. for (auto oneof : OneOfRange(descriptor_)) {
  3439. format("switch ($1$_case()) {\n", oneof->name());
  3440. format.Indent();
  3441. for (auto field : FieldRange(oneof)) {
  3442. PrintFieldComment(format, field);
  3443. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  3444. format.Indent();
  3445. if (!IsFieldStripped(field, options_)) {
  3446. field_generators_.get(field).GenerateByteSize(printer);
  3447. }
  3448. format("break;\n");
  3449. format.Outdent();
  3450. format("}\n");
  3451. }
  3452. format(
  3453. "case $1$_NOT_SET: {\n"
  3454. " break;\n"
  3455. "}\n",
  3456. ToUpper(oneof->name()));
  3457. format.Outdent();
  3458. format("}\n");
  3459. }
  3460. if (num_weak_fields_) {
  3461. // TagSize + MessageSize
  3462. format("total_size += _weak_field_map_.ByteSizeLong();\n");
  3463. }
  3464. format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n");
  3465. if (UseUnknownFieldSet(descriptor_->file(), options_)) {
  3466. // We go out of our way to put the computation of the uncommon path of
  3467. // unknown fields in tail position. This allows for better code generation
  3468. // of this function for simple protos.
  3469. format(
  3470. " return ::$proto_ns$::internal::ComputeUnknownFieldsSize(\n"
  3471. " _internal_metadata_, total_size, &_cached_size_);\n");
  3472. } else {
  3473. format(" total_size += $unknown_fields$.size();\n");
  3474. }
  3475. format("}\n");
  3476. // We update _cached_size_ even though this is a const method. Because
  3477. // const methods might be called concurrently this needs to be atomic
  3478. // operations or the program is undefined. In practice, since any concurrent
  3479. // writes will be writing the exact same value, normal writes will work on
  3480. // all common processors. We use a dedicated wrapper class to abstract away
  3481. // the underlying atomic. This makes it easier on platforms where even relaxed
  3482. // memory order might have perf impact to replace it with ordinary loads and
  3483. // stores.
  3484. format(
  3485. "int cached_size = ::$proto_ns$::internal::ToCachedSize(total_size);\n"
  3486. "SetCachedSize(cached_size);\n"
  3487. "return total_size;\n");
  3488. format.Outdent();
  3489. format("}\n");
  3490. }
  3491. void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
  3492. Formatter format(printer, variables_);
  3493. format("bool $classname$::IsInitialized() const {\n");
  3494. format.Indent();
  3495. if (descriptor_->extension_range_count() > 0) {
  3496. format(
  3497. "if (!_extensions_.IsInitialized()) {\n"
  3498. " return false;\n"
  3499. "}\n\n");
  3500. }
  3501. if (num_required_fields_ > 0) {
  3502. format(
  3503. "if (_Internal::MissingRequiredFields(_has_bits_))"
  3504. " return false;\n");
  3505. }
  3506. // Now check that all non-oneof embedded messages are initialized.
  3507. for (auto field : optimized_order_) {
  3508. // TODO(ckennelly): Push this down into a generator?
  3509. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  3510. !ShouldIgnoreRequiredFieldCheck(field, options_) &&
  3511. scc_analyzer_->HasRequiredFields(field->message_type())) {
  3512. if (field->is_repeated()) {
  3513. if (IsImplicitWeakField(field, options_, scc_analyzer_)) {
  3514. format(
  3515. "if "
  3516. "(!::$proto_ns$::internal::AllAreInitializedWeak($1$_.weak)"
  3517. ")"
  3518. " return false;\n",
  3519. FieldName(field));
  3520. } else {
  3521. format(
  3522. "if (!::$proto_ns$::internal::AllAreInitialized($1$_))"
  3523. " return false;\n",
  3524. FieldName(field));
  3525. }
  3526. } else if (field->options().weak()) {
  3527. continue;
  3528. } else {
  3529. GOOGLE_CHECK(!field->real_containing_oneof());
  3530. format(
  3531. "if (_internal_has_$1$()) {\n"
  3532. " if (!$1$_->IsInitialized()) return false;\n"
  3533. "}\n",
  3534. FieldName(field));
  3535. }
  3536. }
  3537. }
  3538. if (num_weak_fields_) {
  3539. // For Weak fields.
  3540. format("if (!_weak_field_map_.IsInitialized()) return false;\n");
  3541. }
  3542. // Go through the oneof fields, emitting a switch if any might have required
  3543. // fields.
  3544. for (auto oneof : OneOfRange(descriptor_)) {
  3545. bool has_required_fields = false;
  3546. for (auto field : FieldRange(oneof)) {
  3547. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  3548. !ShouldIgnoreRequiredFieldCheck(field, options_) &&
  3549. scc_analyzer_->HasRequiredFields(field->message_type())) {
  3550. has_required_fields = true;
  3551. break;
  3552. }
  3553. }
  3554. if (!has_required_fields) {
  3555. continue;
  3556. }
  3557. format("switch ($1$_case()) {\n", oneof->name());
  3558. format.Indent();
  3559. for (auto field : FieldRange(oneof)) {
  3560. format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true));
  3561. format.Indent();
  3562. if (!IsFieldStripped(field, options_) &&
  3563. field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  3564. !ShouldIgnoreRequiredFieldCheck(field, options_) &&
  3565. scc_analyzer_->HasRequiredFields(field->message_type())) {
  3566. GOOGLE_CHECK(!(field->options().weak() || !field->real_containing_oneof()));
  3567. if (field->options().weak()) {
  3568. // Just skip.
  3569. } else {
  3570. format(
  3571. "if (has_$1$()) {\n"
  3572. " if (!this->$1$().IsInitialized()) return false;\n"
  3573. "}\n",
  3574. FieldName(field));
  3575. }
  3576. }
  3577. format("break;\n");
  3578. format.Outdent();
  3579. format("}\n");
  3580. }
  3581. format(
  3582. "case $1$_NOT_SET: {\n"
  3583. " break;\n"
  3584. "}\n",
  3585. ToUpper(oneof->name()));
  3586. format.Outdent();
  3587. format("}\n");
  3588. }
  3589. format.Outdent();
  3590. format(
  3591. " return true;\n"
  3592. "}\n");
  3593. }
  3594. } // namespace cpp
  3595. } // namespace compiler
  3596. } // namespace protobuf
  3597. } // namespace google