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