PageRenderTime 51ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/src/google/protobuf/compiler/java/java_string_field.cc

http://protobuf.googlecode.com/
C++ | 726 lines | 551 code | 74 blank | 101 comment | 6 complexity | 9fef8ae7d348629d9936b3815698a377 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  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/compiler/java/java_string_field.h>
  37. #include <google/protobuf/compiler/java/java_doc_comment.h>
  38. #include <google/protobuf/stubs/common.h>
  39. #include <google/protobuf/compiler/java/java_helpers.h>
  40. #include <google/protobuf/io/printer.h>
  41. #include <google/protobuf/wire_format.h>
  42. #include <google/protobuf/stubs/strutil.h>
  43. namespace google {
  44. namespace protobuf {
  45. namespace compiler {
  46. namespace java {
  47. using internal::WireFormat;
  48. using internal::WireFormatLite;
  49. namespace {
  50. void SetPrimitiveVariables(const FieldDescriptor* descriptor,
  51. int messageBitIndex,
  52. int builderBitIndex,
  53. map<string, string>* variables) {
  54. (*variables)["name"] =
  55. UnderscoresToCamelCase(descriptor);
  56. (*variables)["capitalized_name"] =
  57. UnderscoresToCapitalizedCamelCase(descriptor);
  58. (*variables)["constant_name"] = FieldConstantName(descriptor);
  59. (*variables)["number"] = SimpleItoa(descriptor->number());
  60. (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
  61. (*variables)["default"] = DefaultValue(descriptor);
  62. (*variables)["default_init"] = ("= " + DefaultValue(descriptor));
  63. (*variables)["capitalized_type"] = "String";
  64. (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
  65. (*variables)["tag_size"] = SimpleItoa(
  66. WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
  67. (*variables)["null_check"] =
  68. " if (value == null) {\n"
  69. " throw new NullPointerException();\n"
  70. " }\n";
  71. // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
  72. // by the proto compiler
  73. (*variables)["deprecation"] = descriptor->options().deprecated()
  74. ? "@java.lang.Deprecated " : "";
  75. (*variables)["on_changed"] =
  76. HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
  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)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex);
  80. (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
  81. (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
  82. (*variables)["clear_has_field_bit_builder"] =
  83. GenerateClearBit(builderBitIndex);
  84. // For repated builders, one bit is used for whether the array is immutable.
  85. (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
  86. (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
  87. (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
  88. // For repeated fields, one bit is used for whether the array is immutable
  89. // in the parsing constructor.
  90. (*variables)["get_mutable_bit_parser"] =
  91. GenerateGetBitMutableLocal(builderBitIndex);
  92. (*variables)["set_mutable_bit_parser"] =
  93. GenerateSetBitMutableLocal(builderBitIndex);
  94. (*variables)["get_has_field_bit_from_local"] =
  95. GenerateGetBitFromLocal(builderBitIndex);
  96. (*variables)["set_has_field_bit_to_local"] =
  97. GenerateSetBitToLocal(messageBitIndex);
  98. }
  99. } // namespace
  100. // ===================================================================
  101. StringFieldGenerator::
  102. StringFieldGenerator(const FieldDescriptor* descriptor,
  103. int messageBitIndex,
  104. int builderBitIndex)
  105. : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
  106. builderBitIndex_(builderBitIndex) {
  107. SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
  108. &variables_);
  109. }
  110. StringFieldGenerator::~StringFieldGenerator() {}
  111. int StringFieldGenerator::GetNumBitsForMessage() const {
  112. return 1;
  113. }
  114. int StringFieldGenerator::GetNumBitsForBuilder() const {
  115. return 1;
  116. }
  117. // A note about how strings are handled. This code used to just store a String
  118. // in the Message. This had two issues:
  119. //
  120. // 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
  121. // strings, but rather fields that were raw bytes incorrectly marked
  122. // as strings in the proto file. This is common because in the proto1
  123. // syntax, string was the way to indicate bytes and C++ engineers can
  124. // easily make this mistake without affecting the C++ API. By converting to
  125. // strings immediately, some java code might corrupt these byte arrays as
  126. // it passes through a java server even if the field was never accessed by
  127. // application code.
  128. //
  129. // 2. There's a performance hit to converting between bytes and strings and
  130. // it many cases, the field is never even read by the application code. This
  131. // avoids unnecessary conversions in the common use cases.
  132. //
  133. // So now, the field for String is maintained as an Object reference which can
  134. // either store a String or a ByteString. The code uses an instanceof check
  135. // to see which one it has and converts to the other one if needed. It remembers
  136. // the last value requested (in a thread safe manner) as this is most likely
  137. // the one needed next. The thread safety is such that if two threads both
  138. // convert the field because the changes made by each thread were not visible to
  139. // the other, they may cause a conversion to happen more times than would
  140. // otherwise be necessary. This was deemed better than adding synchronization
  141. // overhead. It will not cause any corruption issues or affect the behavior of
  142. // the API. The instanceof check is also highly optimized in the JVM and we
  143. // decided it was better to reduce the memory overhead by not having two
  144. // separate fields but rather use dynamic type checking.
  145. //
  146. // For single fields, the logic for this is done inside the generated code. For
  147. // repeated fields, the logic is done in LazyStringArrayList and
  148. // UnmodifiableLazyStringList.
  149. void StringFieldGenerator::
  150. GenerateInterfaceMembers(io::Printer* printer) const {
  151. WriteFieldDocComment(printer, descriptor_);
  152. printer->Print(variables_,
  153. "$deprecation$boolean has$capitalized_name$();\n");
  154. WriteFieldDocComment(printer, descriptor_);
  155. printer->Print(variables_,
  156. "$deprecation$java.lang.String get$capitalized_name$();\n");
  157. WriteFieldDocComment(printer, descriptor_);
  158. printer->Print(variables_,
  159. "$deprecation$com.google.protobuf.ByteString\n"
  160. " get$capitalized_name$Bytes();\n");
  161. }
  162. void StringFieldGenerator::
  163. GenerateMembers(io::Printer* printer) const {
  164. printer->Print(variables_,
  165. "private java.lang.Object $name$_;\n");
  166. WriteFieldDocComment(printer, descriptor_);
  167. printer->Print(variables_,
  168. "$deprecation$public boolean has$capitalized_name$() {\n"
  169. " return $get_has_field_bit_message$;\n"
  170. "}\n");
  171. WriteFieldDocComment(printer, descriptor_);
  172. printer->Print(variables_,
  173. "$deprecation$public java.lang.String get$capitalized_name$() {\n"
  174. " java.lang.Object ref = $name$_;\n"
  175. " if (ref instanceof java.lang.String) {\n"
  176. " return (java.lang.String) ref;\n"
  177. " } else {\n"
  178. " com.google.protobuf.ByteString bs = \n"
  179. " (com.google.protobuf.ByteString) ref;\n"
  180. " java.lang.String s = bs.toStringUtf8();\n"
  181. " if (bs.isValidUtf8()) {\n"
  182. " $name$_ = s;\n"
  183. " }\n"
  184. " return s;\n"
  185. " }\n"
  186. "}\n");
  187. WriteFieldDocComment(printer, descriptor_);
  188. printer->Print(variables_,
  189. "$deprecation$public com.google.protobuf.ByteString\n"
  190. " get$capitalized_name$Bytes() {\n"
  191. " java.lang.Object ref = $name$_;\n"
  192. " if (ref instanceof java.lang.String) {\n"
  193. " com.google.protobuf.ByteString b = \n"
  194. " com.google.protobuf.ByteString.copyFromUtf8(\n"
  195. " (java.lang.String) ref);\n"
  196. " $name$_ = b;\n"
  197. " return b;\n"
  198. " } else {\n"
  199. " return (com.google.protobuf.ByteString) ref;\n"
  200. " }\n"
  201. "}\n");
  202. }
  203. void StringFieldGenerator::
  204. GenerateBuilderMembers(io::Printer* printer) const {
  205. printer->Print(variables_,
  206. "private java.lang.Object $name$_ $default_init$;\n");
  207. WriteFieldDocComment(printer, descriptor_);
  208. printer->Print(variables_,
  209. "$deprecation$public boolean has$capitalized_name$() {\n"
  210. " return $get_has_field_bit_builder$;\n"
  211. "}\n");
  212. WriteFieldDocComment(printer, descriptor_);
  213. printer->Print(variables_,
  214. "$deprecation$public java.lang.String get$capitalized_name$() {\n"
  215. " java.lang.Object ref = $name$_;\n"
  216. " if (!(ref instanceof java.lang.String)) {\n"
  217. " java.lang.String s = ((com.google.protobuf.ByteString) ref)\n"
  218. " .toStringUtf8();\n"
  219. " $name$_ = s;\n"
  220. " return s;\n"
  221. " } else {\n"
  222. " return (java.lang.String) ref;\n"
  223. " }\n"
  224. "}\n");
  225. WriteFieldDocComment(printer, descriptor_);
  226. printer->Print(variables_,
  227. "$deprecation$public com.google.protobuf.ByteString\n"
  228. " get$capitalized_name$Bytes() {\n"
  229. " java.lang.Object ref = $name$_;\n"
  230. " if (ref instanceof String) {\n"
  231. " com.google.protobuf.ByteString b = \n"
  232. " com.google.protobuf.ByteString.copyFromUtf8(\n"
  233. " (java.lang.String) ref);\n"
  234. " $name$_ = b;\n"
  235. " return b;\n"
  236. " } else {\n"
  237. " return (com.google.protobuf.ByteString) ref;\n"
  238. " }\n"
  239. "}\n");
  240. WriteFieldDocComment(printer, descriptor_);
  241. printer->Print(variables_,
  242. "$deprecation$public Builder set$capitalized_name$(\n"
  243. " java.lang.String value) {\n"
  244. "$null_check$"
  245. " $set_has_field_bit_builder$;\n"
  246. " $name$_ = value;\n"
  247. " $on_changed$\n"
  248. " return this;\n"
  249. "}\n");
  250. WriteFieldDocComment(printer, descriptor_);
  251. printer->Print(variables_,
  252. "$deprecation$public Builder clear$capitalized_name$() {\n"
  253. " $clear_has_field_bit_builder$;\n");
  254. // The default value is not a simple literal so we want to avoid executing
  255. // it multiple times. Instead, get the default out of the default instance.
  256. printer->Print(variables_,
  257. " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
  258. printer->Print(variables_,
  259. " $on_changed$\n"
  260. " return this;\n"
  261. "}\n");
  262. WriteFieldDocComment(printer, descriptor_);
  263. printer->Print(variables_,
  264. "$deprecation$public Builder set$capitalized_name$Bytes(\n"
  265. " com.google.protobuf.ByteString value) {\n"
  266. "$null_check$"
  267. " $set_has_field_bit_builder$;\n"
  268. " $name$_ = value;\n"
  269. " $on_changed$\n"
  270. " return this;\n"
  271. "}\n");
  272. }
  273. void StringFieldGenerator::
  274. GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
  275. // noop for primitives
  276. }
  277. void StringFieldGenerator::
  278. GenerateInitializationCode(io::Printer* printer) const {
  279. printer->Print(variables_, "$name$_ = $default$;\n");
  280. }
  281. void StringFieldGenerator::
  282. GenerateBuilderClearCode(io::Printer* printer) const {
  283. printer->Print(variables_,
  284. "$name$_ = $default$;\n"
  285. "$clear_has_field_bit_builder$;\n");
  286. }
  287. void StringFieldGenerator::
  288. GenerateMergingCode(io::Printer* printer) const {
  289. // Allow a slight breach of abstraction here in order to avoid forcing
  290. // all string fields to Strings when copying fields from a Message.
  291. printer->Print(variables_,
  292. "if (other.has$capitalized_name$()) {\n"
  293. " $set_has_field_bit_builder$;\n"
  294. " $name$_ = other.$name$_;\n"
  295. " $on_changed$\n"
  296. "}\n");
  297. }
  298. void StringFieldGenerator::
  299. GenerateBuildingCode(io::Printer* printer) const {
  300. printer->Print(variables_,
  301. "if ($get_has_field_bit_from_local$) {\n"
  302. " $set_has_field_bit_to_local$;\n"
  303. "}\n"
  304. "result.$name$_ = $name$_;\n");
  305. }
  306. void StringFieldGenerator::
  307. GenerateParsingCode(io::Printer* printer) const {
  308. printer->Print(variables_,
  309. "$set_has_field_bit_message$;\n"
  310. "$name$_ = input.readBytes();\n");
  311. }
  312. void StringFieldGenerator::
  313. GenerateParsingDoneCode(io::Printer* printer) const {
  314. // noop for strings.
  315. }
  316. void StringFieldGenerator::
  317. GenerateSerializationCode(io::Printer* printer) const {
  318. printer->Print(variables_,
  319. "if ($get_has_field_bit_message$) {\n"
  320. " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
  321. "}\n");
  322. }
  323. void StringFieldGenerator::
  324. GenerateSerializedSizeCode(io::Printer* printer) const {
  325. printer->Print(variables_,
  326. "if ($get_has_field_bit_message$) {\n"
  327. " size += com.google.protobuf.CodedOutputStream\n"
  328. " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
  329. "}\n");
  330. }
  331. void StringFieldGenerator::
  332. GenerateEqualsCode(io::Printer* printer) const {
  333. printer->Print(variables_,
  334. "result = result && get$capitalized_name$()\n"
  335. " .equals(other.get$capitalized_name$());\n");
  336. }
  337. void StringFieldGenerator::
  338. GenerateHashCode(io::Printer* printer) const {
  339. printer->Print(variables_,
  340. "hash = (37 * hash) + $constant_name$;\n");
  341. printer->Print(variables_,
  342. "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
  343. }
  344. string StringFieldGenerator::GetBoxedType() const {
  345. return "java.lang.String";
  346. }
  347. // ===================================================================
  348. RepeatedStringFieldGenerator::
  349. RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
  350. int messageBitIndex,
  351. int builderBitIndex)
  352. : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
  353. builderBitIndex_(builderBitIndex) {
  354. SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
  355. &variables_);
  356. }
  357. RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
  358. int RepeatedStringFieldGenerator::GetNumBitsForMessage() const {
  359. return 0;
  360. }
  361. int RepeatedStringFieldGenerator::GetNumBitsForBuilder() const {
  362. return 1;
  363. }
  364. void RepeatedStringFieldGenerator::
  365. GenerateInterfaceMembers(io::Printer* printer) const {
  366. WriteFieldDocComment(printer, descriptor_);
  367. printer->Print(variables_,
  368. "$deprecation$java.util.List<java.lang.String>\n"
  369. "get$capitalized_name$List();\n");
  370. WriteFieldDocComment(printer, descriptor_);
  371. printer->Print(variables_,
  372. "$deprecation$int get$capitalized_name$Count();\n");
  373. WriteFieldDocComment(printer, descriptor_);
  374. printer->Print(variables_,
  375. "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
  376. WriteFieldDocComment(printer, descriptor_);
  377. printer->Print(variables_,
  378. "$deprecation$com.google.protobuf.ByteString\n"
  379. " get$capitalized_name$Bytes(int index);\n");
  380. }
  381. void RepeatedStringFieldGenerator::
  382. GenerateMembers(io::Printer* printer) const {
  383. printer->Print(variables_,
  384. "private com.google.protobuf.LazyStringList $name$_;\n");
  385. WriteFieldDocComment(printer, descriptor_);
  386. printer->Print(variables_,
  387. "$deprecation$public java.util.List<java.lang.String>\n"
  388. " get$capitalized_name$List() {\n"
  389. " return $name$_;\n" // note: unmodifiable list
  390. "}\n");
  391. WriteFieldDocComment(printer, descriptor_);
  392. printer->Print(variables_,
  393. "$deprecation$public int get$capitalized_name$Count() {\n"
  394. " return $name$_.size();\n"
  395. "}\n");
  396. WriteFieldDocComment(printer, descriptor_);
  397. printer->Print(variables_,
  398. "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
  399. " return $name$_.get(index);\n"
  400. "}\n");
  401. WriteFieldDocComment(printer, descriptor_);
  402. printer->Print(variables_,
  403. "$deprecation$public com.google.protobuf.ByteString\n"
  404. " get$capitalized_name$Bytes(int index) {\n"
  405. " return $name$_.getByteString(index);\n"
  406. "}\n");
  407. if (descriptor_->options().packed() &&
  408. HasGeneratedMethods(descriptor_->containing_type())) {
  409. printer->Print(variables_,
  410. "private int $name$MemoizedSerializedSize = -1;\n");
  411. }
  412. }
  413. void RepeatedStringFieldGenerator::
  414. GenerateBuilderMembers(io::Printer* printer) const {
  415. // One field is the list and the bit field keeps track of whether the
  416. // list is immutable. If it's immutable, the invariant is that it must
  417. // either an instance of Collections.emptyList() or it's an ArrayList
  418. // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
  419. // a refererence to the underlying ArrayList. This invariant allows us to
  420. // share instances of lists between protocol buffers avoiding expensive
  421. // memory allocations. Note, immutable is a strong guarantee here -- not
  422. // just that the list cannot be modified via the reference but that the
  423. // list can never be modified.
  424. printer->Print(variables_,
  425. "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
  426. printer->Print(variables_,
  427. "private void ensure$capitalized_name$IsMutable() {\n"
  428. " if (!$get_mutable_bit_builder$) {\n"
  429. " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
  430. " $set_mutable_bit_builder$;\n"
  431. " }\n"
  432. "}\n");
  433. // Note: We return an unmodifiable list because otherwise the caller
  434. // could hold on to the returned list and modify it after the message
  435. // has been built, thus mutating the message which is supposed to be
  436. // immutable.
  437. WriteFieldDocComment(printer, descriptor_);
  438. printer->Print(variables_,
  439. "$deprecation$public java.util.List<java.lang.String>\n"
  440. " get$capitalized_name$List() {\n"
  441. " return java.util.Collections.unmodifiableList($name$_);\n"
  442. "}\n");
  443. WriteFieldDocComment(printer, descriptor_);
  444. printer->Print(variables_,
  445. "$deprecation$public int get$capitalized_name$Count() {\n"
  446. " return $name$_.size();\n"
  447. "}\n");
  448. WriteFieldDocComment(printer, descriptor_);
  449. printer->Print(variables_,
  450. "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
  451. " return $name$_.get(index);\n"
  452. "}\n");
  453. WriteFieldDocComment(printer, descriptor_);
  454. printer->Print(variables_,
  455. "$deprecation$public com.google.protobuf.ByteString\n"
  456. " get$capitalized_name$Bytes(int index) {\n"
  457. " return $name$_.getByteString(index);\n"
  458. "}\n");
  459. WriteFieldDocComment(printer, descriptor_);
  460. printer->Print(variables_,
  461. "$deprecation$public Builder set$capitalized_name$(\n"
  462. " int index, java.lang.String value) {\n"
  463. "$null_check$"
  464. " ensure$capitalized_name$IsMutable();\n"
  465. " $name$_.set(index, value);\n"
  466. " $on_changed$\n"
  467. " return this;\n"
  468. "}\n");
  469. WriteFieldDocComment(printer, descriptor_);
  470. printer->Print(variables_,
  471. "$deprecation$public Builder add$capitalized_name$(\n"
  472. " java.lang.String value) {\n"
  473. "$null_check$"
  474. " ensure$capitalized_name$IsMutable();\n"
  475. " $name$_.add(value);\n"
  476. " $on_changed$\n"
  477. " return this;\n"
  478. "}\n");
  479. WriteFieldDocComment(printer, descriptor_);
  480. printer->Print(variables_,
  481. "$deprecation$public Builder addAll$capitalized_name$(\n"
  482. " java.lang.Iterable<java.lang.String> values) {\n"
  483. " ensure$capitalized_name$IsMutable();\n"
  484. " super.addAll(values, $name$_);\n"
  485. " $on_changed$\n"
  486. " return this;\n"
  487. "}\n");
  488. WriteFieldDocComment(printer, descriptor_);
  489. printer->Print(variables_,
  490. "$deprecation$public Builder clear$capitalized_name$() {\n"
  491. " $name$_ = $empty_list$;\n"
  492. " $clear_mutable_bit_builder$;\n"
  493. " $on_changed$\n"
  494. " return this;\n"
  495. "}\n");
  496. WriteFieldDocComment(printer, descriptor_);
  497. printer->Print(variables_,
  498. "$deprecation$public Builder add$capitalized_name$Bytes(\n"
  499. " com.google.protobuf.ByteString value) {\n"
  500. "$null_check$"
  501. " ensure$capitalized_name$IsMutable();\n"
  502. " $name$_.add(value);\n"
  503. " $on_changed$\n"
  504. " return this;\n"
  505. "}\n");
  506. }
  507. void RepeatedStringFieldGenerator::
  508. GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
  509. // noop for primitives
  510. }
  511. void RepeatedStringFieldGenerator::
  512. GenerateInitializationCode(io::Printer* printer) const {
  513. printer->Print(variables_, "$name$_ = $empty_list$;\n");
  514. }
  515. void RepeatedStringFieldGenerator::
  516. GenerateBuilderClearCode(io::Printer* printer) const {
  517. printer->Print(variables_,
  518. "$name$_ = $empty_list$;\n"
  519. "$clear_mutable_bit_builder$;\n");
  520. }
  521. void RepeatedStringFieldGenerator::
  522. GenerateMergingCode(io::Printer* printer) const {
  523. // The code below does two optimizations:
  524. // 1. If the other list is empty, there's nothing to do. This ensures we
  525. // don't allocate a new array if we already have an immutable one.
  526. // 2. If the other list is non-empty and our current list is empty, we can
  527. // reuse the other list which is guaranteed to be immutable.
  528. printer->Print(variables_,
  529. "if (!other.$name$_.isEmpty()) {\n"
  530. " if ($name$_.isEmpty()) {\n"
  531. " $name$_ = other.$name$_;\n"
  532. " $clear_mutable_bit_builder$;\n"
  533. " } else {\n"
  534. " ensure$capitalized_name$IsMutable();\n"
  535. " $name$_.addAll(other.$name$_);\n"
  536. " }\n"
  537. " $on_changed$\n"
  538. "}\n");
  539. }
  540. void RepeatedStringFieldGenerator::
  541. GenerateBuildingCode(io::Printer* printer) const {
  542. // The code below ensures that the result has an immutable list. If our
  543. // list is immutable, we can just reuse it. If not, we make it immutable.
  544. printer->Print(variables_,
  545. "if ($get_mutable_bit_builder$) {\n"
  546. " $name$_ = new com.google.protobuf.UnmodifiableLazyStringList(\n"
  547. " $name$_);\n"
  548. " $clear_mutable_bit_builder$;\n"
  549. "}\n"
  550. "result.$name$_ = $name$_;\n");
  551. }
  552. void RepeatedStringFieldGenerator::
  553. GenerateParsingCode(io::Printer* printer) const {
  554. printer->Print(variables_,
  555. "if (!$get_mutable_bit_parser$) {\n"
  556. " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
  557. " $set_mutable_bit_parser$;\n"
  558. "}\n"
  559. "$name$_.add(input.readBytes());\n");
  560. }
  561. void RepeatedStringFieldGenerator::
  562. GenerateParsingCodeFromPacked(io::Printer* printer) const {
  563. printer->Print(variables_,
  564. "int length = input.readRawVarint32();\n"
  565. "int limit = input.pushLimit(length);\n"
  566. "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
  567. " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
  568. " $set_mutable_bit_parser$;\n"
  569. "}\n"
  570. "while (input.getBytesUntilLimit() > 0) {\n"
  571. " $name$.add(input.read$capitalized_type$());\n"
  572. "}\n"
  573. "input.popLimit(limit);\n");
  574. }
  575. void RepeatedStringFieldGenerator::
  576. GenerateParsingDoneCode(io::Printer* printer) const {
  577. printer->Print(variables_,
  578. "if ($get_mutable_bit_parser$) {\n"
  579. " $name$_ = new com.google.protobuf.UnmodifiableLazyStringList($name$_);\n"
  580. "}\n");
  581. }
  582. void RepeatedStringFieldGenerator::
  583. GenerateSerializationCode(io::Printer* printer) const {
  584. if (descriptor_->options().packed()) {
  585. printer->Print(variables_,
  586. "if (get$capitalized_name$List().size() > 0) {\n"
  587. " output.writeRawVarint32($tag$);\n"
  588. " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
  589. "}\n"
  590. "for (int i = 0; i < $name$_.size(); i++) {\n"
  591. " output.write$capitalized_type$NoTag($name$_.get(i));\n"
  592. "}\n");
  593. } else {
  594. printer->Print(variables_,
  595. "for (int i = 0; i < $name$_.size(); i++) {\n"
  596. " output.writeBytes($number$, $name$_.getByteString(i));\n"
  597. "}\n");
  598. }
  599. }
  600. void RepeatedStringFieldGenerator::
  601. GenerateSerializedSizeCode(io::Printer* printer) const {
  602. printer->Print(variables_,
  603. "{\n"
  604. " int dataSize = 0;\n");
  605. printer->Indent();
  606. printer->Print(variables_,
  607. "for (int i = 0; i < $name$_.size(); i++) {\n"
  608. " dataSize += com.google.protobuf.CodedOutputStream\n"
  609. " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
  610. "}\n");
  611. printer->Print(
  612. "size += dataSize;\n");
  613. if (descriptor_->options().packed()) {
  614. printer->Print(variables_,
  615. "if (!get$capitalized_name$List().isEmpty()) {\n"
  616. " size += $tag_size$;\n"
  617. " size += com.google.protobuf.CodedOutputStream\n"
  618. " .computeInt32SizeNoTag(dataSize);\n"
  619. "}\n");
  620. } else {
  621. printer->Print(variables_,
  622. "size += $tag_size$ * get$capitalized_name$List().size();\n");
  623. }
  624. // cache the data size for packed fields.
  625. if (descriptor_->options().packed()) {
  626. printer->Print(variables_,
  627. "$name$MemoizedSerializedSize = dataSize;\n");
  628. }
  629. printer->Outdent();
  630. printer->Print("}\n");
  631. }
  632. void RepeatedStringFieldGenerator::
  633. GenerateEqualsCode(io::Printer* printer) const {
  634. printer->Print(variables_,
  635. "result = result && get$capitalized_name$List()\n"
  636. " .equals(other.get$capitalized_name$List());\n");
  637. }
  638. void RepeatedStringFieldGenerator::
  639. GenerateHashCode(io::Printer* printer) const {
  640. printer->Print(variables_,
  641. "if (get$capitalized_name$Count() > 0) {\n"
  642. " hash = (37 * hash) + $constant_name$;\n"
  643. " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
  644. "}\n");
  645. }
  646. string RepeatedStringFieldGenerator::GetBoxedType() const {
  647. return "String";
  648. }
  649. } // namespace java
  650. } // namespace compiler
  651. } // namespace protobuf
  652. } // namespace google