• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
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_context.h>
39 #include <google/protobuf/compiler/java/java_message_field.h>
40 #include <google/protobuf/compiler/java/java_doc_comment.h>
41 #include <google/protobuf/compiler/java/java_helpers.h>
42 #include <google/protobuf/compiler/java/java_name_resolver.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 namespace {
53 
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,map<string,string> * variables)54 void SetMessageVariables(const FieldDescriptor* descriptor,
55                          int messageBitIndex,
56                          int builderBitIndex,
57                          const FieldGeneratorInfo* info,
58                          ClassNameResolver* name_resolver,
59                          map<string, string>* variables) {
60   SetCommonFieldVariables(descriptor, info, variables);
61 
62   (*variables)["type"] =
63       name_resolver->GetImmutableClassName(descriptor->message_type());
64   (*variables)["mutable_type"] =
65       name_resolver->GetMutableClassName(descriptor->message_type());
66   (*variables)["group_or_message"] =
67     (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
68     "Group" : "Message";
69   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
70   // by the proto compiler
71   (*variables)["deprecation"] = descriptor->options().deprecated()
72       ? "@java.lang.Deprecated " : "";
73   (*variables)["on_changed"] = "onChanged();";
74 
75   if (SupportFieldPresence(descriptor->file())) {
76     // For singular messages and builders, one bit is used for the hasField bit.
77     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
78     (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
79 
80     // Note that these have a trailing ";".
81     (*variables)["set_has_field_bit_message"] =
82         GenerateSetBit(messageBitIndex) + ";";
83     (*variables)["set_has_field_bit_builder"] =
84         GenerateSetBit(builderBitIndex) + ";";
85     (*variables)["clear_has_field_bit_builder"] =
86         GenerateClearBit(builderBitIndex) + ";";
87 
88     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
89   } else {
90     (*variables)["set_has_field_bit_message"] = "";
91     (*variables)["set_has_field_bit_builder"] = "";
92     (*variables)["clear_has_field_bit_builder"] = "";
93 
94     (*variables)["is_field_present_message"] =
95         (*variables)["name"] + "_ != null";
96   }
97 
98   // For repated builders, one bit is used for whether the array is immutable.
99   (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
100   (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
101   (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
102 
103   // For repeated fields, one bit is used for whether the array is immutable
104   // in the parsing constructor.
105   (*variables)["get_mutable_bit_parser"] =
106       GenerateGetBitMutableLocal(builderBitIndex);
107   (*variables)["set_mutable_bit_parser"] =
108       GenerateSetBitMutableLocal(builderBitIndex);
109 
110   (*variables)["get_has_field_bit_from_local"] =
111       GenerateGetBitFromLocal(builderBitIndex);
112   (*variables)["set_has_field_bit_to_local"] =
113       GenerateSetBitToLocal(messageBitIndex);
114 }
115 
116 }  // namespace
117 
118 // ===================================================================
119 
120 ImmutableMessageFieldGenerator::
ImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)121 ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
122                       int messageBitIndex,
123                       int builderBitIndex,
124                       Context* context)
125   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
126     builderBitIndex_(builderBitIndex), context_(context),
127     name_resolver_(context->GetNameResolver()) {
128     SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
129                         context->GetFieldGeneratorInfo(descriptor),
130                         name_resolver_, &variables_);
131 }
132 
~ImmutableMessageFieldGenerator()133 ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
134 
GetNumBitsForMessage() const135 int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
136   return 1;
137 }
138 
GetNumBitsForBuilder() const139 int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
140   return 1;
141 }
142 
143 void ImmutableMessageFieldGenerator::
GenerateInterfaceMembers(io::Printer * printer) const144 GenerateInterfaceMembers(io::Printer* printer) const {
145   // TODO(jonp): In the future, consider having a method specific to the
146   // interface so that builders can choose dynamically to either return a
147   // message or a nested builder, so that asking for the interface doesn't
148   // cause a message to ever be built.
149   if (SupportFieldPresence(descriptor_->file()) ||
150       descriptor_->containing_oneof() == NULL) {
151     WriteFieldDocComment(printer, descriptor_);
152     printer->Print(variables_,
153       "$deprecation$boolean has$capitalized_name$();\n");
154   }
155   WriteFieldDocComment(printer, descriptor_);
156   printer->Print(variables_,
157     "$deprecation$$type$ get$capitalized_name$();\n");
158 
159   WriteFieldDocComment(printer, descriptor_);
160   printer->Print(variables_,
161     "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
162 }
163 
164 void ImmutableMessageFieldGenerator::
GenerateMembers(io::Printer * printer) const165 GenerateMembers(io::Printer* printer) const {
166   printer->Print(variables_,
167     "private $type$ $name$_;\n");
168   PrintExtraFieldInfo(variables_, printer);
169 
170   if (SupportFieldPresence(descriptor_->file())) {
171     WriteFieldDocComment(printer, descriptor_);
172     printer->Print(variables_,
173       "$deprecation$public boolean has$capitalized_name$() {\n"
174       "  return $get_has_field_bit_message$;\n"
175       "}\n");
176     WriteFieldDocComment(printer, descriptor_);
177     printer->Print(variables_,
178       "$deprecation$public $type$ get$capitalized_name$() {\n"
179       "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
180       "}\n");
181 
182     WriteFieldDocComment(printer, descriptor_);
183     printer->Print(variables_,
184       "$deprecation$public $type$OrBuilder "
185       "get$capitalized_name$OrBuilder() {\n"
186       "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
187       "}\n");
188   } else {
189     WriteFieldDocComment(printer, descriptor_);
190     printer->Print(variables_,
191       "$deprecation$public boolean has$capitalized_name$() {\n"
192       "  return $name$_ != null;\n"
193       "}\n");
194     WriteFieldDocComment(printer, descriptor_);
195     printer->Print(variables_,
196       "$deprecation$public $type$ get$capitalized_name$() {\n"
197       "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
198       "}\n");
199 
200     WriteFieldDocComment(printer, descriptor_);
201     printer->Print(variables_,
202       "$deprecation$public $type$OrBuilder "
203       "get$capitalized_name$OrBuilder() {\n"
204       "  return get$capitalized_name$();\n"
205       "}\n");
206   }
207 }
208 
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const209 void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
210     io::Printer* printer,
211     const char* regular_case,
212     const char* nested_builder_case) const {
213   printer->Print(variables_, "if ($name$Builder_ == null) {\n");
214   printer->Indent();
215   printer->Print(variables_, regular_case);
216   printer->Outdent();
217   printer->Print("} else {\n");
218   printer->Indent();
219   printer->Print(variables_, nested_builder_case);
220   printer->Outdent();
221   printer->Print("}\n");
222 }
223 
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const224 void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
225     io::Printer* printer,
226     const char* method_prototype,
227     const char* regular_case,
228     const char* nested_builder_case,
229     const char* trailing_code) const {
230   printer->Print(variables_, method_prototype);
231   printer->Print(" {\n");
232   printer->Indent();
233   PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
234   if (trailing_code != NULL) {
235     printer->Print(variables_, trailing_code);
236   }
237   printer->Outdent();
238   printer->Print("}\n");
239 }
240 
241 void ImmutableMessageFieldGenerator::
GenerateBuilderMembers(io::Printer * printer) const242 GenerateBuilderMembers(io::Printer* printer) const {
243   // When using nested-builders, the code initially works just like the
244   // non-nested builder case. It only creates a nested builder lazily on
245   // demand and then forever delegates to it after creation.
246 
247   bool support_field_presence = SupportFieldPresence(descriptor_->file());
248 
249   printer->Print(variables_,
250     "private $type$ $name$_ = null;\n");
251 
252   printer->Print(variables_,
253       // If this builder is non-null, it is used and the other fields are
254       // ignored.
255       "private com.google.protobuf.SingleFieldBuilder<\n"
256       "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
257       "\n");
258 
259   // The comments above the methods below are based on a hypothetical
260   // field of type "Field" called "Field".
261 
262   // boolean hasField()
263   WriteFieldDocComment(printer, descriptor_);
264   if (support_field_presence) {
265     printer->Print(variables_,
266       "$deprecation$public boolean has$capitalized_name$() {\n"
267       "  return $get_has_field_bit_builder$;\n"
268       "}\n");
269   } else {
270     printer->Print(variables_,
271       "$deprecation$public boolean has$capitalized_name$() {\n"
272       "  return $name$Builder_ != null || $name$_ != null;\n"
273       "}\n");
274   }
275 
276   // Field getField()
277   WriteFieldDocComment(printer, descriptor_);
278   PrintNestedBuilderFunction(printer,
279     "$deprecation$public $type$ get$capitalized_name$()",
280     "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
281     "return $name$Builder_.getMessage();\n",
282     NULL);
283 
284   // Field.Builder setField(Field value)
285   WriteFieldDocComment(printer, descriptor_);
286   PrintNestedBuilderFunction(printer,
287     "$deprecation$public Builder set$capitalized_name$($type$ value)",
288 
289     "if (value == null) {\n"
290     "  throw new NullPointerException();\n"
291     "}\n"
292     "$name$_ = value;\n"
293     "$on_changed$\n",
294 
295     "$name$Builder_.setMessage(value);\n",
296 
297     "$set_has_field_bit_builder$\n"
298     "return this;\n");
299 
300   // Field.Builder setField(Field.Builder builderForValue)
301   WriteFieldDocComment(printer, descriptor_);
302   PrintNestedBuilderFunction(printer,
303     "$deprecation$public Builder set$capitalized_name$(\n"
304     "    $type$.Builder builderForValue)",
305 
306     "$name$_ = builderForValue.build();\n"
307     "$on_changed$\n",
308 
309     "$name$Builder_.setMessage(builderForValue.build());\n",
310 
311     "$set_has_field_bit_builder$\n"
312     "return this;\n");
313 
314   // Field.Builder mergeField(Field value)
315   WriteFieldDocComment(printer, descriptor_);
316   PrintNestedBuilderFunction(printer,
317     "$deprecation$public Builder merge$capitalized_name$($type$ value)",
318 
319     support_field_presence
320         ? "if ($get_has_field_bit_builder$ &&\n"
321           "    $name$_ != null &&\n"
322           "    $name$_ != $type$.getDefaultInstance()) {\n"
323           "  $name$_ =\n"
324           "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
325           "} else {\n"
326           "  $name$_ = value;\n"
327           "}\n"
328           "$on_changed$\n"
329         : "if ($name$_ != null) {\n"
330           "  $name$_ =\n"
331           "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
332           "} else {\n"
333           "  $name$_ = value;\n"
334           "}\n"
335           "$on_changed$\n",
336 
337     "$name$Builder_.mergeFrom(value);\n",
338 
339     "$set_has_field_bit_builder$\n"
340     "return this;\n");
341 
342   // Field.Builder clearField()
343   WriteFieldDocComment(printer, descriptor_);
344   PrintNestedBuilderFunction(printer,
345     "$deprecation$public Builder clear$capitalized_name$()",
346 
347     "$name$_ = null;\n"
348     "$on_changed$\n",
349 
350     support_field_presence
351         ? "$name$Builder_.clear();\n"
352         : "$name$_ = null;\n"
353           "$name$Builder_ = null;\n",
354 
355     "$clear_has_field_bit_builder$\n"
356     "return this;\n");
357 
358   WriteFieldDocComment(printer, descriptor_);
359   printer->Print(variables_,
360     "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
361     "  $set_has_field_bit_builder$\n"
362     "  $on_changed$\n"
363     "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
364     "}\n");
365   WriteFieldDocComment(printer, descriptor_);
366   printer->Print(variables_,
367     "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
368     "  if ($name$Builder_ != null) {\n"
369     "    return $name$Builder_.getMessageOrBuilder();\n"
370     "  } else {\n"
371     "    return $name$_ == null ?\n"
372     "        $type$.getDefaultInstance() : $name$_;\n"
373     "  }\n"
374     "}\n");
375   WriteFieldDocComment(printer, descriptor_);
376   printer->Print(variables_,
377     "private com.google.protobuf.SingleFieldBuilder<\n"
378     "    $type$, $type$.Builder, $type$OrBuilder> \n"
379     "    get$capitalized_name$FieldBuilder() {\n"
380     "  if ($name$Builder_ == null) {\n"
381     "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
382     "        $type$, $type$.Builder, $type$OrBuilder>(\n"
383     "            get$capitalized_name$(),\n"
384     "            getParentForChildren(),\n"
385     "            isClean());\n"
386     "    $name$_ = null;\n"
387     "  }\n"
388     "  return $name$Builder_;\n"
389     "}\n");
390 }
391 
392 void ImmutableMessageFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const393 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
394   if (SupportFieldPresence(descriptor_->file())) {
395     printer->Print(variables_,
396       "get$capitalized_name$FieldBuilder();\n");
397   }
398 }
399 
400 
401 void ImmutableMessageFieldGenerator::
GenerateInitializationCode(io::Printer * printer) const402 GenerateInitializationCode(io::Printer* printer) const {}
403 
404 void ImmutableMessageFieldGenerator::
GenerateBuilderClearCode(io::Printer * printer) const405 GenerateBuilderClearCode(io::Printer* printer) const {
406   if (SupportFieldPresence(descriptor_->file())) {
407     PrintNestedBuilderCondition(printer,
408       "$name$_ = null;\n",
409 
410       "$name$Builder_.clear();\n");
411     printer->Print(variables_, "$clear_has_field_bit_builder$\n");
412   } else {
413     PrintNestedBuilderCondition(printer,
414       "$name$_ = null;\n",
415 
416       "$name$_ = null;\n"
417       "$name$Builder_ = null;\n");
418   }
419 }
420 
421 void ImmutableMessageFieldGenerator::
GenerateMergingCode(io::Printer * printer) const422 GenerateMergingCode(io::Printer* printer) const {
423   printer->Print(variables_,
424     "if (other.has$capitalized_name$()) {\n"
425     "  merge$capitalized_name$(other.get$capitalized_name$());\n"
426     "}\n");
427 }
428 
429 void ImmutableMessageFieldGenerator::
GenerateBuildingCode(io::Printer * printer) const430 GenerateBuildingCode(io::Printer* printer) const {
431   if (SupportFieldPresence(descriptor_->file())) {
432     printer->Print(variables_,
433         "if ($get_has_field_bit_from_local$) {\n"
434         "  $set_has_field_bit_to_local$;\n"
435         "}\n");
436   }
437 
438   PrintNestedBuilderCondition(printer,
439     "result.$name$_ = $name$_;\n",
440 
441     "result.$name$_ = $name$Builder_.build();\n");
442 }
443 
444 void ImmutableMessageFieldGenerator::
GenerateParsingCode(io::Printer * printer) const445 GenerateParsingCode(io::Printer* printer) const {
446   printer->Print(variables_,
447     "$type$.Builder subBuilder = null;\n"
448     "if ($is_field_present_message$) {\n"
449     "  subBuilder = $name$_.toBuilder();\n"
450     "}\n");
451 
452   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
453     printer->Print(variables_,
454       "$name$_ = input.readGroup($number$, $type$.parser(),\n"
455       "    extensionRegistry);\n");
456   } else {
457     printer->Print(variables_,
458       "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
459   }
460 
461   printer->Print(variables_,
462     "if (subBuilder != null) {\n"
463     "  subBuilder.mergeFrom($name$_);\n"
464     "  $name$_ = subBuilder.buildPartial();\n"
465     "}\n"
466     "$set_has_field_bit_message$\n");
467 }
468 
469 void ImmutableMessageFieldGenerator::
GenerateParsingDoneCode(io::Printer * printer) const470 GenerateParsingDoneCode(io::Printer* printer) const {
471   // noop for messages.
472 }
473 
474 void ImmutableMessageFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const475 GenerateSerializationCode(io::Printer* printer) const {
476   printer->Print(variables_,
477     "if ($is_field_present_message$) {\n"
478     "  output.write$group_or_message$($number$, get$capitalized_name$());\n"
479     "}\n");
480 }
481 
482 void ImmutableMessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const483 GenerateSerializedSizeCode(io::Printer* printer) const {
484   printer->Print(variables_,
485     "if ($is_field_present_message$) {\n"
486     "  size += com.google.protobuf.CodedOutputStream\n"
487     "    .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
488     "}\n");
489 }
490 
491 void ImmutableMessageFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const492 GenerateEqualsCode(io::Printer* printer) const {
493   printer->Print(variables_,
494     "result = result && get$capitalized_name$()\n"
495     "    .equals(other.get$capitalized_name$());\n");
496 }
497 
498 void ImmutableMessageFieldGenerator::
GenerateHashCode(io::Printer * printer) const499 GenerateHashCode(io::Printer* printer) const {
500   printer->Print(variables_,
501     "hash = (37 * hash) + $constant_name$;\n"
502     "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
503 }
504 
GetBoxedType() const505 string ImmutableMessageFieldGenerator::GetBoxedType() const {
506   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
507 }
508 
509 // ===================================================================
510 
511 ImmutableMessageOneofFieldGenerator::
ImmutableMessageOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)512 ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
513                                  int messageBitIndex,
514                                  int builderBitIndex,
515                                  Context* context)
516     : ImmutableMessageFieldGenerator(
517           descriptor, messageBitIndex, builderBitIndex, context) {
518   const OneofGeneratorInfo* info =
519       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
520   SetCommonOneofVariables(descriptor, info, &variables_);
521 }
522 
523 ImmutableMessageOneofFieldGenerator::
~ImmutableMessageOneofFieldGenerator()524 ~ImmutableMessageOneofFieldGenerator() {}
525 
526 void ImmutableMessageOneofFieldGenerator::
GenerateMembers(io::Printer * printer) const527 GenerateMembers(io::Printer* printer) const {
528   PrintExtraFieldInfo(variables_, printer);
529   if (SupportFieldPresence(descriptor_->file())) {
530     WriteFieldDocComment(printer, descriptor_);
531     printer->Print(variables_,
532       "$deprecation$public boolean has$capitalized_name$() {\n"
533       "  return $has_oneof_case_message$;\n"
534       "}\n");
535   }
536   WriteFieldDocComment(printer, descriptor_);
537   printer->Print(variables_,
538     "$deprecation$public $type$ get$capitalized_name$() {\n"
539     "  if ($has_oneof_case_message$) {\n"
540     "     return ($type$) $oneof_name$_;\n"
541     "  }\n"
542     "  return $type$.getDefaultInstance();\n"
543     "}\n");
544 
545   WriteFieldDocComment(printer, descriptor_);
546   printer->Print(variables_,
547     "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
548     "  if ($has_oneof_case_message$) {\n"
549     "     return ($type$) $oneof_name$_;\n"
550     "  }\n"
551     "  return $type$.getDefaultInstance();\n"
552     "}\n");
553 }
554 
555 void ImmutableMessageOneofFieldGenerator::
GenerateBuilderMembers(io::Printer * printer) const556 GenerateBuilderMembers(io::Printer* printer) const {
557   // When using nested-builders, the code initially works just like the
558   // non-nested builder case. It only creates a nested builder lazily on
559   // demand and then forever delegates to it after creation.
560   printer->Print(variables_,
561     // If this builder is non-null, it is used and the other fields are
562     // ignored.
563     "private com.google.protobuf.SingleFieldBuilder<\n"
564     "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
565     "\n");
566 
567   // The comments above the methods below are based on a hypothetical
568   // field of type "Field" called "Field".
569 
570   if (SupportFieldPresence(descriptor_->file())) {
571     // boolean hasField()
572     WriteFieldDocComment(printer, descriptor_);
573     printer->Print(variables_,
574       "$deprecation$public boolean has$capitalized_name$() {\n"
575       "  return $has_oneof_case_message$;\n"
576       "}\n");
577   }
578 
579   // Field getField()
580   WriteFieldDocComment(printer, descriptor_);
581   PrintNestedBuilderFunction(printer,
582     "$deprecation$public $type$ get$capitalized_name$()",
583 
584     "if ($has_oneof_case_message$) {\n"
585     "  return ($type$) $oneof_name$_;\n"
586     "}\n"
587     "return $type$.getDefaultInstance();\n",
588 
589     "if ($has_oneof_case_message$) {\n"
590     "  return $name$Builder_.getMessage();\n"
591     "}\n"
592     "return $type$.getDefaultInstance();\n",
593 
594     NULL);
595 
596   // Field.Builder setField(Field value)
597   WriteFieldDocComment(printer, descriptor_);
598   PrintNestedBuilderFunction(printer,
599     "$deprecation$public Builder set$capitalized_name$($type$ value)",
600 
601     "if (value == null) {\n"
602     "  throw new NullPointerException();\n"
603     "}\n"
604     "$oneof_name$_ = value;\n"
605     "$on_changed$\n",
606 
607     "$name$Builder_.setMessage(value);\n",
608 
609     "$set_oneof_case_message$;\n"
610     "return this;\n");
611 
612   // Field.Builder setField(Field.Builder builderForValue)
613   WriteFieldDocComment(printer, descriptor_);
614   PrintNestedBuilderFunction(printer,
615     "$deprecation$public Builder set$capitalized_name$(\n"
616     "    $type$.Builder builderForValue)",
617 
618     "$oneof_name$_ = builderForValue.build();\n"
619     "$on_changed$\n",
620 
621     "$name$Builder_.setMessage(builderForValue.build());\n",
622 
623     "$set_oneof_case_message$;\n"
624     "return this;\n");
625 
626   // Field.Builder mergeField(Field value)
627   WriteFieldDocComment(printer, descriptor_);
628   PrintNestedBuilderFunction(printer,
629     "$deprecation$public Builder merge$capitalized_name$($type$ value)",
630 
631     "if ($has_oneof_case_message$ &&\n"
632     "    $oneof_name$_ != $type$.getDefaultInstance()) {\n"
633     "  $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
634     "      .mergeFrom(value).buildPartial();\n"
635     "} else {\n"
636     "  $oneof_name$_ = value;\n"
637     "}\n"
638     "$on_changed$\n",
639 
640     "if ($has_oneof_case_message$) {\n"
641     "  $name$Builder_.mergeFrom(value);\n"
642     "}\n"
643     "$name$Builder_.setMessage(value);\n",
644 
645     "$set_oneof_case_message$;\n"
646     "return this;\n");
647 
648   // Field.Builder clearField()
649   WriteFieldDocComment(printer, descriptor_);
650   PrintNestedBuilderFunction(printer,
651     "$deprecation$public Builder clear$capitalized_name$()",
652 
653     "if ($has_oneof_case_message$) {\n"
654     "  $clear_oneof_case_message$;\n"
655     "  $oneof_name$_ = null;\n"
656     "  $on_changed$\n"
657     "}\n",
658 
659     "if ($has_oneof_case_message$) {\n"
660     "  $clear_oneof_case_message$;\n"
661     "  $oneof_name$_ = null;\n"
662     "}\n"
663     "$name$Builder_.clear();\n",
664 
665     "return this;\n");
666 
667   WriteFieldDocComment(printer, descriptor_);
668   printer->Print(variables_,
669     "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
670     "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
671     "}\n");
672   WriteFieldDocComment(printer, descriptor_);
673   printer->Print(variables_,
674     "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
675     "  if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
676     "    return $name$Builder_.getMessageOrBuilder();\n"
677     "  } else {\n"
678     "    if ($has_oneof_case_message$) {\n"
679     "      return ($type$) $oneof_name$_;\n"
680     "    }\n"
681     "    return $type$.getDefaultInstance();\n"
682     "  }\n"
683     "}\n");
684   WriteFieldDocComment(printer, descriptor_);
685   printer->Print(variables_,
686     "private com.google.protobuf.SingleFieldBuilder<\n"
687     "    $type$, $type$.Builder, $type$OrBuilder> \n"
688     "    get$capitalized_name$FieldBuilder() {\n"
689     "  if ($name$Builder_ == null) {\n"
690     "    if (!($has_oneof_case_message$)) {\n"
691     "      $oneof_name$_ = $type$.getDefaultInstance();\n"
692     "    }\n"
693     "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
694     "        $type$, $type$.Builder, $type$OrBuilder>(\n"
695     "            ($type$) $oneof_name$_,\n"
696     "            getParentForChildren(),\n"
697     "            isClean());\n"
698     "    $oneof_name$_ = null;\n"
699     "  }\n"
700     "  $set_oneof_case_message$;\n"
701     "  $on_changed$;\n"
702     "  return $name$Builder_;\n"
703     "}\n");
704 }
705 
706 void ImmutableMessageOneofFieldGenerator::
GenerateBuildingCode(io::Printer * printer) const707 GenerateBuildingCode(io::Printer* printer) const {
708 
709   printer->Print(variables_,
710                  "if ($has_oneof_case_message$) {\n");
711   printer->Indent();
712 
713   PrintNestedBuilderCondition(printer,
714     "result.$oneof_name$_ = $oneof_name$_;\n",
715 
716     "result.$oneof_name$_ = $name$Builder_.build();\n");
717 
718   printer->Outdent();
719   printer->Print("}\n");
720 }
721 
722 void ImmutableMessageOneofFieldGenerator::
GenerateMergingCode(io::Printer * printer) const723 GenerateMergingCode(io::Printer* printer) const {
724   printer->Print(variables_,
725     "merge$capitalized_name$(other.get$capitalized_name$());\n");
726 }
727 
728 void ImmutableMessageOneofFieldGenerator::
GenerateParsingCode(io::Printer * printer) const729 GenerateParsingCode(io::Printer* printer) const {
730   printer->Print(variables_,
731     "$type$.Builder subBuilder = null;\n"
732     "if ($has_oneof_case_message$) {\n"
733     "  subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
734     "}\n");
735 
736   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
737     printer->Print(variables_,
738       "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
739       "    extensionRegistry);\n");
740   } else {
741     printer->Print(variables_,
742       "$oneof_name$_ =\n"
743       "    input.readMessage($type$.parser(), extensionRegistry);\n");
744   }
745 
746   printer->Print(variables_,
747     "if (subBuilder != null) {\n"
748     "  subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
749     "  $oneof_name$_ = subBuilder.buildPartial();\n"
750     "}\n");
751   printer->Print(variables_,
752     "$set_oneof_case_message$;\n");
753 }
754 
755 void ImmutableMessageOneofFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const756 GenerateSerializationCode(io::Printer* printer) const {
757   printer->Print(variables_,
758     "if ($has_oneof_case_message$) {\n"
759     "  output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
760     "}\n");
761 }
762 
763 void ImmutableMessageOneofFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const764 GenerateSerializedSizeCode(io::Printer* printer) const {
765   printer->Print(variables_,
766     "if ($has_oneof_case_message$) {\n"
767     "  size += com.google.protobuf.CodedOutputStream\n"
768     "    .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
769     "}\n");
770 }
771 
772 // ===================================================================
773 
774 RepeatedImmutableMessageFieldGenerator::
RepeatedImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)775 RepeatedImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
776                                        int messageBitIndex,
777                                        int builderBitIndex,
778                                        Context* context)
779   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
780     builderBitIndex_(builderBitIndex), context_(context),
781     name_resolver_(context->GetNameResolver())  {
782   SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
783                       context->GetFieldGeneratorInfo(descriptor),
784                       name_resolver_, &variables_);
785 }
786 
787 RepeatedImmutableMessageFieldGenerator::
~RepeatedImmutableMessageFieldGenerator()788 ~RepeatedImmutableMessageFieldGenerator() {}
789 
GetNumBitsForMessage() const790 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
791   return 0;
792 }
793 
GetNumBitsForBuilder() const794 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
795   return 1;
796 }
797 
798 void RepeatedImmutableMessageFieldGenerator::
GenerateInterfaceMembers(io::Printer * printer) const799 GenerateInterfaceMembers(io::Printer* printer) const {
800   // TODO(jonp): In the future, consider having methods specific to the
801   // interface so that builders can choose dynamically to either return a
802   // message or a nested builder, so that asking for the interface doesn't
803   // cause a message to ever be built.
804   WriteFieldDocComment(printer, descriptor_);
805   printer->Print(variables_,
806     "$deprecation$java.util.List<$type$> \n"
807     "    get$capitalized_name$List();\n");
808   WriteFieldDocComment(printer, descriptor_);
809   printer->Print(variables_,
810     "$deprecation$$type$ get$capitalized_name$(int index);\n");
811   WriteFieldDocComment(printer, descriptor_);
812   printer->Print(variables_,
813     "$deprecation$int get$capitalized_name$Count();\n");
814 
815   WriteFieldDocComment(printer, descriptor_);
816   printer->Print(variables_,
817     "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
818     "    get$capitalized_name$OrBuilderList();\n");
819   WriteFieldDocComment(printer, descriptor_);
820   printer->Print(variables_,
821     "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
822     "    int index);\n");
823 }
824 
825 void RepeatedImmutableMessageFieldGenerator::
GenerateMembers(io::Printer * printer) const826 GenerateMembers(io::Printer* printer) const {
827   printer->Print(variables_,
828     "private java.util.List<$type$> $name$_;\n");
829   PrintExtraFieldInfo(variables_, printer);
830   WriteFieldDocComment(printer, descriptor_);
831   printer->Print(variables_,
832     "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
833     "  return $name$_;\n"   // note:  unmodifiable list
834     "}\n");
835   WriteFieldDocComment(printer, descriptor_);
836   printer->Print(variables_,
837     "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
838     "    get$capitalized_name$OrBuilderList() {\n"
839     "  return $name$_;\n"
840     "}\n");
841   WriteFieldDocComment(printer, descriptor_);
842   printer->Print(variables_,
843     "$deprecation$public int get$capitalized_name$Count() {\n"
844     "  return $name$_.size();\n"
845     "}\n");
846   WriteFieldDocComment(printer, descriptor_);
847   printer->Print(variables_,
848     "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
849     "  return $name$_.get(index);\n"
850     "}\n");
851   WriteFieldDocComment(printer, descriptor_);
852   printer->Print(variables_,
853     "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
854     "    int index) {\n"
855     "  return $name$_.get(index);\n"
856     "}\n");
857 
858 }
859 
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const860 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
861     io::Printer* printer,
862     const char* regular_case,
863     const char* nested_builder_case) const {
864   printer->Print(variables_, "if ($name$Builder_ == null) {\n");
865   printer->Indent();
866   printer->Print(variables_, regular_case);
867   printer->Outdent();
868   printer->Print("} else {\n");
869   printer->Indent();
870   printer->Print(variables_, nested_builder_case);
871   printer->Outdent();
872   printer->Print("}\n");
873 }
874 
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const875 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
876     io::Printer* printer,
877     const char* method_prototype,
878     const char* regular_case,
879     const char* nested_builder_case,
880     const char* trailing_code) const {
881   printer->Print(variables_, method_prototype);
882   printer->Print(" {\n");
883   printer->Indent();
884   PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
885   if (trailing_code != NULL) {
886     printer->Print(variables_, trailing_code);
887   }
888   printer->Outdent();
889   printer->Print("}\n");
890 }
891 
892 void RepeatedImmutableMessageFieldGenerator::
GenerateBuilderMembers(io::Printer * printer) const893 GenerateBuilderMembers(io::Printer* printer) const {
894   // When using nested-builders, the code initially works just like the
895   // non-nested builder case. It only creates a nested builder lazily on
896   // demand and then forever delegates to it after creation.
897 
898   printer->Print(variables_,
899     // Used when the builder is null.
900     // One field is the list and the other field keeps track of whether the
901     // list is immutable. If it's immutable, the invariant is that it must
902     // either an instance of Collections.emptyList() or it's an ArrayList
903     // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
904     // a refererence to the underlying ArrayList. This invariant allows us to
905     // share instances of lists between protocol buffers avoiding expensive
906     // memory allocations. Note, immutable is a strong guarantee here -- not
907     // just that the list cannot be modified via the reference but that the
908     // list can never be modified.
909     "private java.util.List<$type$> $name$_ =\n"
910     "  java.util.Collections.emptyList();\n"
911 
912     "private void ensure$capitalized_name$IsMutable() {\n"
913     "  if (!$get_mutable_bit_builder$) {\n"
914     "    $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
915     "    $set_mutable_bit_builder$;\n"
916     "   }\n"
917     "}\n"
918     "\n");
919 
920   printer->Print(variables_,
921     // If this builder is non-null, it is used and the other fields are
922     // ignored.
923     "private com.google.protobuf.RepeatedFieldBuilder<\n"
924     "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
925     "\n");
926 
927   // The comments above the methods below are based on a hypothetical
928   // repeated field of type "Field" called "RepeatedField".
929 
930   // List<Field> getRepeatedFieldList()
931   WriteFieldDocComment(printer, descriptor_);
932   PrintNestedBuilderFunction(printer,
933     "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
934 
935     "return java.util.Collections.unmodifiableList($name$_);\n",
936     "return $name$Builder_.getMessageList();\n",
937 
938     NULL);
939 
940   // int getRepeatedFieldCount()
941   WriteFieldDocComment(printer, descriptor_);
942   PrintNestedBuilderFunction(printer,
943     "$deprecation$public int get$capitalized_name$Count()",
944 
945     "return $name$_.size();\n",
946     "return $name$Builder_.getCount();\n",
947 
948     NULL);
949 
950   // Field getRepeatedField(int index)
951   WriteFieldDocComment(printer, descriptor_);
952   PrintNestedBuilderFunction(printer,
953     "$deprecation$public $type$ get$capitalized_name$(int index)",
954 
955     "return $name$_.get(index);\n",
956 
957     "return $name$Builder_.getMessage(index);\n",
958 
959     NULL);
960 
961   // Builder setRepeatedField(int index, Field value)
962   WriteFieldDocComment(printer, descriptor_);
963   PrintNestedBuilderFunction(printer,
964     "$deprecation$public Builder set$capitalized_name$(\n"
965     "    int index, $type$ value)",
966     "if (value == null) {\n"
967     "  throw new NullPointerException();\n"
968     "}\n"
969     "ensure$capitalized_name$IsMutable();\n"
970     "$name$_.set(index, value);\n"
971     "$on_changed$\n",
972     "$name$Builder_.setMessage(index, value);\n",
973     "return this;\n");
974 
975   // Builder setRepeatedField(int index, Field.Builder builderForValue)
976   WriteFieldDocComment(printer, descriptor_);
977   PrintNestedBuilderFunction(printer,
978     "$deprecation$public Builder set$capitalized_name$(\n"
979     "    int index, $type$.Builder builderForValue)",
980 
981     "ensure$capitalized_name$IsMutable();\n"
982     "$name$_.set(index, builderForValue.build());\n"
983     "$on_changed$\n",
984 
985     "$name$Builder_.setMessage(index, builderForValue.build());\n",
986 
987     "return this;\n");
988 
989   // Builder addRepeatedField(Field value)
990   WriteFieldDocComment(printer, descriptor_);
991   PrintNestedBuilderFunction(printer,
992     "$deprecation$public Builder add$capitalized_name$($type$ value)",
993 
994     "if (value == null) {\n"
995     "  throw new NullPointerException();\n"
996     "}\n"
997     "ensure$capitalized_name$IsMutable();\n"
998     "$name$_.add(value);\n"
999 
1000     "$on_changed$\n",
1001 
1002     "$name$Builder_.addMessage(value);\n",
1003 
1004     "return this;\n");
1005 
1006   // Builder addRepeatedField(int index, Field value)
1007   WriteFieldDocComment(printer, descriptor_);
1008   PrintNestedBuilderFunction(printer,
1009     "$deprecation$public Builder add$capitalized_name$(\n"
1010     "    int index, $type$ value)",
1011 
1012     "if (value == null) {\n"
1013     "  throw new NullPointerException();\n"
1014     "}\n"
1015     "ensure$capitalized_name$IsMutable();\n"
1016     "$name$_.add(index, value);\n"
1017     "$on_changed$\n",
1018 
1019     "$name$Builder_.addMessage(index, value);\n",
1020 
1021     "return this;\n");
1022 
1023   // Builder addRepeatedField(Field.Builder builderForValue)
1024   WriteFieldDocComment(printer, descriptor_);
1025   PrintNestedBuilderFunction(printer,
1026     "$deprecation$public Builder add$capitalized_name$(\n"
1027     "    $type$.Builder builderForValue)",
1028 
1029     "ensure$capitalized_name$IsMutable();\n"
1030     "$name$_.add(builderForValue.build());\n"
1031     "$on_changed$\n",
1032 
1033     "$name$Builder_.addMessage(builderForValue.build());\n",
1034 
1035     "return this;\n");
1036 
1037   // Builder addRepeatedField(int index, Field.Builder builderForValue)
1038   WriteFieldDocComment(printer, descriptor_);
1039   PrintNestedBuilderFunction(printer,
1040     "$deprecation$public Builder add$capitalized_name$(\n"
1041     "    int index, $type$.Builder builderForValue)",
1042 
1043     "ensure$capitalized_name$IsMutable();\n"
1044     "$name$_.add(index, builderForValue.build());\n"
1045     "$on_changed$\n",
1046 
1047     "$name$Builder_.addMessage(index, builderForValue.build());\n",
1048 
1049     "return this;\n");
1050 
1051   // Builder addAllRepeatedField(Iterable<Field> values)
1052   WriteFieldDocComment(printer, descriptor_);
1053   PrintNestedBuilderFunction(printer,
1054     "$deprecation$public Builder addAll$capitalized_name$(\n"
1055     "    java.lang.Iterable<? extends $type$> values)",
1056 
1057     "ensure$capitalized_name$IsMutable();\n"
1058     "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
1059     "    values, $name$_);\n"
1060     "$on_changed$\n",
1061 
1062     "$name$Builder_.addAllMessages(values);\n",
1063 
1064     "return this;\n");
1065 
1066   // Builder clearAllRepeatedField()
1067   WriteFieldDocComment(printer, descriptor_);
1068   PrintNestedBuilderFunction(printer,
1069     "$deprecation$public Builder clear$capitalized_name$()",
1070 
1071     "$name$_ = java.util.Collections.emptyList();\n"
1072     "$clear_mutable_bit_builder$;\n"
1073     "$on_changed$\n",
1074 
1075     "$name$Builder_.clear();\n",
1076 
1077     "return this;\n");
1078 
1079   // Builder removeRepeatedField(int index)
1080   WriteFieldDocComment(printer, descriptor_);
1081   PrintNestedBuilderFunction(printer,
1082     "$deprecation$public Builder remove$capitalized_name$(int index)",
1083 
1084     "ensure$capitalized_name$IsMutable();\n"
1085     "$name$_.remove(index);\n"
1086     "$on_changed$\n",
1087 
1088     "$name$Builder_.remove(index);\n",
1089 
1090     "return this;\n");
1091 
1092   WriteFieldDocComment(printer, descriptor_);
1093   printer->Print(variables_,
1094     "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
1095     "    int index) {\n"
1096     "  return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
1097     "}\n");
1098 
1099   WriteFieldDocComment(printer, descriptor_);
1100       printer->Print(variables_,
1101     "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
1102     "    int index) {\n"
1103     "  if ($name$Builder_ == null) {\n"
1104     "    return $name$_.get(index);"
1105     "  } else {\n"
1106     "    return $name$Builder_.getMessageOrBuilder(index);\n"
1107     "  }\n"
1108     "}\n");
1109 
1110   WriteFieldDocComment(printer, descriptor_);
1111       printer->Print(variables_,
1112     "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
1113     "     get$capitalized_name$OrBuilderList() {\n"
1114     "  if ($name$Builder_ != null) {\n"
1115     "    return $name$Builder_.getMessageOrBuilderList();\n"
1116     "  } else {\n"
1117     "    return java.util.Collections.unmodifiableList($name$_);\n"
1118     "  }\n"
1119     "}\n");
1120 
1121   WriteFieldDocComment(printer, descriptor_);
1122       printer->Print(variables_,
1123     "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
1124     "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
1125     "      $type$.getDefaultInstance());\n"
1126     "}\n");
1127   WriteFieldDocComment(printer, descriptor_);
1128       printer->Print(variables_,
1129     "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
1130     "    int index) {\n"
1131     "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
1132     "      index, $type$.getDefaultInstance());\n"
1133     "}\n");
1134   WriteFieldDocComment(printer, descriptor_);
1135       printer->Print(variables_,
1136     "$deprecation$public java.util.List<$type$.Builder> \n"
1137     "     get$capitalized_name$BuilderList() {\n"
1138     "  return get$capitalized_name$FieldBuilder().getBuilderList();\n"
1139     "}\n"
1140     "private com.google.protobuf.RepeatedFieldBuilder<\n"
1141     "    $type$, $type$.Builder, $type$OrBuilder> \n"
1142     "    get$capitalized_name$FieldBuilder() {\n"
1143     "  if ($name$Builder_ == null) {\n"
1144     "    $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n"
1145     "        $type$, $type$.Builder, $type$OrBuilder>(\n"
1146     "            $name$_,\n"
1147     "            $get_mutable_bit_builder$,\n"
1148     "            getParentForChildren(),\n"
1149     "            isClean());\n"
1150     "    $name$_ = null;\n"
1151     "  }\n"
1152     "  return $name$Builder_;\n"
1153     "}\n");
1154 }
1155 
1156 void RepeatedImmutableMessageFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const1157 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
1158   printer->Print(variables_,
1159     "get$capitalized_name$FieldBuilder();\n");
1160 }
1161 
1162 void RepeatedImmutableMessageFieldGenerator::
GenerateInitializationCode(io::Printer * printer) const1163 GenerateInitializationCode(io::Printer* printer) const {
1164   printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
1165 }
1166 
1167 void RepeatedImmutableMessageFieldGenerator::
GenerateBuilderClearCode(io::Printer * printer) const1168 GenerateBuilderClearCode(io::Printer* printer) const {
1169   PrintNestedBuilderCondition(printer,
1170     "$name$_ = java.util.Collections.emptyList();\n"
1171     "$clear_mutable_bit_builder$;\n",
1172 
1173     "$name$Builder_.clear();\n");
1174 }
1175 
1176 void RepeatedImmutableMessageFieldGenerator::
GenerateMergingCode(io::Printer * printer) const1177 GenerateMergingCode(io::Printer* printer) const {
1178   // The code below does two optimizations (non-nested builder case):
1179   //   1. If the other list is empty, there's nothing to do. This ensures we
1180   //      don't allocate a new array if we already have an immutable one.
1181   //   2. If the other list is non-empty and our current list is empty, we can
1182   //      reuse the other list which is guaranteed to be immutable.
1183   PrintNestedBuilderCondition(printer,
1184     "if (!other.$name$_.isEmpty()) {\n"
1185     "  if ($name$_.isEmpty()) {\n"
1186     "    $name$_ = other.$name$_;\n"
1187     "    $clear_mutable_bit_builder$;\n"
1188     "  } else {\n"
1189     "    ensure$capitalized_name$IsMutable();\n"
1190     "    $name$_.addAll(other.$name$_);\n"
1191     "  }\n"
1192     "  $on_changed$\n"
1193     "}\n",
1194 
1195     "if (!other.$name$_.isEmpty()) {\n"
1196     "  if ($name$Builder_.isEmpty()) {\n"
1197     "    $name$Builder_.dispose();\n"
1198     "    $name$Builder_ = null;\n"
1199     "    $name$_ = other.$name$_;\n"
1200     "    $clear_mutable_bit_builder$;\n"
1201     "    $name$Builder_ = \n"
1202     "      com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n"
1203     "         get$capitalized_name$FieldBuilder() : null;\n"
1204     "  } else {\n"
1205     "    $name$Builder_.addAllMessages(other.$name$_);\n"
1206     "  }\n"
1207     "}\n");
1208 }
1209 
1210 void RepeatedImmutableMessageFieldGenerator::
GenerateBuildingCode(io::Printer * printer) const1211 GenerateBuildingCode(io::Printer* printer) const {
1212   // The code below (non-nested builder case) ensures that the result has an
1213   // immutable list. If our list is immutable, we can just reuse it. If not,
1214   // we make it immutable.
1215   PrintNestedBuilderCondition(printer,
1216     "if ($get_mutable_bit_builder$) {\n"
1217     "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1218     "  $clear_mutable_bit_builder$;\n"
1219     "}\n"
1220     "result.$name$_ = $name$_;\n",
1221 
1222     "result.$name$_ = $name$Builder_.build();\n");
1223 }
1224 
1225 void RepeatedImmutableMessageFieldGenerator::
GenerateParsingCode(io::Printer * printer) const1226 GenerateParsingCode(io::Printer* printer) const {
1227   printer->Print(variables_,
1228     "if (!$get_mutable_bit_parser$) {\n"
1229     "  $name$_ = new java.util.ArrayList<$type$>();\n"
1230     "  $set_mutable_bit_parser$;\n"
1231     "}\n");
1232 
1233   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
1234     printer->Print(variables_,
1235       "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
1236       "    extensionRegistry));\n");
1237   } else {
1238     printer->Print(variables_,
1239       "$name$_.add(input.readMessage($type$.parser(), extensionRegistry));\n");
1240   }
1241 }
1242 
1243 void RepeatedImmutableMessageFieldGenerator::
GenerateParsingDoneCode(io::Printer * printer) const1244 GenerateParsingDoneCode(io::Printer* printer) const {
1245   printer->Print(variables_,
1246     "if ($get_mutable_bit_parser$) {\n"
1247     "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1248     "}\n");
1249 }
1250 
1251 void RepeatedImmutableMessageFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const1252 GenerateSerializationCode(io::Printer* printer) const {
1253   printer->Print(variables_,
1254     "for (int i = 0; i < $name$_.size(); i++) {\n"
1255     "  output.write$group_or_message$($number$, $name$_.get(i));\n"
1256     "}\n");
1257 }
1258 
1259 void RepeatedImmutableMessageFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const1260 GenerateSerializedSizeCode(io::Printer* printer) const {
1261   printer->Print(variables_,
1262     "for (int i = 0; i < $name$_.size(); i++) {\n"
1263     "  size += com.google.protobuf.CodedOutputStream\n"
1264     "    .compute$group_or_message$Size($number$, $name$_.get(i));\n"
1265     "}\n");
1266 }
1267 
1268 void RepeatedImmutableMessageFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const1269 GenerateEqualsCode(io::Printer* printer) const {
1270   printer->Print(variables_,
1271     "result = result && get$capitalized_name$List()\n"
1272     "    .equals(other.get$capitalized_name$List());\n");
1273 }
1274 
1275 void RepeatedImmutableMessageFieldGenerator::
GenerateHashCode(io::Printer * printer) const1276 GenerateHashCode(io::Printer* printer) const {
1277   printer->Print(variables_,
1278     "if (get$capitalized_name$Count() > 0) {\n"
1279     "  hash = (37 * hash) + $constant_name$;\n"
1280     "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
1281     "}\n");
1282 }
1283 
GetBoxedType() const1284 string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
1285   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
1286 }
1287 
1288 }  // namespace java
1289 }  // namespace compiler
1290 }  // namespace protobuf
1291 }  // namespace google
1292