java_string_field.cc 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  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. // Author: jonp@google.com (Jon Perlow)
  32. // Based on original Protocol Buffers design by
  33. // Sanjay Ghemawat, Jeff Dean, and others.
  34. #include <map>
  35. #include <string>
  36. #include <google/protobuf/stubs/logging.h>
  37. #include <google/protobuf/stubs/common.h>
  38. #include <google/protobuf/compiler/java/java_context.h>
  39. #include <google/protobuf/compiler/java/java_doc_comment.h>
  40. #include <google/protobuf/compiler/java/java_helpers.h>
  41. #include <google/protobuf/compiler/java/java_name_resolver.h>
  42. #include <google/protobuf/compiler/java/java_string_field.h>
  43. #include <google/protobuf/io/printer.h>
  44. #include <google/protobuf/wire_format.h>
  45. #include <google/protobuf/stubs/strutil.h>
  46. namespace google {
  47. namespace protobuf {
  48. namespace compiler {
  49. namespace java {
  50. using internal::WireFormat;
  51. using internal::WireFormatLite;
  52. namespace {
  53. void SetPrimitiveVariables(const FieldDescriptor* descriptor,
  54. int messageBitIndex,
  55. int builderBitIndex,
  56. const FieldGeneratorInfo* info,
  57. ClassNameResolver* name_resolver,
  58. std::map<string, string>* variables) {
  59. SetCommonFieldVariables(descriptor, info, variables);
  60. (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
  61. (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
  62. (*variables)["default_init"] =
  63. "= " + ImmutableDefaultValue(descriptor, name_resolver);
  64. (*variables)["capitalized_type"] = "String";
  65. (*variables)["tag"] =
  66. SimpleItoa(static_cast<int32>(WireFormat::MakeTag(descriptor)));
  67. (*variables)["tag_size"] = SimpleItoa(
  68. WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
  69. (*variables)["null_check"] =
  70. " if (value == null) {\n"
  71. " throw new NullPointerException();\n"
  72. " }\n";
  73. (*variables)["writeString"] =
  74. "com.google.protobuf.GeneratedMessage" + GeneratedCodeVersionSuffix() +
  75. ".writeString";
  76. (*variables)["computeStringSize"] =
  77. "com.google.protobuf.GeneratedMessage" + GeneratedCodeVersionSuffix() +
  78. ".computeStringSize";
  79. // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
  80. // by the proto compiler
  81. (*variables)["deprecation"] = descriptor->options().deprecated()
  82. ? "@java.lang.Deprecated " : "";
  83. (*variables)["on_changed"] = "onChanged();";
  84. if (SupportFieldPresence(descriptor->file())) {
  85. // For singular messages and builders, one bit is used for the hasField bit.
  86. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
  87. (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
  88. // Note that these have a trailing ";".
  89. (*variables)["set_has_field_bit_message"] =
  90. GenerateSetBit(messageBitIndex) + ";";
  91. (*variables)["set_has_field_bit_builder"] =
  92. GenerateSetBit(builderBitIndex) + ";";
  93. (*variables)["clear_has_field_bit_builder"] =
  94. GenerateClearBit(builderBitIndex) + ";";
  95. (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
  96. } else {
  97. (*variables)["set_has_field_bit_message"] = "";
  98. (*variables)["set_has_field_bit_builder"] = "";
  99. (*variables)["clear_has_field_bit_builder"] = "";
  100. (*variables)["is_field_present_message"] =
  101. "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
  102. }
  103. // For repeated builders, one bit is used for whether the array is immutable.
  104. (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
  105. (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
  106. (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
  107. // For repeated fields, one bit is used for whether the array is immutable
  108. // in the parsing constructor.
  109. (*variables)["get_mutable_bit_parser"] =
  110. GenerateGetBitMutableLocal(builderBitIndex);
  111. (*variables)["set_mutable_bit_parser"] =
  112. GenerateSetBitMutableLocal(builderBitIndex);
  113. (*variables)["get_has_field_bit_from_local"] =
  114. GenerateGetBitFromLocal(builderBitIndex);
  115. (*variables)["set_has_field_bit_to_local"] =
  116. GenerateSetBitToLocal(messageBitIndex);
  117. }
  118. } // namespace
  119. // ===================================================================
  120. ImmutableStringFieldGenerator::
  121. ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
  122. int messageBitIndex,
  123. int builderBitIndex,
  124. Context* context)
  125. : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
  126. builderBitIndex_(builderBitIndex), context_(context),
  127. name_resolver_(context->GetNameResolver()) {
  128. SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
  129. context->GetFieldGeneratorInfo(descriptor),
  130. name_resolver_, &variables_);
  131. }
  132. ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
  133. int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
  134. return 1;
  135. }
  136. int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
  137. return 1;
  138. }
  139. // A note about how strings are handled. This code used to just store a String
  140. // in the Message. This had two issues:
  141. //
  142. // 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
  143. // strings, but rather fields that were raw bytes incorrectly marked
  144. // as strings in the proto file. This is common because in the proto1
  145. // syntax, string was the way to indicate bytes and C++ engineers can
  146. // easily make this mistake without affecting the C++ API. By converting to
  147. // strings immediately, some java code might corrupt these byte arrays as
  148. // it passes through a java server even if the field was never accessed by
  149. // application code.
  150. //
  151. // 2. There's a performance hit to converting between bytes and strings and
  152. // it many cases, the field is never even read by the application code. This
  153. // avoids unnecessary conversions in the common use cases.
  154. //
  155. // So now, the field for String is maintained as an Object reference which can
  156. // either store a String or a ByteString. The code uses an instanceof check
  157. // to see which one it has and converts to the other one if needed. It remembers
  158. // the last value requested (in a thread safe manner) as this is most likely
  159. // the one needed next. The thread safety is such that if two threads both
  160. // convert the field because the changes made by each thread were not visible to
  161. // the other, they may cause a conversion to happen more times than would
  162. // otherwise be necessary. This was deemed better than adding synchronization
  163. // overhead. It will not cause any corruption issues or affect the behavior of
  164. // the API. The instanceof check is also highly optimized in the JVM and we
  165. // decided it was better to reduce the memory overhead by not having two
  166. // separate fields but rather use dynamic type checking.
  167. //
  168. // For single fields, the logic for this is done inside the generated code. For
  169. // repeated fields, the logic is done in LazyStringArrayList and
  170. // UnmodifiableLazyStringList.
  171. void ImmutableStringFieldGenerator::
  172. GenerateInterfaceMembers(io::Printer* printer) const {
  173. if (SupportFieldPresence(descriptor_->file())) {
  174. WriteFieldDocComment(printer, descriptor_);
  175. printer->Print(variables_,
  176. "$deprecation$boolean has$capitalized_name$();\n");
  177. }
  178. WriteFieldDocComment(printer, descriptor_);
  179. printer->Print(variables_,
  180. "$deprecation$java.lang.String get$capitalized_name$();\n");
  181. WriteFieldDocComment(printer, descriptor_);
  182. printer->Print(variables_,
  183. "$deprecation$com.google.protobuf.ByteString\n"
  184. " get$capitalized_name$Bytes();\n");
  185. }
  186. void ImmutableStringFieldGenerator::
  187. GenerateMembers(io::Printer* printer) const {
  188. printer->Print(variables_,
  189. "private volatile java.lang.Object $name$_;\n");
  190. PrintExtraFieldInfo(variables_, printer);
  191. if (SupportFieldPresence(descriptor_->file())) {
  192. WriteFieldDocComment(printer, descriptor_);
  193. printer->Print(variables_,
  194. "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
  195. " return $get_has_field_bit_message$;\n"
  196. "}\n");
  197. printer->Annotate("{", "}", descriptor_);
  198. }
  199. WriteFieldDocComment(printer, descriptor_);
  200. printer->Print(variables_,
  201. "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
  202. " java.lang.Object ref = $name$_;\n"
  203. " if (ref instanceof java.lang.String) {\n"
  204. " return (java.lang.String) ref;\n"
  205. " } else {\n"
  206. " com.google.protobuf.ByteString bs = \n"
  207. " (com.google.protobuf.ByteString) ref;\n"
  208. " java.lang.String s = bs.toStringUtf8();\n");
  209. printer->Annotate("{", "}", descriptor_);
  210. if (CheckUtf8(descriptor_)) {
  211. printer->Print(variables_,
  212. " $name$_ = s;\n");
  213. } else {
  214. printer->Print(variables_,
  215. " if (bs.isValidUtf8()) {\n"
  216. " $name$_ = s;\n"
  217. " }\n");
  218. }
  219. printer->Print(variables_,
  220. " return s;\n"
  221. " }\n"
  222. "}\n");
  223. WriteFieldDocComment(printer, descriptor_);
  224. printer->Print(variables_,
  225. "$deprecation$public com.google.protobuf.ByteString\n"
  226. " ${$get$capitalized_name$Bytes$}$() {\n"
  227. " java.lang.Object ref = $name$_;\n"
  228. " if (ref instanceof java.lang.String) {\n"
  229. " com.google.protobuf.ByteString b = \n"
  230. " com.google.protobuf.ByteString.copyFromUtf8(\n"
  231. " (java.lang.String) ref);\n"
  232. " $name$_ = b;\n"
  233. " return b;\n"
  234. " } else {\n"
  235. " return (com.google.protobuf.ByteString) ref;\n"
  236. " }\n"
  237. "}\n");
  238. printer->Annotate("{", "}", descriptor_);
  239. }
  240. void ImmutableStringFieldGenerator::
  241. GenerateBuilderMembers(io::Printer* printer) const {
  242. printer->Print(variables_,
  243. "private java.lang.Object $name$_ $default_init$;\n");
  244. if (SupportFieldPresence(descriptor_->file())) {
  245. WriteFieldDocComment(printer, descriptor_);
  246. printer->Print(variables_,
  247. "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
  248. " return $get_has_field_bit_builder$;\n"
  249. "}\n");
  250. printer->Annotate("{", "}", descriptor_);
  251. }
  252. WriteFieldDocComment(printer, descriptor_);
  253. printer->Print(variables_,
  254. "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
  255. " java.lang.Object ref = $name$_;\n"
  256. " if (!(ref instanceof java.lang.String)) {\n"
  257. " com.google.protobuf.ByteString bs =\n"
  258. " (com.google.protobuf.ByteString) ref;\n"
  259. " java.lang.String s = bs.toStringUtf8();\n");
  260. printer->Annotate("{", "}", descriptor_);
  261. if (CheckUtf8(descriptor_)) {
  262. printer->Print(variables_,
  263. " $name$_ = s;\n");
  264. } else {
  265. printer->Print(variables_,
  266. " if (bs.isValidUtf8()) {\n"
  267. " $name$_ = s;\n"
  268. " }\n");
  269. }
  270. printer->Print(variables_,
  271. " return s;\n"
  272. " } else {\n"
  273. " return (java.lang.String) ref;\n"
  274. " }\n"
  275. "}\n");
  276. WriteFieldDocComment(printer, descriptor_);
  277. printer->Print(variables_,
  278. "$deprecation$public com.google.protobuf.ByteString\n"
  279. " ${$get$capitalized_name$Bytes$}$() {\n"
  280. " java.lang.Object ref = $name$_;\n"
  281. " if (ref instanceof String) {\n"
  282. " com.google.protobuf.ByteString b = \n"
  283. " com.google.protobuf.ByteString.copyFromUtf8(\n"
  284. " (java.lang.String) ref);\n"
  285. " $name$_ = b;\n"
  286. " return b;\n"
  287. " } else {\n"
  288. " return (com.google.protobuf.ByteString) ref;\n"
  289. " }\n"
  290. "}\n");
  291. printer->Annotate("{", "}", descriptor_);
  292. WriteFieldDocComment(printer, descriptor_);
  293. printer->Print(variables_,
  294. "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
  295. " java.lang.String value) {\n"
  296. "$null_check$"
  297. " $set_has_field_bit_builder$\n"
  298. " $name$_ = value;\n"
  299. " $on_changed$\n"
  300. " return this;\n"
  301. "}\n");
  302. printer->Annotate("{", "}", descriptor_);
  303. WriteFieldDocComment(printer, descriptor_);
  304. printer->Print(variables_,
  305. "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
  306. " $clear_has_field_bit_builder$\n");
  307. printer->Annotate("{", "}", descriptor_);
  308. // The default value is not a simple literal so we want to avoid executing
  309. // it multiple times. Instead, get the default out of the default instance.
  310. printer->Print(variables_,
  311. " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
  312. printer->Print(variables_,
  313. " $on_changed$\n"
  314. " return this;\n"
  315. "}\n");
  316. WriteFieldDocComment(printer, descriptor_);
  317. printer->Print(variables_,
  318. "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
  319. " com.google.protobuf.ByteString value) {\n"
  320. "$null_check$");
  321. printer->Annotate("{", "}", descriptor_);
  322. if (CheckUtf8(descriptor_)) {
  323. printer->Print(variables_,
  324. " checkByteStringIsUtf8(value);\n");
  325. }
  326. printer->Print(variables_,
  327. " $set_has_field_bit_builder$\n"
  328. " $name$_ = value;\n"
  329. " $on_changed$\n"
  330. " return this;\n"
  331. "}\n");
  332. }
  333. void ImmutableStringFieldGenerator::
  334. GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
  335. // noop for primitives
  336. }
  337. void ImmutableStringFieldGenerator::
  338. GenerateInitializationCode(io::Printer* printer) const {
  339. printer->Print(variables_, "$name$_ = $default$;\n");
  340. }
  341. void ImmutableStringFieldGenerator::
  342. GenerateBuilderClearCode(io::Printer* printer) const {
  343. printer->Print(variables_,
  344. "$name$_ = $default$;\n"
  345. "$clear_has_field_bit_builder$\n");
  346. }
  347. void ImmutableStringFieldGenerator::
  348. GenerateMergingCode(io::Printer* printer) const {
  349. if (SupportFieldPresence(descriptor_->file())) {
  350. // Allow a slight breach of abstraction here in order to avoid forcing
  351. // all string fields to Strings when copying fields from a Message.
  352. printer->Print(variables_,
  353. "if (other.has$capitalized_name$()) {\n"
  354. " $set_has_field_bit_builder$\n"
  355. " $name$_ = other.$name$_;\n"
  356. " $on_changed$\n"
  357. "}\n");
  358. } else {
  359. printer->Print(variables_,
  360. "if (!other.get$capitalized_name$().isEmpty()) {\n"
  361. " $name$_ = other.$name$_;\n"
  362. " $on_changed$\n"
  363. "}\n");
  364. }
  365. }
  366. void ImmutableStringFieldGenerator::
  367. GenerateBuildingCode(io::Printer* printer) const {
  368. if (SupportFieldPresence(descriptor_->file())) {
  369. printer->Print(variables_,
  370. "if ($get_has_field_bit_from_local$) {\n"
  371. " $set_has_field_bit_to_local$;\n"
  372. "}\n");
  373. }
  374. printer->Print(variables_,
  375. "result.$name$_ = $name$_;\n");
  376. }
  377. void ImmutableStringFieldGenerator::
  378. GenerateParsingCode(io::Printer* printer) const {
  379. if (CheckUtf8(descriptor_)) {
  380. printer->Print(variables_,
  381. "java.lang.String s = input.readStringRequireUtf8();\n"
  382. "$set_has_field_bit_message$\n"
  383. "$name$_ = s;\n");
  384. } else {
  385. printer->Print(variables_,
  386. "com.google.protobuf.ByteString bs = input.readBytes();\n"
  387. "$set_has_field_bit_message$\n"
  388. "$name$_ = bs;\n");
  389. }
  390. }
  391. void ImmutableStringFieldGenerator::
  392. GenerateParsingDoneCode(io::Printer* printer) const {
  393. // noop for strings.
  394. }
  395. void ImmutableStringFieldGenerator::
  396. GenerateSerializationCode(io::Printer* printer) const {
  397. printer->Print(variables_,
  398. "if ($is_field_present_message$) {\n"
  399. " $writeString$(output, $number$, $name$_);\n"
  400. "}\n");
  401. }
  402. void ImmutableStringFieldGenerator::
  403. GenerateSerializedSizeCode(io::Printer* printer) const {
  404. printer->Print(variables_,
  405. "if ($is_field_present_message$) {\n"
  406. " size += $computeStringSize$($number$, $name$_);\n"
  407. "}\n");
  408. }
  409. void ImmutableStringFieldGenerator::
  410. GenerateEqualsCode(io::Printer* printer) const {
  411. printer->Print(variables_,
  412. "result = result && get$capitalized_name$()\n"
  413. " .equals(other.get$capitalized_name$());\n");
  414. }
  415. void ImmutableStringFieldGenerator::
  416. GenerateHashCode(io::Printer* printer) const {
  417. printer->Print(variables_,
  418. "hash = (37 * hash) + $constant_name$;\n");
  419. printer->Print(variables_,
  420. "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
  421. }
  422. string ImmutableStringFieldGenerator::GetBoxedType() const {
  423. return "java.lang.String";
  424. }
  425. // ===================================================================
  426. ImmutableStringOneofFieldGenerator::
  427. ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
  428. int messageBitIndex,
  429. int builderBitIndex,
  430. Context* context)
  431. : ImmutableStringFieldGenerator(
  432. descriptor, messageBitIndex, builderBitIndex, context) {
  433. const OneofGeneratorInfo* info =
  434. context->GetOneofGeneratorInfo(descriptor->containing_oneof());
  435. SetCommonOneofVariables(descriptor, info, &variables_);
  436. }
  437. ImmutableStringOneofFieldGenerator::
  438. ~ImmutableStringOneofFieldGenerator() {}
  439. void ImmutableStringOneofFieldGenerator::
  440. GenerateMembers(io::Printer* printer) const {
  441. PrintExtraFieldInfo(variables_, printer);
  442. if (SupportFieldPresence(descriptor_->file())) {
  443. WriteFieldDocComment(printer, descriptor_);
  444. printer->Print(variables_,
  445. "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
  446. " return $has_oneof_case_message$;\n"
  447. "}\n");
  448. printer->Annotate("{", "}", descriptor_);
  449. }
  450. WriteFieldDocComment(printer, descriptor_);
  451. printer->Print(variables_,
  452. "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
  453. " java.lang.Object ref $default_init$;\n"
  454. " if ($has_oneof_case_message$) {\n"
  455. " ref = $oneof_name$_;\n"
  456. " }\n"
  457. " if (ref instanceof java.lang.String) {\n"
  458. " return (java.lang.String) ref;\n"
  459. " } else {\n"
  460. " com.google.protobuf.ByteString bs = \n"
  461. " (com.google.protobuf.ByteString) ref;\n"
  462. " java.lang.String s = bs.toStringUtf8();\n");
  463. printer->Annotate("{", "}", descriptor_);
  464. if (CheckUtf8(descriptor_)) {
  465. printer->Print(variables_,
  466. " if ($has_oneof_case_message$) {\n"
  467. " $oneof_name$_ = s;\n"
  468. " }\n");
  469. } else {
  470. printer->Print(variables_,
  471. " if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
  472. " $oneof_name$_ = s;\n"
  473. " }\n");
  474. }
  475. printer->Print(variables_,
  476. " return s;\n"
  477. " }\n"
  478. "}\n");
  479. WriteFieldDocComment(printer, descriptor_);
  480. printer->Print(variables_,
  481. "$deprecation$public com.google.protobuf.ByteString\n"
  482. " ${$get$capitalized_name$Bytes$}$() {\n"
  483. " java.lang.Object ref $default_init$;\n"
  484. " if ($has_oneof_case_message$) {\n"
  485. " ref = $oneof_name$_;\n"
  486. " }\n"
  487. " if (ref instanceof java.lang.String) {\n"
  488. " com.google.protobuf.ByteString b = \n"
  489. " com.google.protobuf.ByteString.copyFromUtf8(\n"
  490. " (java.lang.String) ref);\n"
  491. " if ($has_oneof_case_message$) {\n"
  492. " $oneof_name$_ = b;\n"
  493. " }\n"
  494. " return b;\n"
  495. " } else {\n"
  496. " return (com.google.protobuf.ByteString) ref;\n"
  497. " }\n"
  498. "}\n");
  499. printer->Annotate("{", "}", descriptor_);
  500. }
  501. void ImmutableStringOneofFieldGenerator::
  502. GenerateBuilderMembers(io::Printer* printer) const {
  503. if (SupportFieldPresence(descriptor_->file())) {
  504. WriteFieldDocComment(printer, descriptor_);
  505. printer->Print(variables_,
  506. "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
  507. " return $has_oneof_case_message$;\n"
  508. "}\n");
  509. printer->Annotate("{", "}", descriptor_);
  510. }
  511. WriteFieldDocComment(printer, descriptor_);
  512. printer->Print(variables_,
  513. "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
  514. " java.lang.Object ref $default_init$;\n"
  515. " if ($has_oneof_case_message$) {\n"
  516. " ref = $oneof_name$_;\n"
  517. " }\n"
  518. " if (!(ref instanceof java.lang.String)) {\n"
  519. " com.google.protobuf.ByteString bs =\n"
  520. " (com.google.protobuf.ByteString) ref;\n"
  521. " java.lang.String s = bs.toStringUtf8();\n"
  522. " if ($has_oneof_case_message$) {\n");
  523. printer->Annotate("{", "}", descriptor_);
  524. if (CheckUtf8(descriptor_)) {
  525. printer->Print(variables_,
  526. " $oneof_name$_ = s;\n");
  527. } else {
  528. printer->Print(variables_,
  529. " if (bs.isValidUtf8()) {\n"
  530. " $oneof_name$_ = s;\n"
  531. " }\n");
  532. }
  533. printer->Print(variables_,
  534. " }\n"
  535. " return s;\n"
  536. " } else {\n"
  537. " return (java.lang.String) ref;\n"
  538. " }\n"
  539. "}\n");
  540. WriteFieldDocComment(printer, descriptor_);
  541. printer->Print(variables_,
  542. "$deprecation$public com.google.protobuf.ByteString\n"
  543. " ${$get$capitalized_name$Bytes$}$() {\n"
  544. " java.lang.Object ref $default_init$;\n"
  545. " if ($has_oneof_case_message$) {\n"
  546. " ref = $oneof_name$_;\n"
  547. " }\n"
  548. " if (ref instanceof String) {\n"
  549. " com.google.protobuf.ByteString b = \n"
  550. " com.google.protobuf.ByteString.copyFromUtf8(\n"
  551. " (java.lang.String) ref);\n"
  552. " if ($has_oneof_case_message$) {\n"
  553. " $oneof_name$_ = b;\n"
  554. " }\n"
  555. " return b;\n"
  556. " } else {\n"
  557. " return (com.google.protobuf.ByteString) ref;\n"
  558. " }\n"
  559. "}\n");
  560. printer->Annotate("{", "}", descriptor_);
  561. WriteFieldDocComment(printer, descriptor_);
  562. printer->Print(variables_,
  563. "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
  564. " java.lang.String value) {\n"
  565. "$null_check$"
  566. " $set_oneof_case_message$;\n"
  567. " $oneof_name$_ = value;\n"
  568. " $on_changed$\n"
  569. " return this;\n"
  570. "}\n");
  571. printer->Annotate("{", "}", descriptor_);
  572. WriteFieldDocComment(printer, descriptor_);
  573. printer->Print(variables_,
  574. "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
  575. " if ($has_oneof_case_message$) {\n"
  576. " $clear_oneof_case_message$;\n"
  577. " $oneof_name$_ = null;\n"
  578. " $on_changed$\n"
  579. " }\n"
  580. " return this;\n"
  581. "}\n");
  582. printer->Annotate("{", "}", descriptor_);
  583. WriteFieldDocComment(printer, descriptor_);
  584. printer->Print(variables_,
  585. "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
  586. " com.google.protobuf.ByteString value) {\n"
  587. "$null_check$");
  588. printer->Annotate("{", "}", descriptor_);
  589. if (CheckUtf8(descriptor_)) {
  590. printer->Print(variables_,
  591. " checkByteStringIsUtf8(value);\n");
  592. }
  593. printer->Print(variables_,
  594. " $set_oneof_case_message$;\n"
  595. " $oneof_name$_ = value;\n"
  596. " $on_changed$\n"
  597. " return this;\n"
  598. "}\n");
  599. }
  600. void ImmutableStringOneofFieldGenerator::
  601. GenerateMergingCode(io::Printer* printer) const {
  602. // Allow a slight breach of abstraction here in order to avoid forcing
  603. // all string fields to Strings when copying fields from a Message.
  604. printer->Print(variables_,
  605. "$set_oneof_case_message$;\n"
  606. "$oneof_name$_ = other.$oneof_name$_;\n"
  607. "$on_changed$\n");
  608. }
  609. void ImmutableStringOneofFieldGenerator::
  610. GenerateBuildingCode(io::Printer* printer) const {
  611. printer->Print(variables_,
  612. "if ($has_oneof_case_message$) {\n"
  613. " result.$oneof_name$_ = $oneof_name$_;\n"
  614. "}\n");
  615. }
  616. void ImmutableStringOneofFieldGenerator::
  617. GenerateParsingCode(io::Printer* printer) const {
  618. if (CheckUtf8(descriptor_)) {
  619. printer->Print(variables_,
  620. "java.lang.String s = input.readStringRequireUtf8();\n"
  621. "$set_oneof_case_message$;\n"
  622. "$oneof_name$_ = s;\n");
  623. } else {
  624. printer->Print(variables_,
  625. "com.google.protobuf.ByteString bs = input.readBytes();\n"
  626. "$set_oneof_case_message$;\n"
  627. "$oneof_name$_ = bs;\n");
  628. }
  629. }
  630. void ImmutableStringOneofFieldGenerator::
  631. GenerateSerializationCode(io::Printer* printer) const {
  632. printer->Print(variables_,
  633. "if ($has_oneof_case_message$) {\n"
  634. " $writeString$(output, $number$, $oneof_name$_);\n"
  635. "}\n");
  636. }
  637. void ImmutableStringOneofFieldGenerator::
  638. GenerateSerializedSizeCode(io::Printer* printer) const {
  639. printer->Print(variables_,
  640. "if ($has_oneof_case_message$) {\n"
  641. " size += $computeStringSize$($number$, $oneof_name$_);\n"
  642. "}\n");
  643. }
  644. // ===================================================================
  645. RepeatedImmutableStringFieldGenerator::
  646. RepeatedImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
  647. int messageBitIndex,
  648. int builderBitIndex,
  649. Context* context)
  650. : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
  651. builderBitIndex_(builderBitIndex), context_(context),
  652. name_resolver_(context->GetNameResolver()) {
  653. SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
  654. context->GetFieldGeneratorInfo(descriptor),
  655. name_resolver_, &variables_);
  656. }
  657. RepeatedImmutableStringFieldGenerator::
  658. ~RepeatedImmutableStringFieldGenerator() {}
  659. int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const {
  660. return 0;
  661. }
  662. int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
  663. return 1;
  664. }
  665. void RepeatedImmutableStringFieldGenerator::
  666. GenerateInterfaceMembers(io::Printer* printer) const {
  667. WriteFieldDocComment(printer, descriptor_);
  668. printer->Print(variables_,
  669. // NOTE: the same method in the implementation class actually returns
  670. // com.google.protobuf.ProtocolStringList (a subclass of List). It's
  671. // changed between protobuf 2.5.0 release and protobuf 2.6.1 release.
  672. // To retain binary compatibility with both 2.5.0 and 2.6.1 generated
  673. // code, we make this interface method return List so both methods
  674. // with different return types exist in the compiled byte code.
  675. "$deprecation$java.util.List<java.lang.String>\n"
  676. " get$capitalized_name$List();\n");
  677. WriteFieldDocComment(printer, descriptor_);
  678. printer->Print(variables_,
  679. "$deprecation$int get$capitalized_name$Count();\n");
  680. WriteFieldDocComment(printer, descriptor_);
  681. printer->Print(variables_,
  682. "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
  683. WriteFieldDocComment(printer, descriptor_);
  684. printer->Print(variables_,
  685. "$deprecation$com.google.protobuf.ByteString\n"
  686. " get$capitalized_name$Bytes(int index);\n");
  687. }
  688. void RepeatedImmutableStringFieldGenerator::
  689. GenerateMembers(io::Printer* printer) const {
  690. printer->Print(variables_,
  691. "private com.google.protobuf.LazyStringList $name$_;\n");
  692. PrintExtraFieldInfo(variables_, printer);
  693. WriteFieldDocComment(printer, descriptor_);
  694. printer->Print(variables_,
  695. "$deprecation$public com.google.protobuf.ProtocolStringList\n"
  696. " ${$get$capitalized_name$List$}$() {\n"
  697. " return $name$_;\n" // note: unmodifiable list
  698. "}\n");
  699. printer->Annotate("{", "}", descriptor_);
  700. WriteFieldDocComment(printer, descriptor_);
  701. printer->Print(variables_,
  702. "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
  703. " return $name$_.size();\n"
  704. "}\n");
  705. printer->Annotate("{", "}", descriptor_);
  706. WriteFieldDocComment(printer, descriptor_);
  707. printer->Print(variables_,
  708. "$deprecation$public java.lang.String "
  709. "${$get$capitalized_name$$}$(int index) {\n"
  710. " return $name$_.get(index);\n"
  711. "}\n");
  712. printer->Annotate("{", "}", descriptor_);
  713. WriteFieldDocComment(printer, descriptor_);
  714. printer->Print(variables_,
  715. "$deprecation$public com.google.protobuf.ByteString\n"
  716. " ${$get$capitalized_name$Bytes$}$(int index) {\n"
  717. " return $name$_.getByteString(index);\n"
  718. "}\n");
  719. printer->Annotate("{", "}", descriptor_);
  720. }
  721. void RepeatedImmutableStringFieldGenerator::
  722. GenerateBuilderMembers(io::Printer* printer) const {
  723. // One field is the list and the bit field keeps track of whether the
  724. // list is immutable. If it's immutable, the invariant is that it must
  725. // either an instance of Collections.emptyList() or it's an ArrayList
  726. // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
  727. // a refererence to the underlying ArrayList. This invariant allows us to
  728. // share instances of lists between protocol buffers avoiding expensive
  729. // memory allocations. Note, immutable is a strong guarantee here -- not
  730. // just that the list cannot be modified via the reference but that the
  731. // list can never be modified.
  732. printer->Print(variables_,
  733. "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
  734. printer->Print(variables_,
  735. "private void ensure$capitalized_name$IsMutable() {\n"
  736. " if (!$get_mutable_bit_builder$) {\n"
  737. " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
  738. " $set_mutable_bit_builder$;\n"
  739. " }\n"
  740. "}\n");
  741. // Note: We return an unmodifiable list because otherwise the caller
  742. // could hold on to the returned list and modify it after the message
  743. // has been built, thus mutating the message which is supposed to be
  744. // immutable.
  745. WriteFieldDocComment(printer, descriptor_);
  746. printer->Print(variables_,
  747. "$deprecation$public com.google.protobuf.ProtocolStringList\n"
  748. " ${$get$capitalized_name$List$}$() {\n"
  749. " return $name$_.getUnmodifiableView();\n"
  750. "}\n");
  751. printer->Annotate("{", "}", descriptor_);
  752. WriteFieldDocComment(printer, descriptor_);
  753. printer->Print(variables_,
  754. "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
  755. " return $name$_.size();\n"
  756. "}\n");
  757. printer->Annotate("{", "}", descriptor_);
  758. WriteFieldDocComment(printer, descriptor_);
  759. printer->Print(variables_,
  760. "$deprecation$public java.lang.String "
  761. "${$get$capitalized_name$$}$(int index) {\n"
  762. " return $name$_.get(index);\n"
  763. "}\n");
  764. printer->Annotate("{", "}", descriptor_);
  765. WriteFieldDocComment(printer, descriptor_);
  766. printer->Print(variables_,
  767. "$deprecation$public com.google.protobuf.ByteString\n"
  768. " ${$get$capitalized_name$Bytes$}$(int index) {\n"
  769. " return $name$_.getByteString(index);\n"
  770. "}\n");
  771. printer->Annotate("{", "}", descriptor_);
  772. WriteFieldDocComment(printer, descriptor_);
  773. printer->Print(variables_,
  774. "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
  775. " int index, java.lang.String value) {\n"
  776. "$null_check$"
  777. " ensure$capitalized_name$IsMutable();\n"
  778. " $name$_.set(index, value);\n"
  779. " $on_changed$\n"
  780. " return this;\n"
  781. "}\n");
  782. printer->Annotate("{", "}", descriptor_);
  783. WriteFieldDocComment(printer, descriptor_);
  784. printer->Print(variables_,
  785. "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
  786. " java.lang.String value) {\n"
  787. "$null_check$"
  788. " ensure$capitalized_name$IsMutable();\n"
  789. " $name$_.add(value);\n"
  790. " $on_changed$\n"
  791. " return this;\n"
  792. "}\n");
  793. printer->Annotate("{", "}", descriptor_);
  794. WriteFieldDocComment(printer, descriptor_);
  795. printer->Print(variables_,
  796. "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
  797. " java.lang.Iterable<java.lang.String> values) {\n"
  798. " ensure$capitalized_name$IsMutable();\n"
  799. " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
  800. " values, $name$_);\n"
  801. " $on_changed$\n"
  802. " return this;\n"
  803. "}\n");
  804. printer->Annotate("{", "}", descriptor_);
  805. WriteFieldDocComment(printer, descriptor_);
  806. printer->Print(variables_,
  807. "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
  808. " $name$_ = $empty_list$;\n"
  809. " $clear_mutable_bit_builder$;\n"
  810. " $on_changed$\n"
  811. " return this;\n"
  812. "}\n");
  813. printer->Annotate("{", "}", descriptor_);
  814. WriteFieldDocComment(printer, descriptor_);
  815. printer->Print(variables_,
  816. "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n"
  817. " com.google.protobuf.ByteString value) {\n"
  818. "$null_check$");
  819. printer->Annotate("{", "}", descriptor_);
  820. if (CheckUtf8(descriptor_)) {
  821. printer->Print(variables_,
  822. " checkByteStringIsUtf8(value);\n");
  823. }
  824. printer->Print(variables_,
  825. " ensure$capitalized_name$IsMutable();\n"
  826. " $name$_.add(value);\n"
  827. " $on_changed$\n"
  828. " return this;\n"
  829. "}\n");
  830. }
  831. void RepeatedImmutableStringFieldGenerator::
  832. GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
  833. // noop for primitives
  834. }
  835. void RepeatedImmutableStringFieldGenerator::
  836. GenerateInitializationCode(io::Printer* printer) const {
  837. printer->Print(variables_, "$name$_ = $empty_list$;\n");
  838. }
  839. void RepeatedImmutableStringFieldGenerator::
  840. GenerateBuilderClearCode(io::Printer* printer) const {
  841. printer->Print(variables_,
  842. "$name$_ = $empty_list$;\n"
  843. "$clear_mutable_bit_builder$;\n");
  844. }
  845. void RepeatedImmutableStringFieldGenerator::
  846. GenerateMergingCode(io::Printer* printer) const {
  847. // The code below does two optimizations:
  848. // 1. If the other list is empty, there's nothing to do. This ensures we
  849. // don't allocate a new array if we already have an immutable one.
  850. // 2. If the other list is non-empty and our current list is empty, we can
  851. // reuse the other list which is guaranteed to be immutable.
  852. printer->Print(variables_,
  853. "if (!other.$name$_.isEmpty()) {\n"
  854. " if ($name$_.isEmpty()) {\n"
  855. " $name$_ = other.$name$_;\n"
  856. " $clear_mutable_bit_builder$;\n"
  857. " } else {\n"
  858. " ensure$capitalized_name$IsMutable();\n"
  859. " $name$_.addAll(other.$name$_);\n"
  860. " }\n"
  861. " $on_changed$\n"
  862. "}\n");
  863. }
  864. void RepeatedImmutableStringFieldGenerator::
  865. GenerateBuildingCode(io::Printer* printer) const {
  866. // The code below ensures that the result has an immutable list. If our
  867. // list is immutable, we can just reuse it. If not, we make it immutable.
  868. printer->Print(variables_,
  869. "if ($get_mutable_bit_builder$) {\n"
  870. " $name$_ = $name$_.getUnmodifiableView();\n"
  871. " $clear_mutable_bit_builder$;\n"
  872. "}\n"
  873. "result.$name$_ = $name$_;\n");
  874. }
  875. void RepeatedImmutableStringFieldGenerator::
  876. GenerateParsingCode(io::Printer* printer) const {
  877. if (CheckUtf8(descriptor_)) {
  878. printer->Print(variables_,
  879. "java.lang.String s = input.readStringRequireUtf8();\n");
  880. } else {
  881. printer->Print(variables_,
  882. "com.google.protobuf.ByteString bs = input.readBytes();\n");
  883. }
  884. printer->Print(variables_,
  885. "if (!$get_mutable_bit_parser$) {\n"
  886. " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
  887. " $set_mutable_bit_parser$;\n"
  888. "}\n");
  889. if (CheckUtf8(descriptor_)) {
  890. printer->Print(variables_,
  891. "$name$_.add(s);\n");
  892. } else {
  893. printer->Print(variables_,
  894. "$name$_.add(bs);\n");
  895. }
  896. }
  897. void RepeatedImmutableStringFieldGenerator::
  898. GenerateParsingDoneCode(io::Printer* printer) const {
  899. printer->Print(variables_,
  900. "if ($get_mutable_bit_parser$) {\n"
  901. " $name$_ = $name$_.getUnmodifiableView();\n"
  902. "}\n");
  903. }
  904. void RepeatedImmutableStringFieldGenerator::
  905. GenerateSerializationCode(io::Printer* printer) const {
  906. printer->Print(variables_,
  907. "for (int i = 0; i < $name$_.size(); i++) {\n"
  908. " $writeString$(output, $number$, $name$_.getRaw(i));\n"
  909. "}\n");
  910. }
  911. void RepeatedImmutableStringFieldGenerator::
  912. GenerateSerializedSizeCode(io::Printer* printer) const {
  913. printer->Print(variables_,
  914. "{\n"
  915. " int dataSize = 0;\n");
  916. printer->Indent();
  917. printer->Print(variables_,
  918. "for (int i = 0; i < $name$_.size(); i++) {\n"
  919. " dataSize += computeStringSizeNoTag($name$_.getRaw(i));\n"
  920. "}\n");
  921. printer->Print(
  922. "size += dataSize;\n");
  923. printer->Print(variables_,
  924. "size += $tag_size$ * get$capitalized_name$List().size();\n");
  925. printer->Outdent();
  926. printer->Print("}\n");
  927. }
  928. void RepeatedImmutableStringFieldGenerator::
  929. GenerateEqualsCode(io::Printer* printer) const {
  930. printer->Print(variables_,
  931. "result = result && get$capitalized_name$List()\n"
  932. " .equals(other.get$capitalized_name$List());\n");
  933. }
  934. void RepeatedImmutableStringFieldGenerator::
  935. GenerateHashCode(io::Printer* printer) const {
  936. printer->Print(variables_,
  937. "if (get$capitalized_name$Count() > 0) {\n"
  938. " hash = (37 * hash) + $constant_name$;\n"
  939. " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
  940. "}\n");
  941. }
  942. string RepeatedImmutableStringFieldGenerator::GetBoxedType() const {
  943. return "String";
  944. }
  945. } // namespace java
  946. } // namespace compiler
  947. } // namespace protobuf
  948. } // namespace google