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