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