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