- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / protobuf / src / google / protobuf / compiler / java / java_primitive_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 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <map>
36 #include <string>
37
38 #include <google/protobuf/compiler/java/java_primitive_field.h>
39 #include <google/protobuf/compiler/java/java_doc_comment.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/compiler/java/java_helpers.h>
42 #include <google/protobuf/io/printer.h>
43 #include <google/protobuf/wire_format.h>
44 #include <google/protobuf/stubs/strutil.h>
45
46 namespace google {
47 namespace protobuf {
48 namespace compiler {
49 namespace java {
50
51 using internal::WireFormat;
52 using internal::WireFormatLite;
53
54 namespace {
55
56 const char* PrimitiveTypeName(JavaType type) {
57   switch (type) {
58     case JAVATYPE_INT    : return "int";
59     case JAVATYPE_LONG   : return "long";
60     case JAVATYPE_FLOAT  : return "float";
61     case JAVATYPE_DOUBLE : return "double";
62     case JAVATYPE_BOOLEAN: return "boolean";
63     case JAVATYPE_STRING : return "java.lang.String";
64     case JAVATYPE_BYTES  : return "com.google.protobuf.ByteString";
65     case JAVATYPE_ENUM   : return NULL;
66     case JAVATYPE_MESSAGE: return NULL;
67
68     // No default because we want the compiler to complain if any new
69     // JavaTypes are added.
70   }
71
72   GOOGLE_LOG(FATAL) << "Can't get here.";
73   return NULL;
74 }
75
76 bool IsReferenceType(JavaType type) {
77   switch (type) {
78     case JAVATYPE_INT    : return false;
79     case JAVATYPE_LONG   : return false;
80     case JAVATYPE_FLOAT  : return false;
81     case JAVATYPE_DOUBLE : return false;
82     case JAVATYPE_BOOLEAN: return false;
83     case JAVATYPE_STRING : return true;
84     case JAVATYPE_BYTES  : return true;
85     case JAVATYPE_ENUM   : return true;
86     case JAVATYPE_MESSAGE: return true;
87
88     // No default because we want the compiler to complain if any new
89     // JavaTypes are added.
90   }
91
92   GOOGLE_LOG(FATAL) << "Can't get here.";
93   return false;
94 }
95
96 const char* GetCapitalizedType(const FieldDescriptor* field) {
97   switch (GetType(field)) {
98     case FieldDescriptor::TYPE_INT32   : return "Int32"   ;
99     case FieldDescriptor::TYPE_UINT32  : return "UInt32"  ;
100     case FieldDescriptor::TYPE_SINT32  : return "SInt32"  ;
101     case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
102     case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
103     case FieldDescriptor::TYPE_INT64   : return "Int64"   ;
104     case FieldDescriptor::TYPE_UINT64  : return "UInt64"  ;
105     case FieldDescriptor::TYPE_SINT64  : return "SInt64"  ;
106     case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
107     case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
108     case FieldDescriptor::TYPE_FLOAT   : return "Float"   ;
109     case FieldDescriptor::TYPE_DOUBLE  : return "Double"  ;
110     case FieldDescriptor::TYPE_BOOL    : return "Bool"    ;
111     case FieldDescriptor::TYPE_STRING  : return "String"  ;
112     case FieldDescriptor::TYPE_BYTES   : return "Bytes"   ;
113     case FieldDescriptor::TYPE_ENUM    : return "Enum"    ;
114     case FieldDescriptor::TYPE_GROUP   : return "Group"   ;
115     case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
116
117     // No default because we want the compiler to complain if any new
118     // types are added.
119   }
120
121   GOOGLE_LOG(FATAL) << "Can't get here.";
122   return NULL;
123 }
124
125 // For encodings with fixed sizes, returns that size in bytes.  Otherwise
126 // returns -1.
127 int FixedSize(FieldDescriptor::Type type) {
128   switch (type) {
129     case FieldDescriptor::TYPE_INT32   : return -1;
130     case FieldDescriptor::TYPE_INT64   : return -1;
131     case FieldDescriptor::TYPE_UINT32  : return -1;
132     case FieldDescriptor::TYPE_UINT64  : return -1;
133     case FieldDescriptor::TYPE_SINT32  : return -1;
134     case FieldDescriptor::TYPE_SINT64  : return -1;
135     case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
136     case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
137     case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
138     case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
139     case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
140     case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
141
142     case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
143     case FieldDescriptor::TYPE_ENUM    : return -1;
144
145     case FieldDescriptor::TYPE_STRING  : return -1;
146     case FieldDescriptor::TYPE_BYTES   : return -1;
147     case FieldDescriptor::TYPE_GROUP   : return -1;
148     case FieldDescriptor::TYPE_MESSAGE : return -1;
149
150     // No default because we want the compiler to complain if any new
151     // types are added.
152   }
153   GOOGLE_LOG(FATAL) << "Can't get here.";
154   return -1;
155 }
156
157 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
158                            int messageBitIndex,
159                            int builderBitIndex,
160                            map<string, string>* variables) {
161   (*variables)["name"] =
162     UnderscoresToCamelCase(descriptor);
163   (*variables)["capitalized_name"] =
164     UnderscoresToCapitalizedCamelCase(descriptor);
165   (*variables)["constant_name"] = FieldConstantName(descriptor);
166   (*variables)["number"] = SimpleItoa(descriptor->number());
167   (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
168   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
169   (*variables)["field_type"] = (*variables)["type"];
170   (*variables)["field_list_type"] = "java.util.List<" +
171       (*variables)["boxed_type"] + ">";
172   (*variables)["empty_list"] = "java.util.Collections.emptyList()";
173   (*variables)["default"] = DefaultValue(descriptor);
174   (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
175       "" : ("= " + DefaultValue(descriptor));
176   (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
177   (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
178   (*variables)["tag_size"] = SimpleItoa(
179       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
180   if (IsReferenceType(GetJavaType(descriptor))) {
181     (*variables)["null_check"] =
182         "  if (value == null) {\n"
183         "    throw new NullPointerException();\n"
184         "  }\n";
185   } else {
186     (*variables)["null_check"] = "";
187   }
188   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
189   // by the proto compiler
190   (*variables)["deprecation"] = descriptor->options().deprecated()
191       ? "@java.lang.Deprecated " : "";
192   int fixed_size = FixedSize(GetType(descriptor));
193   if (fixed_size != -1) {
194     (*variables)["fixed_size"] = SimpleItoa(fixed_size);
195   }
196   (*variables)["on_changed"] =
197       HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
198
199   // For singular messages and builders, one bit is used for the hasField bit.
200   (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
201   (*variables)["set_has_field_bit_message"] = GenerateSetBit(messageBitIndex);
202
203   (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
204   (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
205   (*variables)["clear_has_field_bit_builder"] =
206       GenerateClearBit(builderBitIndex);
207
208   // For repated builders, one bit is used for whether the array is immutable.
209   (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
210   (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
211   (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
212
213   // For repeated fields, one bit is used for whether the array is immutable
214   // in the parsing constructor.
215   (*variables)["get_mutable_bit_parser"] =
216       GenerateGetBitMutableLocal(builderBitIndex);
217   (*variables)["set_mutable_bit_parser"] =
218       GenerateSetBitMutableLocal(builderBitIndex);
219
220   (*variables)["get_has_field_bit_from_local"] =
221       GenerateGetBitFromLocal(builderBitIndex);
222   (*variables)["set_has_field_bit_to_local"] =
223       GenerateSetBitToLocal(messageBitIndex);
224 }
225
226 }  // namespace
227
228 // ===================================================================
229
230 PrimitiveFieldGenerator::
231 PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
232                         int messageBitIndex,
233                         int builderBitIndex)
234   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
235     builderBitIndex_(builderBitIndex) {
236   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
237                         &variables_);
238 }
239
240 PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
241
242 int PrimitiveFieldGenerator::GetNumBitsForMessage() const {
243   return 1;
244 }
245
246 int PrimitiveFieldGenerator::GetNumBitsForBuilder() const {
247   return 1;
248 }
249
250 void PrimitiveFieldGenerator::
251 GenerateInterfaceMembers(io::Printer* printer) const {
252   WriteFieldDocComment(printer, descriptor_);
253   printer->Print(variables_,
254     "$deprecation$boolean has$capitalized_name$();\n");
255   WriteFieldDocComment(printer, descriptor_);
256   printer->Print(variables_,
257     "$deprecation$$type$ get$capitalized_name$();\n");
258 }
259
260 void PrimitiveFieldGenerator::
261 GenerateMembers(io::Printer* printer) const {
262   printer->Print(variables_,
263     "private $field_type$ $name$_;\n");
264
265   WriteFieldDocComment(printer, descriptor_);
266   printer->Print(variables_,
267     "$deprecation$public boolean has$capitalized_name$() {\n"
268     "  return $get_has_field_bit_message$;\n"
269     "}\n");
270
271   WriteFieldDocComment(printer, descriptor_);
272   printer->Print(variables_,
273     "$deprecation$public $type$ get$capitalized_name$() {\n"
274     "  return $name$_;\n"
275     "}\n");
276 }
277
278 void PrimitiveFieldGenerator::
279 GenerateBuilderMembers(io::Printer* printer) const {
280   printer->Print(variables_,
281     "private $field_type$ $name$_ $default_init$;\n");
282
283   WriteFieldDocComment(printer, descriptor_);
284   printer->Print(variables_,
285     "$deprecation$public boolean has$capitalized_name$() {\n"
286     "  return $get_has_field_bit_builder$;\n"
287     "}\n");
288
289   WriteFieldDocComment(printer, descriptor_);
290   printer->Print(variables_,
291     "$deprecation$public $type$ get$capitalized_name$() {\n"
292     "  return $name$_;\n"
293     "}\n");
294
295   WriteFieldDocComment(printer, descriptor_);
296   printer->Print(variables_,
297     "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
298     "$null_check$"
299     "  $set_has_field_bit_builder$;\n"
300     "  $name$_ = value;\n"
301     "  $on_changed$\n"
302     "  return this;\n"
303     "}\n");
304
305   WriteFieldDocComment(printer, descriptor_);
306   printer->Print(variables_,
307     "$deprecation$public Builder clear$capitalized_name$() {\n"
308     "  $clear_has_field_bit_builder$;\n");
309   JavaType type = GetJavaType(descriptor_);
310   if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
311     // The default value is not a simple literal so we want to avoid executing
312     // it multiple times.  Instead, get the default out of the default instance.
313     printer->Print(variables_,
314       "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
315   } else {
316     printer->Print(variables_,
317       "  $name$_ = $default$;\n");
318   }
319   printer->Print(variables_,
320     "  $on_changed$\n"
321     "  return this;\n"
322     "}\n");
323 }
324
325 void PrimitiveFieldGenerator::
326 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
327   // noop for primitives
328 }
329
330 void PrimitiveFieldGenerator::
331 GenerateInitializationCode(io::Printer* printer) const {
332   printer->Print(variables_, "$name$_ = $default$;\n");
333 }
334
335 void PrimitiveFieldGenerator::
336 GenerateBuilderClearCode(io::Printer* printer) const {
337   printer->Print(variables_,
338     "$name$_ = $default$;\n"
339     "$clear_has_field_bit_builder$;\n");
340 }
341
342 void PrimitiveFieldGenerator::
343 GenerateMergingCode(io::Printer* printer) const {
344   printer->Print(variables_,
345     "if (other.has$capitalized_name$()) {\n"
346     "  set$capitalized_name$(other.get$capitalized_name$());\n"
347     "}\n");
348 }
349
350 void PrimitiveFieldGenerator::
351 GenerateBuildingCode(io::Printer* printer) const {
352   printer->Print(variables_,
353     "if ($get_has_field_bit_from_local$) {\n"
354     "  $set_has_field_bit_to_local$;\n"
355     "}\n"
356     "result.$name$_ = $name$_;\n");
357 }
358
359 void PrimitiveFieldGenerator::
360 GenerateParsingCode(io::Printer* printer) const {
361   printer->Print(variables_,
362     "$set_has_field_bit_message$;\n"
363     "$name$_ = input.read$capitalized_type$();\n");
364 }
365
366 void PrimitiveFieldGenerator::
367 GenerateParsingDoneCode(io::Printer* printer) const {
368   // noop for primitives.
369 }
370
371 void PrimitiveFieldGenerator::
372 GenerateSerializationCode(io::Printer* printer) const {
373   printer->Print(variables_,
374     "if ($get_has_field_bit_message$) {\n"
375     "  output.write$capitalized_type$($number$, $name$_);\n"
376     "}\n");
377 }
378
379 void PrimitiveFieldGenerator::
380 GenerateSerializedSizeCode(io::Printer* printer) const {
381   printer->Print(variables_,
382     "if ($get_has_field_bit_message$) {\n"
383     "  size += com.google.protobuf.CodedOutputStream\n"
384     "    .compute$capitalized_type$Size($number$, $name$_);\n"
385     "}\n");
386 }
387
388 void PrimitiveFieldGenerator::
389 GenerateEqualsCode(io::Printer* printer) const {
390   switch (GetJavaType(descriptor_)) {
391     case JAVATYPE_INT:
392     case JAVATYPE_LONG:
393     case JAVATYPE_BOOLEAN:
394       printer->Print(variables_,
395         "result = result && (get$capitalized_name$()\n"
396         "    == other.get$capitalized_name$());\n");
397       break;
398
399     case JAVATYPE_FLOAT:
400       printer->Print(variables_,
401         "result = result && (Float.floatToIntBits(get$capitalized_name$())"
402         "    == Float.floatToIntBits(other.get$capitalized_name$()));\n");
403       break;
404
405     case JAVATYPE_DOUBLE:
406       printer->Print(variables_,
407         "result = result && (Double.doubleToLongBits(get$capitalized_name$())"
408         "    == Double.doubleToLongBits(other.get$capitalized_name$()));\n");
409       break;
410
411     case JAVATYPE_STRING:
412     case JAVATYPE_BYTES:
413       printer->Print(variables_,
414         "result = result && get$capitalized_name$()\n"
415         "    .equals(other.get$capitalized_name$());\n");
416       break;
417
418     case JAVATYPE_ENUM:
419     case JAVATYPE_MESSAGE:
420     default:
421       GOOGLE_LOG(FATAL) << "Can't get here.";
422       break;
423   }
424 }
425
426 void PrimitiveFieldGenerator::
427 GenerateHashCode(io::Printer* printer) const {
428   printer->Print(variables_,
429     "hash = (37 * hash) + $constant_name$;\n");
430   switch (GetJavaType(descriptor_)) {
431     case JAVATYPE_INT:
432       printer->Print(variables_,
433         "hash = (53 * hash) + get$capitalized_name$();\n");
434       break;
435
436     case JAVATYPE_LONG:
437       printer->Print(variables_,
438         "hash = (53 * hash) + hashLong(get$capitalized_name$());\n");
439       break;
440
441     case JAVATYPE_BOOLEAN:
442       printer->Print(variables_,
443         "hash = (53 * hash) + hashBoolean(get$capitalized_name$());\n");
444       break;
445
446     case JAVATYPE_FLOAT:
447       printer->Print(variables_,
448         "hash = (53 * hash) + Float.floatToIntBits(\n"
449         "    get$capitalized_name$());\n");
450       break;
451
452     case JAVATYPE_DOUBLE:
453       printer->Print(variables_,
454         "hash = (53 * hash) + hashLong(\n"
455         "    Double.doubleToLongBits(get$capitalized_name$()));\n");
456       break;
457
458     case JAVATYPE_STRING:
459     case JAVATYPE_BYTES:
460       printer->Print(variables_,
461         "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
462       break;
463
464     case JAVATYPE_ENUM:
465     case JAVATYPE_MESSAGE:
466     default:
467       GOOGLE_LOG(FATAL) << "Can't get here.";
468       break;
469   }
470 }
471
472 string PrimitiveFieldGenerator::GetBoxedType() const {
473   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
474 }
475
476 // ===================================================================
477
478 RepeatedPrimitiveFieldGenerator::
479 RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
480                                 int messageBitIndex,
481                                 int builderBitIndex)
482   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
483     builderBitIndex_(builderBitIndex) {
484   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
485                         &variables_);
486 }
487
488 RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
489
490 int RepeatedPrimitiveFieldGenerator::GetNumBitsForMessage() const {
491   return 0;
492 }
493
494 int RepeatedPrimitiveFieldGenerator::GetNumBitsForBuilder() const {
495   return 1;
496 }
497
498 void RepeatedPrimitiveFieldGenerator::
499 GenerateInterfaceMembers(io::Printer* printer) const {
500   WriteFieldDocComment(printer, descriptor_);
501   printer->Print(variables_,
502     "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n");
503   WriteFieldDocComment(printer, descriptor_);
504   printer->Print(variables_,
505     "$deprecation$int get$capitalized_name$Count();\n");
506   WriteFieldDocComment(printer, descriptor_);
507   printer->Print(variables_,
508     "$deprecation$$type$ get$capitalized_name$(int index);\n");
509 }
510
511
512 void RepeatedPrimitiveFieldGenerator::
513 GenerateMembers(io::Printer* printer) const {
514   printer->Print(variables_,
515     "private $field_list_type$ $name$_;\n");
516   WriteFieldDocComment(printer, descriptor_);
517   printer->Print(variables_,
518     "$deprecation$public java.util.List<$boxed_type$>\n"
519     "    get$capitalized_name$List() {\n"
520     "  return $name$_;\n"   // note:  unmodifiable list
521     "}\n");
522   WriteFieldDocComment(printer, descriptor_);
523   printer->Print(variables_,
524     "$deprecation$public int get$capitalized_name$Count() {\n"
525     "  return $name$_.size();\n"
526     "}\n");
527   WriteFieldDocComment(printer, descriptor_);
528   printer->Print(variables_,
529     "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
530     "  return $name$_.get(index);\n"
531     "}\n");
532
533   if (descriptor_->options().packed() &&
534       HasGeneratedMethods(descriptor_->containing_type())) {
535     printer->Print(variables_,
536       "private int $name$MemoizedSerializedSize = -1;\n");
537   }
538 }
539
540 void RepeatedPrimitiveFieldGenerator::
541 GenerateBuilderMembers(io::Printer* printer) const {
542   // One field is the list and the bit field keeps track of whether the
543   // list is immutable. If it's immutable, the invariant is that it must
544   // either an instance of Collections.emptyList() or it's an ArrayList
545   // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
546   // a refererence to the underlying ArrayList. This invariant allows us to
547   // share instances of lists between protocol buffers avoiding expensive
548   // memory allocations. Note, immutable is a strong guarantee here -- not
549   // just that the list cannot be modified via the reference but that the
550   // list can never be modified.
551   printer->Print(variables_,
552     "private $field_list_type$ $name$_ = $empty_list$;\n");
553
554   printer->Print(variables_,
555     "private void ensure$capitalized_name$IsMutable() {\n"
556     "  if (!$get_mutable_bit_builder$) {\n"
557     "    $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
558     "    $set_mutable_bit_builder$;\n"
559     "   }\n"
560     "}\n");
561
562     // Note:  We return an unmodifiable list because otherwise the caller
563     //   could hold on to the returned list and modify it after the message
564     //   has been built, thus mutating the message which is supposed to be
565     //   immutable.
566   WriteFieldDocComment(printer, descriptor_);
567   printer->Print(variables_,
568     "$deprecation$public java.util.List<$boxed_type$>\n"
569     "    get$capitalized_name$List() {\n"
570     "  return java.util.Collections.unmodifiableList($name$_);\n"
571     "}\n");
572   WriteFieldDocComment(printer, descriptor_);
573   printer->Print(variables_,
574     "$deprecation$public int get$capitalized_name$Count() {\n"
575     "  return $name$_.size();\n"
576     "}\n");
577   WriteFieldDocComment(printer, descriptor_);
578   printer->Print(variables_,
579     "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
580     "  return $name$_.get(index);\n"
581     "}\n");
582   WriteFieldDocComment(printer, descriptor_);
583   printer->Print(variables_,
584     "$deprecation$public Builder set$capitalized_name$(\n"
585     "    int index, $type$ value) {\n"
586     "$null_check$"
587     "  ensure$capitalized_name$IsMutable();\n"
588     "  $name$_.set(index, value);\n"
589     "  $on_changed$\n"
590     "  return this;\n"
591     "}\n");
592   WriteFieldDocComment(printer, descriptor_);
593   printer->Print(variables_,
594     "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
595     "$null_check$"
596     "  ensure$capitalized_name$IsMutable();\n"
597     "  $name$_.add(value);\n"
598     "  $on_changed$\n"
599     "  return this;\n"
600     "}\n");
601   WriteFieldDocComment(printer, descriptor_);
602   printer->Print(variables_,
603     "$deprecation$public Builder addAll$capitalized_name$(\n"
604     "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
605     "  ensure$capitalized_name$IsMutable();\n"
606     "  super.addAll(values, $name$_);\n"
607     "  $on_changed$\n"
608     "  return this;\n"
609     "}\n");
610   WriteFieldDocComment(printer, descriptor_);
611   printer->Print(variables_,
612     "$deprecation$public Builder clear$capitalized_name$() {\n"
613     "  $name$_ = $empty_list$;\n"
614     "  $clear_mutable_bit_builder$;\n"
615     "  $on_changed$\n"
616     "  return this;\n"
617     "}\n");
618 }
619
620 void RepeatedPrimitiveFieldGenerator::
621 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
622   // noop for primitives
623 }
624
625 void RepeatedPrimitiveFieldGenerator::
626 GenerateInitializationCode(io::Printer* printer) const {
627   printer->Print(variables_, "$name$_ = $empty_list$;\n");
628 }
629
630 void RepeatedPrimitiveFieldGenerator::
631 GenerateBuilderClearCode(io::Printer* printer) const {
632   printer->Print(variables_,
633     "$name$_ = $empty_list$;\n"
634     "$clear_mutable_bit_builder$;\n");
635 }
636
637 void RepeatedPrimitiveFieldGenerator::
638 GenerateMergingCode(io::Printer* printer) const {
639   // The code below does two optimizations:
640   //   1. If the other list is empty, there's nothing to do. This ensures we
641   //      don't allocate a new array if we already have an immutable one.
642   //   2. If the other list is non-empty and our current list is empty, we can
643   //      reuse the other list which is guaranteed to be immutable.
644   printer->Print(variables_,
645     "if (!other.$name$_.isEmpty()) {\n"
646     "  if ($name$_.isEmpty()) {\n"
647     "    $name$_ = other.$name$_;\n"
648     "    $clear_mutable_bit_builder$;\n"
649     "  } else {\n"
650     "    ensure$capitalized_name$IsMutable();\n"
651     "    $name$_.addAll(other.$name$_);\n"
652     "  }\n"
653     "  $on_changed$\n"
654     "}\n");
655 }
656
657 void RepeatedPrimitiveFieldGenerator::
658 GenerateBuildingCode(io::Printer* printer) const {
659   // The code below ensures that the result has an immutable list. If our
660   // list is immutable, we can just reuse it. If not, we make it immutable.
661   printer->Print(variables_,
662     "if ($get_mutable_bit_builder$) {\n"
663     "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
664     "  $clear_mutable_bit_builder$;\n"
665     "}\n"
666     "result.$name$_ = $name$_;\n");
667 }
668
669 void RepeatedPrimitiveFieldGenerator::
670 GenerateParsingCode(io::Printer* printer) const {
671   printer->Print(variables_,
672     "if (!$get_mutable_bit_parser$) {\n"
673     "  $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
674     "  $set_mutable_bit_parser$;\n"
675     "}\n"
676     "$name$_.add(input.read$capitalized_type$());\n");
677 }
678
679 void RepeatedPrimitiveFieldGenerator::
680 GenerateParsingCodeFromPacked(io::Printer* printer) const {
681   printer->Print(variables_,
682     "int length = input.readRawVarint32();\n"
683     "int limit = input.pushLimit(length);\n"
684     "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
685     "  $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
686     "  $set_mutable_bit_parser$;\n"
687     "}\n"
688     "while (input.getBytesUntilLimit() > 0) {\n"
689     "  $name$_.add(input.read$capitalized_type$());\n"
690     "}\n"
691     "input.popLimit(limit);\n");
692 }
693
694 void RepeatedPrimitiveFieldGenerator::
695 GenerateParsingDoneCode(io::Printer* printer) const {
696   printer->Print(variables_,
697     "if ($get_mutable_bit_parser$) {\n"
698     "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
699     "}\n");
700 }
701
702 void RepeatedPrimitiveFieldGenerator::
703 GenerateSerializationCode(io::Printer* printer) const {
704   if (descriptor_->options().packed()) {
705     printer->Print(variables_,
706       "if (get$capitalized_name$List().size() > 0) {\n"
707       "  output.writeRawVarint32($tag$);\n"
708       "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
709       "}\n"
710       "for (int i = 0; i < $name$_.size(); i++) {\n"
711       "  output.write$capitalized_type$NoTag($name$_.get(i));\n"
712       "}\n");
713   } else {
714     printer->Print(variables_,
715       "for (int i = 0; i < $name$_.size(); i++) {\n"
716       "  output.write$capitalized_type$($number$, $name$_.get(i));\n"
717       "}\n");
718   }
719 }
720
721 void RepeatedPrimitiveFieldGenerator::
722 GenerateSerializedSizeCode(io::Printer* printer) const {
723   printer->Print(variables_,
724     "{\n"
725     "  int dataSize = 0;\n");
726   printer->Indent();
727
728   if (FixedSize(GetType(descriptor_)) == -1) {
729     printer->Print(variables_,
730       "for (int i = 0; i < $name$_.size(); i++) {\n"
731       "  dataSize += com.google.protobuf.CodedOutputStream\n"
732       "    .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
733       "}\n");
734   } else {
735     printer->Print(variables_,
736       "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
737   }
738
739   printer->Print(
740       "size += dataSize;\n");
741
742   if (descriptor_->options().packed()) {
743     printer->Print(variables_,
744       "if (!get$capitalized_name$List().isEmpty()) {\n"
745       "  size += $tag_size$;\n"
746       "  size += com.google.protobuf.CodedOutputStream\n"
747       "      .computeInt32SizeNoTag(dataSize);\n"
748       "}\n");
749   } else {
750     printer->Print(variables_,
751       "size += $tag_size$ * get$capitalized_name$List().size();\n");
752   }
753
754   // cache the data size for packed fields.
755   if (descriptor_->options().packed()) {
756     printer->Print(variables_,
757       "$name$MemoizedSerializedSize = dataSize;\n");
758   }
759
760   printer->Outdent();
761   printer->Print("}\n");
762 }
763
764 void RepeatedPrimitiveFieldGenerator::
765 GenerateEqualsCode(io::Printer* printer) const {
766   printer->Print(variables_,
767     "result = result && get$capitalized_name$List()\n"
768     "    .equals(other.get$capitalized_name$List());\n");
769 }
770
771 void RepeatedPrimitiveFieldGenerator::
772 GenerateHashCode(io::Printer* printer) const {
773   printer->Print(variables_,
774     "if (get$capitalized_name$Count() > 0) {\n"
775     "  hash = (37 * hash) + $constant_name$;\n"
776     "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
777     "}\n");
778 }
779
780 string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
781   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
782 }
783
784 }  // namespace java
785 }  // namespace compiler
786 }  // namespace protobuf
787 }  // namespace google