• 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_doc_comment.h>
40 #include <google/protobuf/compiler/java/java_helpers.h>
41 #include <google/protobuf/compiler/java/java_message_field.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,std::map<std::string,std::string> * variables)54 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
55                          int builderBitIndex, const FieldGeneratorInfo* info,
56                          ClassNameResolver* name_resolver,
57                          std::map<std::string, std::string>* variables) {
58   SetCommonFieldVariables(descriptor, info, variables);
59 
60   (*variables)["type"] =
61       name_resolver->GetImmutableClassName(descriptor->message_type());
62   (*variables)["mutable_type"] =
63       name_resolver->GetMutableClassName(descriptor->message_type());
64   (*variables)["group_or_message"] =
65       (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
66                                                            : "Message";
67   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
68   // by the proto compiler
69   (*variables)["deprecation"] =
70       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
71   (*variables)["on_changed"] = "onChanged();";
72   (*variables)["ver"] = GeneratedCodeVersionSuffix();
73   (*variables)["get_parser"] =
74       ExposePublicParser(descriptor->message_type()->file()) ? "PARSER"
75                                                              : "parser()";
76 
77   if (HasHasbit(descriptor)) {
78     // For singular messages and builders, one bit is used for the hasField bit.
79     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
80     (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
81 
82     // Note that these have a trailing ";".
83     (*variables)["set_has_field_bit_message"] =
84         GenerateSetBit(messageBitIndex) + ";";
85     (*variables)["set_has_field_bit_builder"] =
86         GenerateSetBit(builderBitIndex) + ";";
87     (*variables)["clear_has_field_bit_builder"] =
88         GenerateClearBit(builderBitIndex) + ";";
89 
90     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
91   } else {
92     (*variables)["set_has_field_bit_message"] = "";
93     (*variables)["set_has_field_bit_builder"] = "";
94     (*variables)["clear_has_field_bit_builder"] = "";
95 
96     (*variables)["is_field_present_message"] =
97         (*variables)["name"] + "_ != null";
98   }
99 
100   // For repeated builders, one bit is used for whether the array is immutable.
101   (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
102   (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
103   (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
104 
105   // For repeated fields, one bit is used for whether the array is immutable
106   // in the parsing constructor.
107   (*variables)["get_mutable_bit_parser"] =
108       GenerateGetBitMutableLocal(builderBitIndex);
109   (*variables)["set_mutable_bit_parser"] =
110       GenerateSetBitMutableLocal(builderBitIndex);
111 
112   (*variables)["get_has_field_bit_from_local"] =
113       GenerateGetBitFromLocal(builderBitIndex);
114   (*variables)["set_has_field_bit_to_local"] =
115       GenerateSetBitToLocal(messageBitIndex);
116 }
117 
118 }  // namespace
119 
120 // ===================================================================
121 
ImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)122 ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator(
123     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
124     Context* context)
125     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
126   SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
127                       context->GetFieldGeneratorInfo(descriptor),
128                       name_resolver_, &variables_);
129 }
130 
~ImmutableMessageFieldGenerator()131 ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
132 
GetNumBitsForMessage() const133 int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
134   return HasHasbit(descriptor_) ? 1 : 0;
135 }
136 
GetNumBitsForBuilder() const137 int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
138   return GetNumBitsForMessage();
139 }
140 
GenerateInterfaceMembers(io::Printer * printer) const141 void ImmutableMessageFieldGenerator::GenerateInterfaceMembers(
142     io::Printer* printer) const {
143   // TODO(jonp): In the future, consider having a method specific to the
144   // interface so that builders can choose dynamically to either return a
145   // message or a nested builder, so that asking for the interface doesn't
146   // cause a message to ever be built.
147   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
148   printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
149   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
150   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
151 
152   WriteFieldDocComment(printer, descriptor_);
153   printer->Print(
154       variables_,
155       "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
156 }
157 
GenerateMembers(io::Printer * printer) const158 void ImmutableMessageFieldGenerator::GenerateMembers(
159     io::Printer* printer) const {
160   printer->Print(variables_, "private $type$ $name$_;\n");
161   PrintExtraFieldInfo(variables_, printer);
162 
163   if (HasHasbit(descriptor_)) {
164     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
165     printer->Print(
166         variables_,
167         "@java.lang.Override\n"
168         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
169         "  return $get_has_field_bit_message$;\n"
170         "}\n");
171     printer->Annotate("{", "}", descriptor_);
172     WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
173     printer->Print(
174         variables_,
175         "@java.lang.Override\n"
176         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
177         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
178         "}\n");
179     printer->Annotate("{", "}", descriptor_);
180 
181     WriteFieldDocComment(printer, descriptor_);
182     printer->Print(
183         variables_,
184         "@java.lang.Override\n"
185         "$deprecation$public $type$OrBuilder "
186         "${$get$capitalized_name$OrBuilder$}$() {\n"
187         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
188         "}\n");
189     printer->Annotate("{", "}", descriptor_);
190   } else {
191     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
192     printer->Print(
193         variables_,
194         "@java.lang.Override\n"
195         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
196         "  return $name$_ != null;\n"
197         "}\n");
198     printer->Annotate("{", "}", descriptor_);
199     WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
200     printer->Print(
201         variables_,
202         "@java.lang.Override\n"
203         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
204         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
205         "}\n");
206     printer->Annotate("{", "}", descriptor_);
207 
208     WriteFieldDocComment(printer, descriptor_);
209     printer->Print(variables_,
210                    "@java.lang.Override\n"
211                    "$deprecation$public $type$OrBuilder "
212                    "${$get$capitalized_name$OrBuilder$}$() {\n"
213                    "  return get$capitalized_name$();\n"
214                    "}\n");
215     printer->Annotate("{", "}", descriptor_);
216   }
217 }
218 
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const219 void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
220     io::Printer* printer, const char* regular_case,
221     const char* nested_builder_case) const {
222   printer->Print(variables_, "if ($name$Builder_ == null) {\n");
223   printer->Indent();
224   printer->Print(variables_, regular_case);
225   printer->Outdent();
226   printer->Print("} else {\n");
227   printer->Indent();
228   printer->Print(variables_, nested_builder_case);
229   printer->Outdent();
230   printer->Print("}\n");
231 }
232 
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const233 void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
234     io::Printer* printer, const char* method_prototype,
235     const char* regular_case, const char* nested_builder_case,
236     const char* trailing_code) const {
237   printer->Print(variables_, method_prototype);
238   printer->Annotate("{", "}", descriptor_);
239   printer->Print(" {\n");
240   printer->Indent();
241   PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
242   if (trailing_code != NULL) {
243     printer->Print(variables_, trailing_code);
244   }
245   printer->Outdent();
246   printer->Print("}\n");
247 }
248 
GenerateBuilderMembers(io::Printer * printer) const249 void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
250     io::Printer* printer) const {
251   // When using nested-builders, the code initially works just like the
252   // non-nested builder case. It only creates a nested builder lazily on
253   // demand and then forever delegates to it after creation.
254 
255   bool has_hasbit = HasHasbit(descriptor_);
256 
257   printer->Print(variables_, "private $type$ $name$_;\n");
258 
259   printer->Print(variables_,
260                  // If this builder is non-null, it is used and the other fields
261                  // are ignored.
262                  "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
263                  "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
264                  "\n");
265 
266   // The comments above the methods below are based on a hypothetical
267   // field of type "Field" called "Field".
268 
269   // boolean hasField()
270   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
271   if (has_hasbit) {
272     printer->Print(
273         variables_,
274         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
275         "  return $get_has_field_bit_builder$;\n"
276         "}\n");
277     printer->Annotate("{", "}", descriptor_);
278   } else {
279     printer->Print(
280         variables_,
281         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
282         "  return $name$Builder_ != null || $name$_ != null;\n"
283         "}\n");
284     printer->Annotate("{", "}", descriptor_);
285   }
286 
287   // Field getField()
288   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
289   PrintNestedBuilderFunction(
290       printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
291       "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
292       "return $name$Builder_.getMessage();\n", NULL);
293 
294   // Field.Builder setField(Field value)
295   WriteFieldDocComment(printer, descriptor_);
296   PrintNestedBuilderFunction(
297       printer,
298       "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
299 
300       "if (value == null) {\n"
301       "  throw new NullPointerException();\n"
302       "}\n"
303       "$name$_ = value;\n"
304       "$on_changed$\n",
305 
306       "$name$Builder_.setMessage(value);\n",
307 
308       "$set_has_field_bit_builder$\n"
309       "return this;\n");
310 
311   // Field.Builder setField(Field.Builder builderForValue)
312   WriteFieldDocComment(printer, descriptor_);
313   PrintNestedBuilderFunction(
314       printer,
315       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
316       "    $type$.Builder builderForValue)",
317 
318       "$name$_ = builderForValue.build();\n"
319       "$on_changed$\n",
320 
321       "$name$Builder_.setMessage(builderForValue.build());\n",
322 
323       "$set_has_field_bit_builder$\n"
324       "return this;\n");
325 
326   // Field.Builder mergeField(Field value)
327   WriteFieldDocComment(printer, descriptor_);
328   PrintNestedBuilderFunction(
329       printer,
330       "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
331 
332       has_hasbit
333           ? "if ($get_has_field_bit_builder$ &&\n"
334             "    $name$_ != null &&\n"
335             "    $name$_ != $type$.getDefaultInstance()) {\n"
336             "  $name$_ =\n"
337             "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
338             "} else {\n"
339             "  $name$_ = value;\n"
340             "}\n"
341             "$on_changed$\n"
342           : "if ($name$_ != null) {\n"
343             "  $name$_ =\n"
344             "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
345             "} else {\n"
346             "  $name$_ = value;\n"
347             "}\n"
348             "$on_changed$\n",
349 
350       "$name$Builder_.mergeFrom(value);\n",
351 
352       "$set_has_field_bit_builder$\n"
353       "return this;\n");
354 
355   // Field.Builder clearField()
356   WriteFieldDocComment(printer, descriptor_);
357   PrintNestedBuilderFunction(
358       printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
359 
360       "$name$_ = null;\n"
361       "$on_changed$\n",
362 
363       has_hasbit ? "$name$Builder_.clear();\n"
364                  : "$name$_ = null;\n"
365                    "$name$Builder_ = null;\n",
366 
367       "$clear_has_field_bit_builder$\n"
368       "return this;\n");
369 
370   WriteFieldDocComment(printer, descriptor_);
371   printer->Print(variables_,
372                  "$deprecation$public $type$.Builder "
373                  "${$get$capitalized_name$Builder$}$() {\n"
374                  "  $set_has_field_bit_builder$\n"
375                  "  $on_changed$\n"
376                  "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
377                  "}\n");
378   printer->Annotate("{", "}", descriptor_);
379   WriteFieldDocComment(printer, descriptor_);
380   printer->Print(variables_,
381                  "$deprecation$public $type$OrBuilder "
382                  "${$get$capitalized_name$OrBuilder$}$() {\n"
383                  "  if ($name$Builder_ != null) {\n"
384                  "    return $name$Builder_.getMessageOrBuilder();\n"
385                  "  } else {\n"
386                  "    return $name$_ == null ?\n"
387                  "        $type$.getDefaultInstance() : $name$_;\n"
388                  "  }\n"
389                  "}\n");
390   printer->Annotate("{", "}", descriptor_);
391   WriteFieldDocComment(printer, descriptor_);
392   printer->Print(
393       variables_,
394       "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
395       "    $type$, $type$.Builder, $type$OrBuilder> \n"
396       "    get$capitalized_name$FieldBuilder() {\n"
397       "  if ($name$Builder_ == null) {\n"
398       "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
399       "        $type$, $type$.Builder, $type$OrBuilder>(\n"
400       "            get$capitalized_name$(),\n"
401       "            getParentForChildren(),\n"
402       "            isClean());\n"
403       "    $name$_ = null;\n"
404       "  }\n"
405       "  return $name$Builder_;\n"
406       "}\n");
407 }
408 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const409 void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode(
410     io::Printer* printer) const {
411   if (HasHasbit(descriptor_)) {
412     printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
413   }
414 }
415 
GenerateInitializationCode(io::Printer * printer) const416 void ImmutableMessageFieldGenerator::GenerateInitializationCode(
417     io::Printer* printer) const {}
418 
GenerateBuilderClearCode(io::Printer * printer) const419 void ImmutableMessageFieldGenerator::GenerateBuilderClearCode(
420     io::Printer* printer) const {
421   if (HasHasbit(descriptor_)) {
422     PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
423 
424                                 "$name$Builder_.clear();\n");
425     printer->Print(variables_, "$clear_has_field_bit_builder$\n");
426   } else {
427     PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
428 
429                                 "$name$_ = null;\n"
430                                 "$name$Builder_ = null;\n");
431   }
432 }
433 
GenerateMergingCode(io::Printer * printer) const434 void ImmutableMessageFieldGenerator::GenerateMergingCode(
435     io::Printer* printer) const {
436   printer->Print(variables_,
437                  "if (other.has$capitalized_name$()) {\n"
438                  "  merge$capitalized_name$(other.get$capitalized_name$());\n"
439                  "}\n");
440 }
441 
GenerateBuildingCode(io::Printer * printer) const442 void ImmutableMessageFieldGenerator::GenerateBuildingCode(
443     io::Printer* printer) const {
444   if (HasHasbit(descriptor_)) {
445     printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
446     printer->Indent();
447     PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
448                                 "result.$name$_ = $name$Builder_.build();\n");
449     printer->Outdent();
450     printer->Print(variables_,
451                    "  $set_has_field_bit_to_local$;\n"
452                    "}\n");
453   } else {
454     PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
455                                 "result.$name$_ = $name$Builder_.build();\n");
456   }
457 }
458 
GenerateParsingCode(io::Printer * printer) const459 void ImmutableMessageFieldGenerator::GenerateParsingCode(
460     io::Printer* printer) const {
461   printer->Print(variables_,
462                  "$type$.Builder subBuilder = null;\n"
463                  "if ($is_field_present_message$) {\n"
464                  "  subBuilder = $name$_.toBuilder();\n"
465                  "}\n");
466 
467   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
468     printer->Print(variables_,
469                    "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
470                    "    extensionRegistry);\n");
471   } else {
472     printer->Print(variables_,
473                    "$name$_ = input.readMessage($type$.$get_parser$, "
474                    "extensionRegistry);\n");
475   }
476 
477   printer->Print(variables_,
478                  "if (subBuilder != null) {\n"
479                  "  subBuilder.mergeFrom($name$_);\n"
480                  "  $name$_ = subBuilder.buildPartial();\n"
481                  "}\n"
482                  "$set_has_field_bit_message$\n");
483 }
484 
GenerateParsingDoneCode(io::Printer * printer) const485 void ImmutableMessageFieldGenerator::GenerateParsingDoneCode(
486     io::Printer* printer) const {
487   // noop for messages.
488 }
489 
GenerateSerializationCode(io::Printer * printer) const490 void ImmutableMessageFieldGenerator::GenerateSerializationCode(
491     io::Printer* printer) const {
492   printer->Print(
493       variables_,
494       "if ($is_field_present_message$) {\n"
495       "  output.write$group_or_message$($number$, get$capitalized_name$());\n"
496       "}\n");
497 }
498 
GenerateSerializedSizeCode(io::Printer * printer) const499 void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
500     io::Printer* printer) const {
501   printer->Print(
502       variables_,
503       "if ($is_field_present_message$) {\n"
504       "  size += com.google.protobuf.CodedOutputStream\n"
505       "    .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
506       "}\n");
507 }
508 
GenerateEqualsCode(io::Printer * printer) const509 void ImmutableMessageFieldGenerator::GenerateEqualsCode(
510     io::Printer* printer) const {
511   printer->Print(variables_,
512                  "if (!get$capitalized_name$()\n"
513                  "    .equals(other.get$capitalized_name$())) return false;\n");
514 }
515 
GenerateHashCode(io::Printer * printer) const516 void ImmutableMessageFieldGenerator::GenerateHashCode(
517     io::Printer* printer) const {
518   printer->Print(variables_,
519                  "hash = (37 * hash) + $constant_name$;\n"
520                  "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
521 }
522 
GetBoxedType() const523 std::string ImmutableMessageFieldGenerator::GetBoxedType() const {
524   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
525 }
526 
527 // ===================================================================
528 
ImmutableMessageOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)529 ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator(
530     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
531     Context* context)
532     : ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
533                                      builderBitIndex, context) {
534   const OneofGeneratorInfo* info =
535       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
536   SetCommonOneofVariables(descriptor, info, &variables_);
537 }
538 
~ImmutableMessageOneofFieldGenerator()539 ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() {}
540 
GenerateMembers(io::Printer * printer) const541 void ImmutableMessageOneofFieldGenerator::GenerateMembers(
542     io::Printer* printer) const {
543   PrintExtraFieldInfo(variables_, printer);
544   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
545   printer->Print(variables_,
546                  "@java.lang.Override\n"
547                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
548                  "  return $has_oneof_case_message$;\n"
549                  "}\n");
550   printer->Annotate("{", "}", descriptor_);
551   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
552   printer->Print(variables_,
553                  "@java.lang.Override\n"
554                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
555                  "  if ($has_oneof_case_message$) {\n"
556                  "     return ($type$) $oneof_name$_;\n"
557                  "  }\n"
558                  "  return $type$.getDefaultInstance();\n"
559                  "}\n");
560   printer->Annotate("{", "}", descriptor_);
561 
562   WriteFieldDocComment(printer, descriptor_);
563   printer->Print(variables_,
564                  "@java.lang.Override\n"
565                  "$deprecation$public $type$OrBuilder "
566                  "${$get$capitalized_name$OrBuilder$}$() {\n"
567                  "  if ($has_oneof_case_message$) {\n"
568                  "     return ($type$) $oneof_name$_;\n"
569                  "  }\n"
570                  "  return $type$.getDefaultInstance();\n"
571                  "}\n");
572   printer->Annotate("{", "}", descriptor_);
573 }
574 
GenerateBuilderMembers(io::Printer * printer) const575 void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers(
576     io::Printer* printer) const {
577   // When using nested-builders, the code initially works just like the
578   // non-nested builder case. It only creates a nested builder lazily on
579   // demand and then forever delegates to it after creation.
580   printer->Print(variables_,
581                  // If this builder is non-null, it is used and the other fields
582                  // are ignored.
583                  "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
584                  "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
585                  "\n");
586 
587   // The comments above the methods below are based on a hypothetical
588   // field of type "Field" called "Field".
589 
590   // boolean hasField()
591   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
592   printer->Print(variables_,
593                  "@java.lang.Override\n"
594                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
595                  "  return $has_oneof_case_message$;\n"
596                  "}\n");
597   printer->Annotate("{", "}", descriptor_);
598 
599   // Field getField()
600   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
601   PrintNestedBuilderFunction(
602       printer,
603       "@java.lang.Override\n"
604       "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
605 
606       "if ($has_oneof_case_message$) {\n"
607       "  return ($type$) $oneof_name$_;\n"
608       "}\n"
609       "return $type$.getDefaultInstance();\n",
610 
611       "if ($has_oneof_case_message$) {\n"
612       "  return $name$Builder_.getMessage();\n"
613       "}\n"
614       "return $type$.getDefaultInstance();\n",
615 
616       NULL);
617 
618   // Field.Builder setField(Field value)
619   WriteFieldDocComment(printer, descriptor_);
620   PrintNestedBuilderFunction(
621       printer,
622       "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
623 
624       "if (value == null) {\n"
625       "  throw new NullPointerException();\n"
626       "}\n"
627       "$oneof_name$_ = value;\n"
628       "$on_changed$\n",
629 
630       "$name$Builder_.setMessage(value);\n",
631 
632       "$set_oneof_case_message$;\n"
633       "return this;\n");
634 
635   // Field.Builder setField(Field.Builder builderForValue)
636   WriteFieldDocComment(printer, descriptor_);
637   PrintNestedBuilderFunction(
638       printer,
639       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
640       "    $type$.Builder builderForValue)",
641 
642       "$oneof_name$_ = builderForValue.build();\n"
643       "$on_changed$\n",
644 
645       "$name$Builder_.setMessage(builderForValue.build());\n",
646 
647       "$set_oneof_case_message$;\n"
648       "return this;\n");
649 
650   // Field.Builder mergeField(Field value)
651   WriteFieldDocComment(printer, descriptor_);
652   PrintNestedBuilderFunction(
653       printer,
654       "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
655 
656       "if ($has_oneof_case_message$ &&\n"
657       "    $oneof_name$_ != $type$.getDefaultInstance()) {\n"
658       "  $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
659       "      .mergeFrom(value).buildPartial();\n"
660       "} else {\n"
661       "  $oneof_name$_ = value;\n"
662       "}\n"
663       "$on_changed$\n",
664 
665       "if ($has_oneof_case_message$) {\n"
666       "  $name$Builder_.mergeFrom(value);\n"
667       "}\n"
668       "$name$Builder_.setMessage(value);\n",
669 
670       "$set_oneof_case_message$;\n"
671       "return this;\n");
672 
673   // Field.Builder clearField()
674   WriteFieldDocComment(printer, descriptor_);
675   PrintNestedBuilderFunction(
676       printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
677 
678       "if ($has_oneof_case_message$) {\n"
679       "  $clear_oneof_case_message$;\n"
680       "  $oneof_name$_ = null;\n"
681       "  $on_changed$\n"
682       "}\n",
683 
684       "if ($has_oneof_case_message$) {\n"
685       "  $clear_oneof_case_message$;\n"
686       "  $oneof_name$_ = null;\n"
687       "}\n"
688       "$name$Builder_.clear();\n",
689 
690       "return this;\n");
691 
692   WriteFieldDocComment(printer, descriptor_);
693   printer->Print(variables_,
694                  "$deprecation$public $type$.Builder "
695                  "${$get$capitalized_name$Builder$}$() {\n"
696                  "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
697                  "}\n");
698   printer->Annotate("{", "}", descriptor_);
699   WriteFieldDocComment(printer, descriptor_);
700   printer->Print(
701       variables_,
702       "@java.lang.Override\n"
703       "$deprecation$public $type$OrBuilder "
704       "${$get$capitalized_name$OrBuilder$}$() {\n"
705       "  if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
706       "    return $name$Builder_.getMessageOrBuilder();\n"
707       "  } else {\n"
708       "    if ($has_oneof_case_message$) {\n"
709       "      return ($type$) $oneof_name$_;\n"
710       "    }\n"
711       "    return $type$.getDefaultInstance();\n"
712       "  }\n"
713       "}\n");
714   printer->Annotate("{", "}", descriptor_);
715   WriteFieldDocComment(printer, descriptor_);
716   printer->Print(
717       variables_,
718       "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
719       "    $type$, $type$.Builder, $type$OrBuilder> \n"
720       "    ${$get$capitalized_name$FieldBuilder$}$() {\n"
721       "  if ($name$Builder_ == null) {\n"
722       "    if (!($has_oneof_case_message$)) {\n"
723       "      $oneof_name$_ = $type$.getDefaultInstance();\n"
724       "    }\n"
725       "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
726       "        $type$, $type$.Builder, $type$OrBuilder>(\n"
727       "            ($type$) $oneof_name$_,\n"
728       "            getParentForChildren(),\n"
729       "            isClean());\n"
730       "    $oneof_name$_ = null;\n"
731       "  }\n"
732       "  $set_oneof_case_message$;\n"
733       "  $on_changed$;\n"
734       "  return $name$Builder_;\n"
735       "}\n");
736   printer->Annotate("{", "}", descriptor_);
737 }
738 
GenerateBuildingCode(io::Printer * printer) const739 void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode(
740     io::Printer* printer) const {
741   printer->Print(variables_, "if ($has_oneof_case_message$) {\n");
742   printer->Indent();
743 
744   PrintNestedBuilderCondition(
745       printer, "result.$oneof_name$_ = $oneof_name$_;\n",
746 
747       "result.$oneof_name$_ = $name$Builder_.build();\n");
748 
749   printer->Outdent();
750   printer->Print("}\n");
751 }
752 
GenerateMergingCode(io::Printer * printer) const753 void ImmutableMessageOneofFieldGenerator::GenerateMergingCode(
754     io::Printer* printer) const {
755   printer->Print(variables_,
756                  "merge$capitalized_name$(other.get$capitalized_name$());\n");
757 }
758 
GenerateParsingCode(io::Printer * printer) const759 void ImmutableMessageOneofFieldGenerator::GenerateParsingCode(
760     io::Printer* printer) const {
761   printer->Print(variables_,
762                  "$type$.Builder subBuilder = null;\n"
763                  "if ($has_oneof_case_message$) {\n"
764                  "  subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
765                  "}\n");
766 
767   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
768     printer->Print(
769         variables_,
770         "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
771         "    extensionRegistry);\n");
772   } else {
773     printer->Print(
774         variables_,
775         "$oneof_name$_ =\n"
776         "    input.readMessage($type$.$get_parser$, extensionRegistry);\n");
777   }
778 
779   printer->Print(variables_,
780                  "if (subBuilder != null) {\n"
781                  "  subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
782                  "  $oneof_name$_ = subBuilder.buildPartial();\n"
783                  "}\n");
784   printer->Print(variables_, "$set_oneof_case_message$;\n");
785 }
786 
GenerateSerializationCode(io::Printer * printer) const787 void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode(
788     io::Printer* printer) const {
789   printer->Print(
790       variables_,
791       "if ($has_oneof_case_message$) {\n"
792       "  output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
793       "}\n");
794 }
795 
GenerateSerializedSizeCode(io::Printer * printer) const796 void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
797     io::Printer* printer) const {
798   printer->Print(
799       variables_,
800       "if ($has_oneof_case_message$) {\n"
801       "  size += com.google.protobuf.CodedOutputStream\n"
802       "    .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
803       "}\n");
804 }
805 
806 // ===================================================================
807 
RepeatedImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)808 RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator(
809     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
810     Context* context)
811     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
812   SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
813                       context->GetFieldGeneratorInfo(descriptor),
814                       name_resolver_, &variables_);
815 }
816 
817 RepeatedImmutableMessageFieldGenerator::
~RepeatedImmutableMessageFieldGenerator()818     ~RepeatedImmutableMessageFieldGenerator() {}
819 
GetNumBitsForMessage() const820 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
821   return 0;
822 }
823 
GetNumBitsForBuilder() const824 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
825   return 1;
826 }
827 
GenerateInterfaceMembers(io::Printer * printer) const828 void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
829     io::Printer* printer) const {
830   // TODO(jonp): In the future, consider having methods specific to the
831   // interface so that builders can choose dynamically to either return a
832   // message or a nested builder, so that asking for the interface doesn't
833   // cause a message to ever be built.
834   WriteFieldDocComment(printer, descriptor_);
835   printer->Print(variables_,
836                  "$deprecation$java.util.List<$type$> \n"
837                  "    get$capitalized_name$List();\n");
838   WriteFieldDocComment(printer, descriptor_);
839   printer->Print(variables_,
840                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
841   WriteFieldDocComment(printer, descriptor_);
842   printer->Print(variables_,
843                  "$deprecation$int get$capitalized_name$Count();\n");
844 
845   WriteFieldDocComment(printer, descriptor_);
846   printer->Print(variables_,
847                  "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
848                  "    get$capitalized_name$OrBuilderList();\n");
849   WriteFieldDocComment(printer, descriptor_);
850   printer->Print(
851       variables_,
852       "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
853       "    int index);\n");
854 }
855 
GenerateMembers(io::Printer * printer) const856 void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
857     io::Printer* printer) const {
858   printer->Print(variables_, "private java.util.List<$type$> $name$_;\n");
859   PrintExtraFieldInfo(variables_, printer);
860   WriteFieldDocComment(printer, descriptor_);
861   printer->Print(variables_,
862                  "@java.lang.Override\n"
863                  "$deprecation$public java.util.List<$type$> "
864                  "${$get$capitalized_name$List$}$() {\n"
865                  "  return $name$_;\n"  // note:  unmodifiable list
866                  "}\n");
867   printer->Annotate("{", "}", descriptor_);
868   WriteFieldDocComment(printer, descriptor_);
869   printer->Print(
870       variables_,
871       "@java.lang.Override\n"
872       "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
873       "    ${$get$capitalized_name$OrBuilderList$}$() {\n"
874       "  return $name$_;\n"
875       "}\n");
876   printer->Annotate("{", "}", descriptor_);
877   WriteFieldDocComment(printer, descriptor_);
878   printer->Print(
879       variables_,
880       "@java.lang.Override\n"
881       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
882       "  return $name$_.size();\n"
883       "}\n");
884   printer->Annotate("{", "}", descriptor_);
885   WriteFieldDocComment(printer, descriptor_);
886   printer->Print(
887       variables_,
888       "@java.lang.Override\n"
889       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
890       "  return $name$_.get(index);\n"
891       "}\n");
892   printer->Annotate("{", "}", descriptor_);
893   WriteFieldDocComment(printer, descriptor_);
894   printer->Print(variables_,
895                  "@java.lang.Override\n"
896                  "$deprecation$public $type$OrBuilder "
897                  "${$get$capitalized_name$OrBuilder$}$(\n"
898                  "    int index) {\n"
899                  "  return $name$_.get(index);\n"
900                  "}\n");
901   printer->Annotate("{", "}", descriptor_);
902 }
903 
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const904 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
905     io::Printer* printer, const char* regular_case,
906     const char* nested_builder_case) const {
907   printer->Print(variables_, "if ($name$Builder_ == null) {\n");
908   printer->Indent();
909   printer->Print(variables_, regular_case);
910   printer->Outdent();
911   printer->Print("} else {\n");
912   printer->Indent();
913   printer->Print(variables_, nested_builder_case);
914   printer->Outdent();
915   printer->Print("}\n");
916 }
917 
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const918 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
919     io::Printer* printer, const char* method_prototype,
920     const char* regular_case, const char* nested_builder_case,
921     const char* trailing_code) const {
922   printer->Print(variables_, method_prototype);
923   printer->Annotate("{", "}", descriptor_);
924   printer->Print(" {\n");
925   printer->Indent();
926   PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
927   if (trailing_code != NULL) {
928     printer->Print(variables_, trailing_code);
929   }
930   printer->Outdent();
931   printer->Print("}\n");
932 }
933 
GenerateBuilderMembers(io::Printer * printer) const934 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
935     io::Printer* printer) const {
936   // When using nested-builders, the code initially works just like the
937   // non-nested builder case. It only creates a nested builder lazily on
938   // demand and then forever delegates to it after creation.
939 
940   printer->Print(
941       variables_,
942       // Used when the builder is null.
943       // One field is the list and the other field keeps track of whether the
944       // list is immutable. If it's immutable, the invariant is that it must
945       // either an instance of Collections.emptyList() or it's an ArrayList
946       // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
947       // a refererence to the underlying ArrayList. This invariant allows us to
948       // share instances of lists between protocol buffers avoiding expensive
949       // memory allocations. Note, immutable is a strong guarantee here -- not
950       // just that the list cannot be modified via the reference but that the
951       // list can never be modified.
952       "private java.util.List<$type$> $name$_ =\n"
953       "  java.util.Collections.emptyList();\n"
954 
955       "private void ensure$capitalized_name$IsMutable() {\n"
956       "  if (!$get_mutable_bit_builder$) {\n"
957       "    $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
958       "    $set_mutable_bit_builder$;\n"
959       "   }\n"
960       "}\n"
961       "\n");
962 
963   printer->Print(
964       variables_,
965       // If this builder is non-null, it is used and the other fields are
966       // ignored.
967       "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
968       "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
969       "\n");
970 
971   // The comments above the methods below are based on a hypothetical
972   // repeated field of type "Field" called "RepeatedField".
973 
974   // List<Field> getRepeatedFieldList()
975   WriteFieldDocComment(printer, descriptor_);
976   PrintNestedBuilderFunction(
977       printer,
978       "$deprecation$public java.util.List<$type$> "
979       "${$get$capitalized_name$List$}$()",
980 
981       "return java.util.Collections.unmodifiableList($name$_);\n",
982       "return $name$Builder_.getMessageList();\n",
983 
984       NULL);
985 
986   // int getRepeatedFieldCount()
987   WriteFieldDocComment(printer, descriptor_);
988   PrintNestedBuilderFunction(
989       printer, "$deprecation$public int ${$get$capitalized_name$Count$}$()",
990 
991       "return $name$_.size();\n", "return $name$Builder_.getCount();\n",
992 
993       NULL);
994 
995   // Field getRepeatedField(int index)
996   WriteFieldDocComment(printer, descriptor_);
997   PrintNestedBuilderFunction(
998       printer,
999       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)",
1000 
1001       "return $name$_.get(index);\n",
1002 
1003       "return $name$Builder_.getMessage(index);\n",
1004 
1005       NULL);
1006 
1007   // Builder setRepeatedField(int index, Field value)
1008   WriteFieldDocComment(printer, descriptor_);
1009   PrintNestedBuilderFunction(
1010       printer,
1011       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1012       "    int index, $type$ value)",
1013       "if (value == null) {\n"
1014       "  throw new NullPointerException();\n"
1015       "}\n"
1016       "ensure$capitalized_name$IsMutable();\n"
1017       "$name$_.set(index, value);\n"
1018       "$on_changed$\n",
1019       "$name$Builder_.setMessage(index, value);\n", "return this;\n");
1020 
1021   // Builder setRepeatedField(int index, Field.Builder builderForValue)
1022   WriteFieldDocComment(printer, descriptor_);
1023   PrintNestedBuilderFunction(
1024       printer,
1025       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1026       "    int index, $type$.Builder builderForValue)",
1027 
1028       "ensure$capitalized_name$IsMutable();\n"
1029       "$name$_.set(index, builderForValue.build());\n"
1030       "$on_changed$\n",
1031 
1032       "$name$Builder_.setMessage(index, builderForValue.build());\n",
1033 
1034       "return this;\n");
1035 
1036   // Builder addRepeatedField(Field value)
1037   WriteFieldDocComment(printer, descriptor_);
1038   PrintNestedBuilderFunction(
1039       printer,
1040       "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)",
1041 
1042       "if (value == null) {\n"
1043       "  throw new NullPointerException();\n"
1044       "}\n"
1045       "ensure$capitalized_name$IsMutable();\n"
1046       "$name$_.add(value);\n"
1047 
1048       "$on_changed$\n",
1049 
1050       "$name$Builder_.addMessage(value);\n",
1051 
1052       "return this;\n");
1053 
1054   // Builder addRepeatedField(int index, Field value)
1055   WriteFieldDocComment(printer, descriptor_);
1056   PrintNestedBuilderFunction(
1057       printer,
1058       "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1059       "    int index, $type$ value)",
1060 
1061       "if (value == null) {\n"
1062       "  throw new NullPointerException();\n"
1063       "}\n"
1064       "ensure$capitalized_name$IsMutable();\n"
1065       "$name$_.add(index, value);\n"
1066       "$on_changed$\n",
1067 
1068       "$name$Builder_.addMessage(index, value);\n",
1069 
1070       "return this;\n");
1071 
1072   // Builder addRepeatedField(Field.Builder builderForValue)
1073   WriteFieldDocComment(printer, descriptor_);
1074   PrintNestedBuilderFunction(
1075       printer,
1076       "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1077       "    $type$.Builder builderForValue)",
1078 
1079       "ensure$capitalized_name$IsMutable();\n"
1080       "$name$_.add(builderForValue.build());\n"
1081       "$on_changed$\n",
1082 
1083       "$name$Builder_.addMessage(builderForValue.build());\n",
1084 
1085       "return this;\n");
1086 
1087   // Builder addRepeatedField(int index, Field.Builder builderForValue)
1088   WriteFieldDocComment(printer, descriptor_);
1089   PrintNestedBuilderFunction(
1090       printer,
1091       "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1092       "    int index, $type$.Builder builderForValue)",
1093 
1094       "ensure$capitalized_name$IsMutable();\n"
1095       "$name$_.add(index, builderForValue.build());\n"
1096       "$on_changed$\n",
1097 
1098       "$name$Builder_.addMessage(index, builderForValue.build());\n",
1099 
1100       "return this;\n");
1101 
1102   // Builder addAllRepeatedField(Iterable<Field> values)
1103   WriteFieldDocComment(printer, descriptor_);
1104   PrintNestedBuilderFunction(
1105       printer,
1106       "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
1107       "    java.lang.Iterable<? extends $type$> values)",
1108 
1109       "ensure$capitalized_name$IsMutable();\n"
1110       "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
1111       "    values, $name$_);\n"
1112       "$on_changed$\n",
1113 
1114       "$name$Builder_.addAllMessages(values);\n",
1115 
1116       "return this;\n");
1117 
1118   // Builder clearAllRepeatedField()
1119   WriteFieldDocComment(printer, descriptor_);
1120   PrintNestedBuilderFunction(
1121       printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
1122 
1123       "$name$_ = java.util.Collections.emptyList();\n"
1124       "$clear_mutable_bit_builder$;\n"
1125       "$on_changed$\n",
1126 
1127       "$name$Builder_.clear();\n",
1128 
1129       "return this;\n");
1130 
1131   // Builder removeRepeatedField(int index)
1132   WriteFieldDocComment(printer, descriptor_);
1133   PrintNestedBuilderFunction(
1134       printer,
1135       "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
1136 
1137       "ensure$capitalized_name$IsMutable();\n"
1138       "$name$_.remove(index);\n"
1139       "$on_changed$\n",
1140 
1141       "$name$Builder_.remove(index);\n",
1142 
1143       "return this;\n");
1144 
1145   WriteFieldDocComment(printer, descriptor_);
1146   printer->Print(
1147       variables_,
1148       "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n"
1149       "    int index) {\n"
1150       "  return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
1151       "}\n");
1152   printer->Annotate("{", "}", descriptor_);
1153 
1154   WriteFieldDocComment(printer, descriptor_);
1155   printer->Print(variables_,
1156                  "$deprecation$public $type$OrBuilder "
1157                  "${$get$capitalized_name$OrBuilder$}$(\n"
1158                  "    int index) {\n"
1159                  "  if ($name$Builder_ == null) {\n"
1160                  "    return $name$_.get(index);"
1161                  "  } else {\n"
1162                  "    return $name$Builder_.getMessageOrBuilder(index);\n"
1163                  "  }\n"
1164                  "}\n");
1165   printer->Annotate("{", "}", descriptor_);
1166 
1167   WriteFieldDocComment(printer, descriptor_);
1168   printer->Print(
1169       variables_,
1170       "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
1171       "     ${$get$capitalized_name$OrBuilderList$}$() {\n"
1172       "  if ($name$Builder_ != null) {\n"
1173       "    return $name$Builder_.getMessageOrBuilderList();\n"
1174       "  } else {\n"
1175       "    return java.util.Collections.unmodifiableList($name$_);\n"
1176       "  }\n"
1177       "}\n");
1178   printer->Annotate("{", "}", descriptor_);
1179 
1180   WriteFieldDocComment(printer, descriptor_);
1181   printer->Print(variables_,
1182                  "$deprecation$public $type$.Builder "
1183                  "${$add$capitalized_name$Builder$}$() {\n"
1184                  "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
1185                  "      $type$.getDefaultInstance());\n"
1186                  "}\n");
1187   printer->Annotate("{", "}", descriptor_);
1188   WriteFieldDocComment(printer, descriptor_);
1189   printer->Print(
1190       variables_,
1191       "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
1192       "    int index) {\n"
1193       "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
1194       "      index, $type$.getDefaultInstance());\n"
1195       "}\n");
1196   printer->Annotate("{", "}", descriptor_);
1197   WriteFieldDocComment(printer, descriptor_);
1198   printer->Print(
1199       variables_,
1200       "$deprecation$public java.util.List<$type$.Builder> \n"
1201       "     ${$get$capitalized_name$BuilderList$}$() {\n"
1202       "  return get$capitalized_name$FieldBuilder().getBuilderList();\n"
1203       "}\n"
1204       "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1205       "    $type$, $type$.Builder, $type$OrBuilder> \n"
1206       "    get$capitalized_name$FieldBuilder() {\n"
1207       "  if ($name$Builder_ == null) {\n"
1208       "    $name$Builder_ = new "
1209       "com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1210       "        $type$, $type$.Builder, $type$OrBuilder>(\n"
1211       "            $name$_,\n"
1212       "            $get_mutable_bit_builder$,\n"
1213       "            getParentForChildren(),\n"
1214       "            isClean());\n"
1215       "    $name$_ = null;\n"
1216       "  }\n"
1217       "  return $name$Builder_;\n"
1218       "}\n");
1219   printer->Annotate("{", "}", descriptor_);
1220 }
1221 
1222 void RepeatedImmutableMessageFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const1223     GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
1224   printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
1225 }
1226 
GenerateInitializationCode(io::Printer * printer) const1227 void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
1228     io::Printer* printer) const {
1229   printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
1230 }
1231 
GenerateBuilderClearCode(io::Printer * printer) const1232 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
1233     io::Printer* printer) const {
1234   PrintNestedBuilderCondition(printer,
1235                               "$name$_ = java.util.Collections.emptyList();\n"
1236                               "$clear_mutable_bit_builder$;\n",
1237 
1238                               "$name$Builder_.clear();\n");
1239 }
1240 
GenerateMergingCode(io::Printer * printer) const1241 void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
1242     io::Printer* printer) const {
1243   // The code below does two optimizations (non-nested builder case):
1244   //   1. If the other list is empty, there's nothing to do. This ensures we
1245   //      don't allocate a new array if we already have an immutable one.
1246   //   2. If the other list is non-empty and our current list is empty, we can
1247   //      reuse the other list which is guaranteed to be immutable.
1248   PrintNestedBuilderCondition(
1249       printer,
1250       "if (!other.$name$_.isEmpty()) {\n"
1251       "  if ($name$_.isEmpty()) {\n"
1252       "    $name$_ = other.$name$_;\n"
1253       "    $clear_mutable_bit_builder$;\n"
1254       "  } else {\n"
1255       "    ensure$capitalized_name$IsMutable();\n"
1256       "    $name$_.addAll(other.$name$_);\n"
1257       "  }\n"
1258       "  $on_changed$\n"
1259       "}\n",
1260 
1261       "if (!other.$name$_.isEmpty()) {\n"
1262       "  if ($name$Builder_.isEmpty()) {\n"
1263       "    $name$Builder_.dispose();\n"
1264       "    $name$Builder_ = null;\n"
1265       "    $name$_ = other.$name$_;\n"
1266       "    $clear_mutable_bit_builder$;\n"
1267       "    $name$Builder_ = \n"
1268       "      com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders "
1269       "?\n"
1270       "         get$capitalized_name$FieldBuilder() : null;\n"
1271       "  } else {\n"
1272       "    $name$Builder_.addAllMessages(other.$name$_);\n"
1273       "  }\n"
1274       "}\n");
1275 }
1276 
GenerateBuildingCode(io::Printer * printer) const1277 void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode(
1278     io::Printer* printer) const {
1279   // The code below (non-nested builder case) ensures that the result has an
1280   // immutable list. If our list is immutable, we can just reuse it. If not,
1281   // we make it immutable.
1282   PrintNestedBuilderCondition(
1283       printer,
1284       "if ($get_mutable_bit_builder$) {\n"
1285       "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1286       "  $clear_mutable_bit_builder$;\n"
1287       "}\n"
1288       "result.$name$_ = $name$_;\n",
1289 
1290       "result.$name$_ = $name$Builder_.build();\n");
1291 }
1292 
GenerateParsingCode(io::Printer * printer) const1293 void RepeatedImmutableMessageFieldGenerator::GenerateParsingCode(
1294     io::Printer* printer) const {
1295   printer->Print(variables_,
1296                  "if (!$get_mutable_bit_parser$) {\n"
1297                  "  $name$_ = new java.util.ArrayList<$type$>();\n"
1298                  "  $set_mutable_bit_parser$;\n"
1299                  "}\n");
1300 
1301   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
1302     printer->Print(
1303         variables_,
1304         "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n"
1305         "    extensionRegistry));\n");
1306   } else {
1307     printer->Print(
1308         variables_,
1309         "$name$_.add(\n"
1310         "    input.readMessage($type$.$get_parser$, extensionRegistry));\n");
1311   }
1312 }
1313 
GenerateParsingDoneCode(io::Printer * printer) const1314 void RepeatedImmutableMessageFieldGenerator::GenerateParsingDoneCode(
1315     io::Printer* printer) const {
1316   printer->Print(
1317       variables_,
1318       "if ($get_mutable_bit_parser$) {\n"
1319       "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1320       "}\n");
1321 }
1322 
GenerateSerializationCode(io::Printer * printer) const1323 void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
1324     io::Printer* printer) const {
1325   printer->Print(variables_,
1326                  "for (int i = 0; i < $name$_.size(); i++) {\n"
1327                  "  output.write$group_or_message$($number$, $name$_.get(i));\n"
1328                  "}\n");
1329 }
1330 
GenerateSerializedSizeCode(io::Printer * printer) const1331 void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
1332     io::Printer* printer) const {
1333   printer->Print(
1334       variables_,
1335       "for (int i = 0; i < $name$_.size(); i++) {\n"
1336       "  size += com.google.protobuf.CodedOutputStream\n"
1337       "    .compute$group_or_message$Size($number$, $name$_.get(i));\n"
1338       "}\n");
1339 }
1340 
GenerateEqualsCode(io::Printer * printer) const1341 void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode(
1342     io::Printer* printer) const {
1343   printer->Print(
1344       variables_,
1345       "if (!get$capitalized_name$List()\n"
1346       "    .equals(other.get$capitalized_name$List())) return false;\n");
1347 }
1348 
GenerateHashCode(io::Printer * printer) const1349 void RepeatedImmutableMessageFieldGenerator::GenerateHashCode(
1350     io::Printer* printer) const {
1351   printer->Print(
1352       variables_,
1353       "if (get$capitalized_name$Count() > 0) {\n"
1354       "  hash = (37 * hash) + $constant_name$;\n"
1355       "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
1356       "}\n");
1357 }
1358 
GetBoxedType() const1359 std::string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
1360   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
1361 }
1362 
1363 }  // namespace java
1364 }  // namespace compiler
1365 }  // namespace protobuf
1366 }  // namespace google
1367