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