java_enum_field.cc 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  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 <map>
  34. #include <string>
  35. #include <google/protobuf/stubs/logging.h>
  36. #include <google/protobuf/stubs/common.h>
  37. #include <google/protobuf/compiler/java/java_context.h>
  38. #include <google/protobuf/compiler/java/java_doc_comment.h>
  39. #include <google/protobuf/compiler/java/java_enum_field.h>
  40. #include <google/protobuf/compiler/java/java_helpers.h>
  41. #include <google/protobuf/compiler/java/java_name_resolver.h>
  42. #include <google/protobuf/io/printer.h>
  43. #include <google/protobuf/wire_format.h>
  44. #include <google/protobuf/stubs/strutil.h>
  45. namespace google {
  46. namespace protobuf {
  47. namespace compiler {
  48. namespace java {
  49. namespace {
  50. void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
  51. int builderBitIndex, const FieldGeneratorInfo* info,
  52. ClassNameResolver* name_resolver,
  53. std::map<std::string, std::string>* variables) {
  54. SetCommonFieldVariables(descriptor, info, variables);
  55. (*variables)["type"] =
  56. name_resolver->GetImmutableClassName(descriptor->enum_type());
  57. (*variables)["mutable_type"] =
  58. name_resolver->GetMutableClassName(descriptor->enum_type());
  59. (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
  60. (*variables)["default_number"] =
  61. StrCat(descriptor->default_value_enum()->number());
  62. (*variables)["tag"] = StrCat(
  63. static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
  64. (*variables)["tag_size"] = StrCat(
  65. internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
  66. // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
  67. // by the proto compiler
  68. (*variables)["deprecation"] =
  69. descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
  70. (*variables)["on_changed"] = "onChanged();";
  71. // Use deprecated valueOf() method to be compatible with old generated code
  72. // for v2.5.0/v2.6.1.
  73. // TODO(xiaofeng): Use "forNumber" when we no longer support compatibility
  74. // with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations.
  75. (*variables)["for_number"] = "valueOf";
  76. if (HasHasbit(descriptor)) {
  77. // For singular messages and builders, one bit is used for the hasField bit.
  78. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
  79. (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
  80. // Note that these have a trailing ";".
  81. (*variables)["set_has_field_bit_message"] =
  82. GenerateSetBit(messageBitIndex) + ";";
  83. (*variables)["set_has_field_bit_builder"] =
  84. GenerateSetBit(builderBitIndex) + ";";
  85. (*variables)["clear_has_field_bit_builder"] =
  86. GenerateClearBit(builderBitIndex) + ";";
  87. (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
  88. } else {
  89. (*variables)["set_has_field_bit_message"] = "";
  90. (*variables)["set_has_field_bit_builder"] = "";
  91. (*variables)["clear_has_field_bit_builder"] = "";
  92. (*variables)["is_field_present_message"] =
  93. (*variables)["name"] + "_ != " + (*variables)["default"] +
  94. ".getNumber()";
  95. }
  96. // For repeated builders, one bit is used for whether the array is immutable.
  97. (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
  98. (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
  99. (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
  100. // For repeated fields, one bit is used for whether the array is immutable
  101. // in the parsing constructor.
  102. (*variables)["get_mutable_bit_parser"] =
  103. GenerateGetBitMutableLocal(builderBitIndex);
  104. (*variables)["set_mutable_bit_parser"] =
  105. GenerateSetBitMutableLocal(builderBitIndex);
  106. (*variables)["get_has_field_bit_from_local"] =
  107. GenerateGetBitFromLocal(builderBitIndex);
  108. (*variables)["set_has_field_bit_to_local"] =
  109. GenerateSetBitToLocal(messageBitIndex);
  110. if (SupportUnknownEnumValue(descriptor->file())) {
  111. (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
  112. } else {
  113. (*variables)["unknown"] = (*variables)["default"];
  114. }
  115. }
  116. } // namespace
  117. // ===================================================================
  118. ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator(
  119. const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
  120. Context* context)
  121. : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
  122. SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
  123. context->GetFieldGeneratorInfo(descriptor), name_resolver_,
  124. &variables_);
  125. }
  126. ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
  127. int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
  128. return HasHasbit(descriptor_) ? 1 : 0;
  129. }
  130. int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
  131. return GetNumBitsForMessage();
  132. }
  133. void ImmutableEnumFieldGenerator::GenerateInterfaceMembers(
  134. io::Printer* printer) const {
  135. if (SupportFieldPresence(descriptor_)) {
  136. WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
  137. printer->Print(variables_,
  138. "$deprecation$boolean has$capitalized_name$();\n");
  139. }
  140. if (SupportUnknownEnumValue(descriptor_->file())) {
  141. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
  142. printer->Print(variables_,
  143. "$deprecation$int get$capitalized_name$Value();\n");
  144. }
  145. WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
  146. printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
  147. }
  148. void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const {
  149. printer->Print(variables_, "private int $name$_;\n");
  150. PrintExtraFieldInfo(variables_, printer);
  151. if (SupportFieldPresence(descriptor_)) {
  152. WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
  153. printer->Print(variables_,
  154. "@java.lang.Override $deprecation$public boolean "
  155. "${$has$capitalized_name$$}$() {\n"
  156. " return $get_has_field_bit_message$;\n"
  157. "}\n");
  158. printer->Annotate("{", "}", descriptor_);
  159. }
  160. if (SupportUnknownEnumValue(descriptor_->file())) {
  161. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
  162. printer->Print(variables_,
  163. "@java.lang.Override $deprecation$public int "
  164. "${$get$capitalized_name$Value$}$() {\n"
  165. " return $name$_;\n"
  166. "}\n");
  167. printer->Annotate("{", "}", descriptor_);
  168. }
  169. WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
  170. printer->Print(variables_,
  171. "@java.lang.Override $deprecation$public $type$ "
  172. "${$get$capitalized_name$$}$() {\n"
  173. " @SuppressWarnings(\"deprecation\")\n"
  174. " $type$ result = $type$.$for_number$($name$_);\n"
  175. " return result == null ? $unknown$ : result;\n"
  176. "}\n");
  177. printer->Annotate("{", "}", descriptor_);
  178. }
  179. void ImmutableEnumFieldGenerator::GenerateBuilderMembers(
  180. io::Printer* printer) const {
  181. printer->Print(variables_, "private int $name$_ = $default_number$;\n");
  182. if (SupportFieldPresence(descriptor_)) {
  183. WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
  184. printer->Print(variables_,
  185. "@java.lang.Override $deprecation$public boolean "
  186. "${$has$capitalized_name$$}$() {\n"
  187. " return $get_has_field_bit_builder$;\n"
  188. "}\n");
  189. printer->Annotate("{", "}", descriptor_);
  190. }
  191. if (SupportUnknownEnumValue(descriptor_->file())) {
  192. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
  193. printer->Print(variables_,
  194. "@java.lang.Override $deprecation$public int "
  195. "${$get$capitalized_name$Value$}$() {\n"
  196. " return $name$_;\n"
  197. "}\n");
  198. printer->Annotate("{", "}", descriptor_);
  199. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
  200. /* builder */ true);
  201. printer->Print(variables_,
  202. "$deprecation$public Builder "
  203. "${$set$capitalized_name$Value$}$(int value) {\n"
  204. " $set_has_field_bit_builder$\n"
  205. " $name$_ = value;\n"
  206. " $on_changed$\n"
  207. " return this;\n"
  208. "}\n");
  209. printer->Annotate("{", "}", descriptor_);
  210. }
  211. WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
  212. printer->Print(variables_,
  213. "@java.lang.Override\n"
  214. "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
  215. " @SuppressWarnings(\"deprecation\")\n"
  216. " $type$ result = $type$.$for_number$($name$_);\n"
  217. " return result == null ? $unknown$ : result;\n"
  218. "}\n");
  219. printer->Annotate("{", "}", descriptor_);
  220. WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
  221. /* builder */ true);
  222. printer->Print(variables_,
  223. "$deprecation$public Builder "
  224. "${$set$capitalized_name$$}$($type$ value) {\n"
  225. " if (value == null) {\n"
  226. " throw new NullPointerException();\n"
  227. " }\n"
  228. " $set_has_field_bit_builder$\n"
  229. " $name$_ = value.getNumber();\n"
  230. " $on_changed$\n"
  231. " return this;\n"
  232. "}\n");
  233. printer->Annotate("{", "}", descriptor_);
  234. WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
  235. /* builder */ true);
  236. printer->Print(
  237. variables_,
  238. "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
  239. " $clear_has_field_bit_builder$\n"
  240. " $name$_ = $default_number$;\n"
  241. " $on_changed$\n"
  242. " return this;\n"
  243. "}\n");
  244. printer->Annotate("{", "}", descriptor_);
  245. }
  246. void ImmutableEnumFieldGenerator::GenerateFieldBuilderInitializationCode(
  247. io::Printer* printer) const {
  248. // noop for enums
  249. }
  250. void ImmutableEnumFieldGenerator::GenerateInitializationCode(
  251. io::Printer* printer) const {
  252. printer->Print(variables_, "$name$_ = $default_number$;\n");
  253. }
  254. void ImmutableEnumFieldGenerator::GenerateBuilderClearCode(
  255. io::Printer* printer) const {
  256. printer->Print(variables_,
  257. "$name$_ = $default_number$;\n"
  258. "$clear_has_field_bit_builder$\n");
  259. }
  260. void ImmutableEnumFieldGenerator::GenerateMergingCode(
  261. io::Printer* printer) const {
  262. if (SupportFieldPresence(descriptor_)) {
  263. printer->Print(variables_,
  264. "if (other.has$capitalized_name$()) {\n"
  265. " set$capitalized_name$(other.get$capitalized_name$());\n"
  266. "}\n");
  267. } else if (SupportUnknownEnumValue(descriptor_->file())) {
  268. printer->Print(
  269. variables_,
  270. "if (other.$name$_ != $default_number$) {\n"
  271. " set$capitalized_name$Value(other.get$capitalized_name$Value());\n"
  272. "}\n");
  273. } else {
  274. GOOGLE_LOG(FATAL) << "Can't reach here.";
  275. }
  276. }
  277. void ImmutableEnumFieldGenerator::GenerateBuildingCode(
  278. io::Printer* printer) const {
  279. if (SupportFieldPresence(descriptor_)) {
  280. printer->Print(variables_,
  281. "if ($get_has_field_bit_from_local$) {\n"
  282. " $set_has_field_bit_to_local$;\n"
  283. "}\n");
  284. }
  285. printer->Print(variables_, "result.$name$_ = $name$_;\n");
  286. }
  287. void ImmutableEnumFieldGenerator::GenerateParsingCode(
  288. io::Printer* printer) const {
  289. if (SupportUnknownEnumValue(descriptor_->file())) {
  290. printer->Print(variables_,
  291. "int rawValue = input.readEnum();\n"
  292. "$set_has_field_bit_message$\n"
  293. "$name$_ = rawValue;\n");
  294. } else {
  295. printer->Print(variables_,
  296. "int rawValue = input.readEnum();\n"
  297. " @SuppressWarnings(\"deprecation\")\n"
  298. "$type$ value = $type$.$for_number$(rawValue);\n"
  299. "if (value == null) {\n"
  300. " unknownFields.mergeVarintField($number$, rawValue);\n"
  301. "} else {\n"
  302. " $set_has_field_bit_message$\n"
  303. " $name$_ = rawValue;\n"
  304. "}\n");
  305. }
  306. }
  307. void ImmutableEnumFieldGenerator::GenerateParsingDoneCode(
  308. io::Printer* printer) const {
  309. // noop for enums
  310. }
  311. void ImmutableEnumFieldGenerator::GenerateSerializationCode(
  312. io::Printer* printer) const {
  313. printer->Print(variables_,
  314. "if ($is_field_present_message$) {\n"
  315. " output.writeEnum($number$, $name$_);\n"
  316. "}\n");
  317. }
  318. void ImmutableEnumFieldGenerator::GenerateSerializedSizeCode(
  319. io::Printer* printer) const {
  320. printer->Print(variables_,
  321. "if ($is_field_present_message$) {\n"
  322. " size += com.google.protobuf.CodedOutputStream\n"
  323. " .computeEnumSize($number$, $name$_);\n"
  324. "}\n");
  325. }
  326. void ImmutableEnumFieldGenerator::GenerateEqualsCode(
  327. io::Printer* printer) const {
  328. printer->Print(variables_, "if ($name$_ != other.$name$_) return false;\n");
  329. }
  330. void ImmutableEnumFieldGenerator::GenerateHashCode(io::Printer* printer) const {
  331. printer->Print(variables_,
  332. "hash = (37 * hash) + $constant_name$;\n"
  333. "hash = (53 * hash) + $name$_;\n");
  334. }
  335. std::string ImmutableEnumFieldGenerator::GetBoxedType() const {
  336. return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
  337. }
  338. // ===================================================================
  339. ImmutableEnumOneofFieldGenerator::ImmutableEnumOneofFieldGenerator(
  340. const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
  341. Context* context)
  342. : ImmutableEnumFieldGenerator(descriptor, messageBitIndex, builderBitIndex,
  343. context) {
  344. const OneofGeneratorInfo* info =
  345. context->GetOneofGeneratorInfo(descriptor->containing_oneof());
  346. SetCommonOneofVariables(descriptor, info, &variables_);
  347. }
  348. ImmutableEnumOneofFieldGenerator::~ImmutableEnumOneofFieldGenerator() {}
  349. void ImmutableEnumOneofFieldGenerator::GenerateMembers(
  350. io::Printer* printer) const {
  351. PrintExtraFieldInfo(variables_, printer);
  352. if (SupportFieldPresence(descriptor_)) {
  353. WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
  354. printer->Print(
  355. variables_,
  356. "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
  357. " return $has_oneof_case_message$;\n"
  358. "}\n");
  359. printer->Annotate("{", "}", descriptor_);
  360. }
  361. if (SupportUnknownEnumValue(descriptor_->file())) {
  362. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
  363. printer->Print(
  364. variables_,
  365. "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
  366. " if ($has_oneof_case_message$) {\n"
  367. " return (java.lang.Integer) $oneof_name$_;\n"
  368. " }\n"
  369. " return $default_number$;\n"
  370. "}\n");
  371. printer->Annotate("{", "}", descriptor_);
  372. }
  373. WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
  374. printer->Print(variables_,
  375. "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
  376. " if ($has_oneof_case_message$) {\n"
  377. " @SuppressWarnings(\"deprecation\")\n"
  378. " $type$ result = $type$.$for_number$(\n"
  379. " (java.lang.Integer) $oneof_name$_);\n"
  380. " return result == null ? $unknown$ : result;\n"
  381. " }\n"
  382. " return $default$;\n"
  383. "}\n");
  384. printer->Annotate("{", "}", descriptor_);
  385. }
  386. void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
  387. io::Printer* printer) const {
  388. if (SupportFieldPresence(descriptor_)) {
  389. WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
  390. printer->Print(
  391. variables_,
  392. "@java.lang.Override\n"
  393. "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
  394. " return $has_oneof_case_message$;\n"
  395. "}\n");
  396. printer->Annotate("{", "}", descriptor_);
  397. }
  398. if (SupportUnknownEnumValue(descriptor_->file())) {
  399. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
  400. printer->Print(
  401. variables_,
  402. "@java.lang.Override\n"
  403. "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
  404. " if ($has_oneof_case_message$) {\n"
  405. " return ((java.lang.Integer) $oneof_name$_).intValue();\n"
  406. " }\n"
  407. " return $default_number$;\n"
  408. "}\n");
  409. printer->Annotate("{", "}", descriptor_);
  410. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
  411. /* builder */ true);
  412. printer->Print(variables_,
  413. "$deprecation$public Builder "
  414. "${$set$capitalized_name$Value$}$(int value) {\n"
  415. " $set_oneof_case_message$;\n"
  416. " $oneof_name$_ = value;\n"
  417. " $on_changed$\n"
  418. " return this;\n"
  419. "}\n");
  420. printer->Annotate("{", "}", descriptor_);
  421. }
  422. WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
  423. printer->Print(variables_,
  424. "@java.lang.Override\n"
  425. "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
  426. " if ($has_oneof_case_message$) {\n"
  427. " @SuppressWarnings(\"deprecation\")\n"
  428. " $type$ result = $type$.$for_number$(\n"
  429. " (java.lang.Integer) $oneof_name$_);\n"
  430. " return result == null ? $unknown$ : result;\n"
  431. " }\n"
  432. " return $default$;\n"
  433. "}\n");
  434. printer->Annotate("{", "}", descriptor_);
  435. WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
  436. /* builder */ true);
  437. printer->Print(variables_,
  438. "$deprecation$public Builder "
  439. "${$set$capitalized_name$$}$($type$ value) {\n"
  440. " if (value == null) {\n"
  441. " throw new NullPointerException();\n"
  442. " }\n"
  443. " $set_oneof_case_message$;\n"
  444. " $oneof_name$_ = value.getNumber();\n"
  445. " $on_changed$\n"
  446. " return this;\n"
  447. "}\n");
  448. printer->Annotate("{", "}", descriptor_);
  449. WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
  450. /* builder */ true);
  451. printer->Print(
  452. variables_,
  453. "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
  454. " if ($has_oneof_case_message$) {\n"
  455. " $clear_oneof_case_message$;\n"
  456. " $oneof_name$_ = null;\n"
  457. " $on_changed$\n"
  458. " }\n"
  459. " return this;\n"
  460. "}\n");
  461. printer->Annotate("{", "}", descriptor_);
  462. }
  463. void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode(
  464. io::Printer* printer) const {
  465. printer->Print(variables_,
  466. "if ($has_oneof_case_message$) {\n"
  467. " result.$oneof_name$_ = $oneof_name$_;\n"
  468. "}\n");
  469. }
  470. void ImmutableEnumOneofFieldGenerator::GenerateMergingCode(
  471. io::Printer* printer) const {
  472. if (SupportUnknownEnumValue(descriptor_->file())) {
  473. printer->Print(
  474. variables_,
  475. "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
  476. } else {
  477. printer->Print(variables_,
  478. "set$capitalized_name$(other.get$capitalized_name$());\n");
  479. }
  480. }
  481. void ImmutableEnumOneofFieldGenerator::GenerateParsingCode(
  482. io::Printer* printer) const {
  483. if (SupportUnknownEnumValue(descriptor_->file())) {
  484. printer->Print(variables_,
  485. "int rawValue = input.readEnum();\n"
  486. "$set_oneof_case_message$;\n"
  487. "$oneof_name$_ = rawValue;\n");
  488. } else {
  489. printer->Print(variables_,
  490. "int rawValue = input.readEnum();\n"
  491. "@SuppressWarnings(\"deprecation\")\n"
  492. "$type$ value = $type$.$for_number$(rawValue);\n"
  493. "if (value == null) {\n"
  494. " unknownFields.mergeVarintField($number$, rawValue);\n"
  495. "} else {\n"
  496. " $set_oneof_case_message$;\n"
  497. " $oneof_name$_ = rawValue;\n"
  498. "}\n");
  499. }
  500. }
  501. void ImmutableEnumOneofFieldGenerator::GenerateSerializationCode(
  502. io::Printer* printer) const {
  503. printer->Print(
  504. variables_,
  505. "if ($has_oneof_case_message$) {\n"
  506. " output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
  507. "}\n");
  508. }
  509. void ImmutableEnumOneofFieldGenerator::GenerateSerializedSizeCode(
  510. io::Printer* printer) const {
  511. printer->Print(
  512. variables_,
  513. "if ($has_oneof_case_message$) {\n"
  514. " size += com.google.protobuf.CodedOutputStream\n"
  515. " .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
  516. "}\n");
  517. }
  518. void ImmutableEnumOneofFieldGenerator::GenerateEqualsCode(
  519. io::Printer* printer) const {
  520. if (SupportUnknownEnumValue(descriptor_->file())) {
  521. printer->Print(
  522. variables_,
  523. "if (get$capitalized_name$Value()\n"
  524. " != other.get$capitalized_name$Value()) return false;\n");
  525. } else {
  526. printer->Print(
  527. variables_,
  528. "if (!get$capitalized_name$()\n"
  529. " .equals(other.get$capitalized_name$())) return false;\n");
  530. }
  531. }
  532. void ImmutableEnumOneofFieldGenerator::GenerateHashCode(
  533. io::Printer* printer) const {
  534. if (SupportUnknownEnumValue(descriptor_->file())) {
  535. printer->Print(variables_,
  536. "hash = (37 * hash) + $constant_name$;\n"
  537. "hash = (53 * hash) + get$capitalized_name$Value();\n");
  538. } else {
  539. printer->Print(
  540. variables_,
  541. "hash = (37 * hash) + $constant_name$;\n"
  542. "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
  543. }
  544. }
  545. // ===================================================================
  546. RepeatedImmutableEnumFieldGenerator::RepeatedImmutableEnumFieldGenerator(
  547. const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
  548. Context* context)
  549. : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
  550. SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
  551. context->GetFieldGeneratorInfo(descriptor), name_resolver_,
  552. &variables_);
  553. }
  554. RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
  555. int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
  556. return 0;
  557. }
  558. int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
  559. return 1;
  560. }
  561. void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceMembers(
  562. io::Printer* printer) const {
  563. WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
  564. printer->Print(
  565. variables_,
  566. "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
  567. WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
  568. printer->Print(variables_,
  569. "$deprecation$int get$capitalized_name$Count();\n");
  570. WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
  571. printer->Print(variables_,
  572. "$deprecation$$type$ get$capitalized_name$(int index);\n");
  573. if (SupportUnknownEnumValue(descriptor_->file())) {
  574. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
  575. printer->Print(variables_,
  576. "$deprecation$java.util.List<java.lang.Integer>\n"
  577. "get$capitalized_name$ValueList();\n");
  578. WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
  579. LIST_INDEXED_GETTER);
  580. printer->Print(variables_,
  581. "$deprecation$int get$capitalized_name$Value(int index);\n");
  582. }
  583. }
  584. void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
  585. io::Printer* printer) const {
  586. printer->Print(
  587. variables_,
  588. "private java.util.List<java.lang.Integer> $name$_;\n"
  589. "private static final "
  590. "com.google.protobuf.Internal.ListAdapter.Converter<\n"
  591. " java.lang.Integer, $type$> $name$_converter_ =\n"
  592. " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
  593. " java.lang.Integer, $type$>() {\n"
  594. " public $type$ convert(java.lang.Integer from) {\n"
  595. " @SuppressWarnings(\"deprecation\")\n"
  596. " $type$ result = $type$.$for_number$(from);\n"
  597. " return result == null ? $unknown$ : result;\n"
  598. " }\n"
  599. " };\n");
  600. PrintExtraFieldInfo(variables_, printer);
  601. WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
  602. printer->Print(
  603. variables_,
  604. "@java.lang.Override\n"
  605. "$deprecation$public java.util.List<$type$> "
  606. "${$get$capitalized_name$List$}$() {\n"
  607. " return new com.google.protobuf.Internal.ListAdapter<\n"
  608. " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
  609. "}\n");
  610. printer->Annotate("{", "}", descriptor_);
  611. WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
  612. printer->Print(
  613. variables_,
  614. "@java.lang.Override\n"
  615. "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
  616. " return $name$_.size();\n"
  617. "}\n");
  618. printer->Annotate("{", "}", descriptor_);
  619. WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
  620. printer->Print(
  621. variables_,
  622. "@java.lang.Override\n"
  623. "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
  624. " return $name$_converter_.convert($name$_.get(index));\n"
  625. "}\n");
  626. printer->Annotate("{", "}", descriptor_);
  627. if (SupportUnknownEnumValue(descriptor_->file())) {
  628. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
  629. printer->Print(variables_,
  630. "@java.lang.Override\n"
  631. "$deprecation$public java.util.List<java.lang.Integer>\n"
  632. "${$get$capitalized_name$ValueList$}$() {\n"
  633. " return $name$_;\n"
  634. "}\n");
  635. printer->Annotate("{", "}", descriptor_);
  636. WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
  637. LIST_INDEXED_GETTER);
  638. printer->Print(variables_,
  639. "@java.lang.Override\n"
  640. "$deprecation$public int "
  641. "${$get$capitalized_name$Value$}$(int index) {\n"
  642. " return $name$_.get(index);\n"
  643. "}\n");
  644. printer->Annotate("{", "}", descriptor_);
  645. }
  646. if (descriptor_->is_packed()) {
  647. printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
  648. }
  649. }
  650. void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
  651. io::Printer* printer) const {
  652. printer->Print(
  653. variables_,
  654. // One field is the list and the other field keeps track of whether the
  655. // list is immutable. If it's immutable, the invariant is that it must
  656. // either an instance of Collections.emptyList() or it's an ArrayList
  657. // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
  658. // a reference to the underlying ArrayList. This invariant allows us to
  659. // share instances of lists between protocol buffers avoiding expensive
  660. // memory allocations. Note, immutable is a strong guarantee here -- not
  661. // just that the list cannot be modified via the reference but that the
  662. // list can never be modified.
  663. "private java.util.List<java.lang.Integer> $name$_ =\n"
  664. " java.util.Collections.emptyList();\n"
  665. "private void ensure$capitalized_name$IsMutable() {\n"
  666. " if (!$get_mutable_bit_builder$) {\n"
  667. " $name$_ = new java.util.ArrayList<java.lang.Integer>($name$_);\n"
  668. " $set_mutable_bit_builder$;\n"
  669. " }\n"
  670. "}\n");
  671. WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
  672. printer->Print(
  673. variables_,
  674. // Note: We return an unmodifiable list because otherwise the caller
  675. // could hold on to the returned list and modify it after the message
  676. // has been built, thus mutating the message which is supposed to be
  677. // immutable.
  678. "$deprecation$public java.util.List<$type$> "
  679. "${$get$capitalized_name$List$}$() {\n"
  680. " return new com.google.protobuf.Internal.ListAdapter<\n"
  681. " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
  682. "}\n");
  683. printer->Annotate("{", "}", descriptor_);
  684. WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
  685. printer->Print(
  686. variables_,
  687. "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
  688. " return $name$_.size();\n"
  689. "}\n");
  690. printer->Annotate("{", "}", descriptor_);
  691. WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
  692. printer->Print(
  693. variables_,
  694. "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
  695. " return $name$_converter_.convert($name$_.get(index));\n"
  696. "}\n");
  697. printer->Annotate("{", "}", descriptor_);
  698. WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
  699. /* builder */ true);
  700. printer->Print(variables_,
  701. "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
  702. " int index, $type$ value) {\n"
  703. " if (value == null) {\n"
  704. " throw new NullPointerException();\n"
  705. " }\n"
  706. " ensure$capitalized_name$IsMutable();\n"
  707. " $name$_.set(index, value.getNumber());\n"
  708. " $on_changed$\n"
  709. " return this;\n"
  710. "}\n");
  711. printer->Annotate("{", "}", descriptor_);
  712. WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
  713. /* builder */ true);
  714. printer->Print(variables_,
  715. "$deprecation$public Builder "
  716. "${$add$capitalized_name$$}$($type$ value) {\n"
  717. " if (value == null) {\n"
  718. " throw new NullPointerException();\n"
  719. " }\n"
  720. " ensure$capitalized_name$IsMutable();\n"
  721. " $name$_.add(value.getNumber());\n"
  722. " $on_changed$\n"
  723. " return this;\n"
  724. "}\n");
  725. printer->Annotate("{", "}", descriptor_);
  726. WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
  727. /* builder */ true);
  728. printer->Print(variables_,
  729. "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
  730. " java.lang.Iterable<? extends $type$> values) {\n"
  731. " ensure$capitalized_name$IsMutable();\n"
  732. " for ($type$ value : values) {\n"
  733. " $name$_.add(value.getNumber());\n"
  734. " }\n"
  735. " $on_changed$\n"
  736. " return this;\n"
  737. "}\n");
  738. printer->Annotate("{", "}", descriptor_);
  739. WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
  740. /* builder */ true);
  741. printer->Print(
  742. variables_,
  743. "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
  744. " $name$_ = java.util.Collections.emptyList();\n"
  745. " $clear_mutable_bit_builder$;\n"
  746. " $on_changed$\n"
  747. " return this;\n"
  748. "}\n");
  749. printer->Annotate("{", "}", descriptor_);
  750. if (SupportUnknownEnumValue(descriptor_->file())) {
  751. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
  752. printer->Print(variables_,
  753. "$deprecation$public java.util.List<java.lang.Integer>\n"
  754. "${$get$capitalized_name$ValueList$}$() {\n"
  755. " return java.util.Collections.unmodifiableList($name$_);\n"
  756. "}\n");
  757. printer->Annotate("{", "}", descriptor_);
  758. WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
  759. LIST_INDEXED_GETTER);
  760. printer->Print(variables_,
  761. "$deprecation$public int "
  762. "${$get$capitalized_name$Value$}$(int index) {\n"
  763. " return $name$_.get(index);\n"
  764. "}\n");
  765. printer->Annotate("{", "}", descriptor_);
  766. WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
  767. LIST_INDEXED_GETTER,
  768. /* builder */ true);
  769. printer->Print(
  770. variables_,
  771. "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
  772. " int index, int value) {\n"
  773. " ensure$capitalized_name$IsMutable();\n"
  774. " $name$_.set(index, value);\n"
  775. " $on_changed$\n"
  776. " return this;\n"
  777. "}\n");
  778. printer->Annotate("{", "}", descriptor_);
  779. WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER,
  780. /* builder */ true);
  781. printer->Print(variables_,
  782. "$deprecation$public Builder "
  783. "${$add$capitalized_name$Value$}$(int value) {\n"
  784. " ensure$capitalized_name$IsMutable();\n"
  785. " $name$_.add(value);\n"
  786. " $on_changed$\n"
  787. " return this;\n"
  788. "}\n");
  789. printer->Annotate("{", "}", descriptor_);
  790. WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
  791. LIST_MULTI_ADDER, /* builder */ true);
  792. printer->Print(
  793. variables_,
  794. "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
  795. " java.lang.Iterable<java.lang.Integer> values) {\n"
  796. " ensure$capitalized_name$IsMutable();\n"
  797. " for (int value : values) {\n"
  798. " $name$_.add(value);\n"
  799. " }\n"
  800. " $on_changed$\n"
  801. " return this;\n"
  802. "}\n");
  803. printer->Annotate("{", "}", descriptor_);
  804. }
  805. }
  806. void RepeatedImmutableEnumFieldGenerator::
  807. GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
  808. // noop for enums
  809. }
  810. void RepeatedImmutableEnumFieldGenerator::GenerateInitializationCode(
  811. io::Printer* printer) const {
  812. printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
  813. }
  814. void RepeatedImmutableEnumFieldGenerator::GenerateBuilderClearCode(
  815. io::Printer* printer) const {
  816. printer->Print(variables_,
  817. "$name$_ = java.util.Collections.emptyList();\n"
  818. "$clear_mutable_bit_builder$;\n");
  819. }
  820. void RepeatedImmutableEnumFieldGenerator::GenerateMergingCode(
  821. io::Printer* printer) const {
  822. // The code below does two optimizations:
  823. // 1. If the other list is empty, there's nothing to do. This ensures we
  824. // don't allocate a new array if we already have an immutable one.
  825. // 2. If the other list is non-empty and our current list is empty, we can
  826. // reuse the other list which is guaranteed to be immutable.
  827. printer->Print(variables_,
  828. "if (!other.$name$_.isEmpty()) {\n"
  829. " if ($name$_.isEmpty()) {\n"
  830. " $name$_ = other.$name$_;\n"
  831. " $clear_mutable_bit_builder$;\n"
  832. " } else {\n"
  833. " ensure$capitalized_name$IsMutable();\n"
  834. " $name$_.addAll(other.$name$_);\n"
  835. " }\n"
  836. " $on_changed$\n"
  837. "}\n");
  838. }
  839. void RepeatedImmutableEnumFieldGenerator::GenerateBuildingCode(
  840. io::Printer* printer) const {
  841. // The code below ensures that the result has an immutable list. If our
  842. // list is immutable, we can just reuse it. If not, we make it immutable.
  843. printer->Print(
  844. variables_,
  845. "if ($get_mutable_bit_builder$) {\n"
  846. " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
  847. " $clear_mutable_bit_builder$;\n"
  848. "}\n"
  849. "result.$name$_ = $name$_;\n");
  850. }
  851. void RepeatedImmutableEnumFieldGenerator::GenerateParsingCode(
  852. io::Printer* printer) const {
  853. // Read and store the enum
  854. if (SupportUnknownEnumValue(descriptor_->file())) {
  855. printer->Print(variables_,
  856. "int rawValue = input.readEnum();\n"
  857. "if (!$get_mutable_bit_parser$) {\n"
  858. " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
  859. " $set_mutable_bit_parser$;\n"
  860. "}\n"
  861. "$name$_.add(rawValue);\n");
  862. } else {
  863. printer->Print(
  864. variables_,
  865. "int rawValue = input.readEnum();\n"
  866. "@SuppressWarnings(\"deprecation\")\n"
  867. "$type$ value = $type$.$for_number$(rawValue);\n"
  868. "if (value == null) {\n"
  869. " unknownFields.mergeVarintField($number$, rawValue);\n"
  870. "} else {\n"
  871. " if (!$get_mutable_bit_parser$) {\n"
  872. " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
  873. " $set_mutable_bit_parser$;\n"
  874. " }\n"
  875. " $name$_.add(rawValue);\n"
  876. "}\n");
  877. }
  878. }
  879. void RepeatedImmutableEnumFieldGenerator::GenerateParsingCodeFromPacked(
  880. io::Printer* printer) const {
  881. // Wrap GenerateParsingCode's contents with a while loop.
  882. printer->Print(variables_,
  883. "int length = input.readRawVarint32();\n"
  884. "int oldLimit = input.pushLimit(length);\n"
  885. "while(input.getBytesUntilLimit() > 0) {\n");
  886. printer->Indent();
  887. GenerateParsingCode(printer);
  888. printer->Outdent();
  889. printer->Print(variables_,
  890. "}\n"
  891. "input.popLimit(oldLimit);\n");
  892. }
  893. void RepeatedImmutableEnumFieldGenerator::GenerateParsingDoneCode(
  894. io::Printer* printer) const {
  895. printer->Print(
  896. variables_,
  897. "if ($get_mutable_bit_parser$) {\n"
  898. " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
  899. "}\n");
  900. }
  901. void RepeatedImmutableEnumFieldGenerator::GenerateSerializationCode(
  902. io::Printer* printer) const {
  903. if (descriptor_->is_packed()) {
  904. printer->Print(variables_,
  905. "if (get$capitalized_name$List().size() > 0) {\n"
  906. " output.writeUInt32NoTag($tag$);\n"
  907. " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
  908. "}\n"
  909. "for (int i = 0; i < $name$_.size(); i++) {\n"
  910. " output.writeEnumNoTag($name$_.get(i));\n"
  911. "}\n");
  912. } else {
  913. printer->Print(variables_,
  914. "for (int i = 0; i < $name$_.size(); i++) {\n"
  915. " output.writeEnum($number$, $name$_.get(i));\n"
  916. "}\n");
  917. }
  918. }
  919. void RepeatedImmutableEnumFieldGenerator::GenerateSerializedSizeCode(
  920. io::Printer* printer) const {
  921. printer->Print(variables_,
  922. "{\n"
  923. " int dataSize = 0;\n");
  924. printer->Indent();
  925. printer->Print(variables_,
  926. "for (int i = 0; i < $name$_.size(); i++) {\n"
  927. " dataSize += com.google.protobuf.CodedOutputStream\n"
  928. " .computeEnumSizeNoTag($name$_.get(i));\n"
  929. "}\n");
  930. printer->Print("size += dataSize;\n");
  931. if (descriptor_->is_packed()) {
  932. printer->Print(variables_,
  933. "if (!get$capitalized_name$List().isEmpty()) {"
  934. " size += $tag_size$;\n"
  935. " size += com.google.protobuf.CodedOutputStream\n"
  936. " .computeUInt32SizeNoTag(dataSize);\n"
  937. "}");
  938. } else {
  939. printer->Print(variables_, "size += $tag_size$ * $name$_.size();\n");
  940. }
  941. // cache the data size for packed fields.
  942. if (descriptor_->is_packed()) {
  943. printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
  944. }
  945. printer->Outdent();
  946. printer->Print("}\n");
  947. }
  948. void RepeatedImmutableEnumFieldGenerator::GenerateEqualsCode(
  949. io::Printer* printer) const {
  950. printer->Print(variables_,
  951. "if (!$name$_.equals(other.$name$_)) return false;\n");
  952. }
  953. void RepeatedImmutableEnumFieldGenerator::GenerateHashCode(
  954. io::Printer* printer) const {
  955. printer->Print(variables_,
  956. "if (get$capitalized_name$Count() > 0) {\n"
  957. " hash = (37 * hash) + $constant_name$;\n"
  958. " hash = (53 * hash) + $name$_.hashCode();\n"
  959. "}\n");
  960. }
  961. std::string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
  962. return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
  963. }
  964. } // namespace java
  965. } // namespace compiler
  966. } // namespace protobuf
  967. } // namespace google