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