• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <map>
36 #include <string>
37 
38 #include <google/protobuf/compiler/java/java_context.h>
39 #include <google/protobuf/compiler/java/java_doc_comment.h>
40 #include <google/protobuf/compiler/java/java_helpers.h>
41 #include <google/protobuf/compiler/java/java_message_field.h>
42 #include <google/protobuf/compiler/java/java_name_resolver.h>
43 #include <google/protobuf/io/printer.h>
44 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/stubs/strutil.h>
46 
47 namespace google {
48 namespace protobuf {
49 namespace compiler {
50 namespace java {
51 
52 namespace {
53 
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)54 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
55                          int builderBitIndex, const FieldGeneratorInfo* info,
56                          ClassNameResolver* name_resolver,
57                          std::map<std::string, std::string>* variables) {
58   SetCommonFieldVariables(descriptor, info, variables);
59 
60   (*variables)["type"] =
61       name_resolver->GetImmutableClassName(descriptor->message_type());
62   (*variables)["mutable_type"] =
63       name_resolver->GetMutableClassName(descriptor->message_type());
64   (*variables)["group_or_message"] =
65       (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
66                                                            : "Message";
67   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
68   // by the proto compiler
69   (*variables)["deprecation"] =
70       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
71   (*variables)["on_changed"] = "onChanged();";
72   (*variables)["ver"] = GeneratedCodeVersionSuffix();
73   (*variables)["get_parser"] =
74       ExposePublicParser(descriptor->message_type()->file()) ? "PARSER"
75                                                              : "parser()";
76 
77   if (HasHasbit(descriptor)) {
78     // For singular messages and builders, one bit is used for the hasField bit.
79     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
80     (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
81 
82     // Note that these have a trailing ";".
83     (*variables)["set_has_field_bit_message"] =
84         GenerateSetBit(messageBitIndex) + ";";
85     (*variables)["set_has_field_bit_builder"] =
86         GenerateSetBit(builderBitIndex) + ";";
87     (*variables)["clear_has_field_bit_builder"] =
88         GenerateClearBit(builderBitIndex) + ";";
89 
90     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
91   } else {
92     (*variables)["set_has_field_bit_message"] = "";
93     (*variables)["set_has_field_bit_builder"] = "";
94     (*variables)["clear_has_field_bit_builder"] = "";
95 
96     (*variables)["is_field_present_message"] =
97         (*variables)["name"] + "_ != null";
98   }
99 
100   // For repeated builders, one bit is used for whether the array is immutable.
101   (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
102   (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
103   (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
104 
105   (*variables)["get_has_field_bit_from_local"] =
106       GenerateGetBitFromLocal(builderBitIndex);
107   (*variables)["set_has_field_bit_to_local"] =
108       GenerateSetBitToLocal(messageBitIndex);
109 }
110 
111 }  // namespace
112 
113 // ===================================================================
114 
ImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)115 ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator(
116     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
117     Context* context)
118     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
119   SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
120                       context->GetFieldGeneratorInfo(descriptor),
121                       name_resolver_, &variables_);
122 }
123 
~ImmutableMessageFieldGenerator()124 ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
125 
GetNumBitsForMessage() const126 int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
127   return HasHasbit(descriptor_) ? 1 : 0;
128 }
129 
GetNumBitsForBuilder() const130 int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
131   return GetNumBitsForMessage();
132 }
133 
GenerateInterfaceMembers(io::Printer * printer) const134 void ImmutableMessageFieldGenerator::GenerateInterfaceMembers(
135     io::Printer* printer) const {
136   // TODO(jonp): In the future, consider having a method specific to the
137   // interface so that builders can choose dynamically to either return a
138   // message or a nested builder, so that asking for the interface doesn't
139   // cause a message to ever be built.
140   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
141   printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
142   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
143   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
144 
145   WriteFieldDocComment(printer, descriptor_);
146   printer->Print(
147       variables_,
148       "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
149 }
150 
GenerateMembers(io::Printer * printer) const151 void ImmutableMessageFieldGenerator::GenerateMembers(
152     io::Printer* printer) const {
153   printer->Print(variables_, "private $type$ $name$_;\n");
154   PrintExtraFieldInfo(variables_, printer);
155 
156   if (HasHasbit(descriptor_)) {
157     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
158     printer->Print(
159         variables_,
160         "@java.lang.Override\n"
161         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
162         "  return $get_has_field_bit_message$;\n"
163         "}\n");
164     printer->Annotate("{", "}", descriptor_);
165     WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
166     printer->Print(
167         variables_,
168         "@java.lang.Override\n"
169         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
170         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
171         "}\n");
172     printer->Annotate("{", "}", descriptor_);
173 
174     WriteFieldDocComment(printer, descriptor_);
175     printer->Print(
176         variables_,
177         "@java.lang.Override\n"
178         "$deprecation$public $type$OrBuilder "
179         "${$get$capitalized_name$OrBuilder$}$() {\n"
180         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\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     WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
193     printer->Print(
194         variables_,
195         "@java.lang.Override\n"
196         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
197         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
198         "}\n");
199     printer->Annotate("{", "}", descriptor_);
200 
201     WriteFieldDocComment(printer, descriptor_);
202     printer->Print(variables_,
203                    "@java.lang.Override\n"
204                    "$deprecation$public $type$OrBuilder "
205                    "${$get$capitalized_name$OrBuilder$}$() {\n"
206                    "  return get$capitalized_name$();\n"
207                    "}\n");
208     printer->Annotate("{", "}", descriptor_);
209   }
210 }
211 
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const212 void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
213     io::Printer* printer, const char* regular_case,
214     const char* nested_builder_case) const {
215   printer->Print(variables_, "if ($name$Builder_ == null) {\n");
216   printer->Indent();
217   printer->Print(variables_, regular_case);
218   printer->Outdent();
219   printer->Print("} else {\n");
220   printer->Indent();
221   printer->Print(variables_, nested_builder_case);
222   printer->Outdent();
223   printer->Print("}\n");
224 }
225 
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const226 void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
227     io::Printer* printer, const char* method_prototype,
228     const char* regular_case, const char* nested_builder_case,
229     const char* trailing_code) const {
230   printer->Print(variables_, method_prototype);
231   printer->Annotate("{", "}", descriptor_);
232   printer->Print(" {\n");
233   printer->Indent();
234   PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
235   if (trailing_code != NULL) {
236     printer->Print(variables_, trailing_code);
237   }
238   printer->Outdent();
239   printer->Print("}\n");
240 }
241 
GenerateBuilderMembers(io::Printer * printer) const242 void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
243     io::Printer* printer) const {
244   // When using nested-builders, the code initially works just like the
245   // non-nested builder case. It only creates a nested builder lazily on
246   // demand and then forever delegates to it after creation.
247 
248   bool has_hasbit = HasHasbit(descriptor_);
249 
250   printer->Print(variables_, "private $type$ $name$_;\n");
251 
252   printer->Print(variables_,
253                  // If this builder is non-null, it is used and the other fields
254                  // are ignored.
255                  "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
256                  "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
257                  "\n");
258 
259   // The comments above the methods below are based on a hypothetical
260   // field of type "Field" called "Field".
261 
262   // boolean hasField()
263   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
264   if (has_hasbit) {
265     printer->Print(
266         variables_,
267         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
268         "  return $get_has_field_bit_builder$;\n"
269         "}\n");
270     printer->Annotate("{", "}", descriptor_);
271   } else {
272     printer->Print(
273         variables_,
274         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
275         "  return $name$Builder_ != null || $name$_ != null;\n"
276         "}\n");
277     printer->Annotate("{", "}", descriptor_);
278   }
279 
280   // Field getField()
281   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
282   PrintNestedBuilderFunction(
283       printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
284       "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
285       "return $name$Builder_.getMessage();\n", NULL);
286 
287   // Field.Builder setField(Field value)
288   WriteFieldDocComment(printer, descriptor_);
289   PrintNestedBuilderFunction(
290       printer,
291       "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
292 
293       "if (value == null) {\n"
294       "  throw new NullPointerException();\n"
295       "}\n"
296       "$name$_ = value;\n"
297       "$on_changed$\n",
298 
299       "$name$Builder_.setMessage(value);\n",
300 
301       "$set_has_field_bit_builder$\n"
302       "return this;\n");
303 
304   // Field.Builder setField(Field.Builder builderForValue)
305   WriteFieldDocComment(printer, descriptor_);
306   PrintNestedBuilderFunction(
307       printer,
308       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
309       "    $type$.Builder builderForValue)",
310 
311       "$name$_ = builderForValue.build();\n"
312       "$on_changed$\n",
313 
314       "$name$Builder_.setMessage(builderForValue.build());\n",
315 
316       "$set_has_field_bit_builder$\n"
317       "return this;\n");
318 
319   // Field.Builder mergeField(Field value)
320   WriteFieldDocComment(printer, descriptor_);
321   PrintNestedBuilderFunction(
322       printer,
323       "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
324 
325       has_hasbit
326           ? "if ($get_has_field_bit_builder$ &&\n"
327             "    $name$_ != null &&\n"
328             "    $name$_ != $type$.getDefaultInstance()) {\n"
329             "  $name$_ =\n"
330             "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
331             "} else {\n"
332             "  $name$_ = value;\n"
333             "}\n"
334             "$on_changed$\n"
335           : "if ($name$_ != null) {\n"
336             "  $name$_ =\n"
337             "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
338             "} else {\n"
339             "  $name$_ = value;\n"
340             "}\n"
341             "$on_changed$\n",
342 
343       "$name$Builder_.mergeFrom(value);\n",
344 
345       "$set_has_field_bit_builder$\n"
346       "return this;\n");
347 
348   // Field.Builder clearField()
349   WriteFieldDocComment(printer, descriptor_);
350   PrintNestedBuilderFunction(
351       printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
352 
353       "$name$_ = null;\n"
354       "$on_changed$\n",
355 
356       has_hasbit ? "$name$Builder_.clear();\n"
357                  : "$name$_ = null;\n"
358                    "$name$Builder_ = null;\n",
359 
360       "$clear_has_field_bit_builder$\n"
361       "return this;\n");
362 
363   WriteFieldDocComment(printer, descriptor_);
364   printer->Print(variables_,
365                  "$deprecation$public $type$.Builder "
366                  "${$get$capitalized_name$Builder$}$() {\n"
367                  "  $set_has_field_bit_builder$\n"
368                  "  $on_changed$\n"
369                  "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
370                  "}\n");
371   printer->Annotate("{", "}", descriptor_);
372   WriteFieldDocComment(printer, descriptor_);
373   printer->Print(variables_,
374                  "$deprecation$public $type$OrBuilder "
375                  "${$get$capitalized_name$OrBuilder$}$() {\n"
376                  "  if ($name$Builder_ != null) {\n"
377                  "    return $name$Builder_.getMessageOrBuilder();\n"
378                  "  } else {\n"
379                  "    return $name$_ == null ?\n"
380                  "        $type$.getDefaultInstance() : $name$_;\n"
381                  "  }\n"
382                  "}\n");
383   printer->Annotate("{", "}", descriptor_);
384   WriteFieldDocComment(printer, descriptor_);
385   printer->Print(
386       variables_,
387       "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
388       "    $type$, $type$.Builder, $type$OrBuilder> \n"
389       "    get$capitalized_name$FieldBuilder() {\n"
390       "  if ($name$Builder_ == null) {\n"
391       "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
392       "        $type$, $type$.Builder, $type$OrBuilder>(\n"
393       "            get$capitalized_name$(),\n"
394       "            getParentForChildren(),\n"
395       "            isClean());\n"
396       "    $name$_ = null;\n"
397       "  }\n"
398       "  return $name$Builder_;\n"
399       "}\n");
400 }
401 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const402 void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode(
403     io::Printer* printer) const {
404   if (HasHasbit(descriptor_)) {
405     printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
406   }
407 }
408 
GenerateInitializationCode(io::Printer * printer) const409 void ImmutableMessageFieldGenerator::GenerateInitializationCode(
410     io::Printer* printer) const {}
411 
GenerateBuilderClearCode(io::Printer * printer) const412 void ImmutableMessageFieldGenerator::GenerateBuilderClearCode(
413     io::Printer* printer) const {
414   if (HasHasbit(descriptor_)) {
415     PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
416 
417                                 "$name$Builder_.clear();\n");
418     printer->Print(variables_, "$clear_has_field_bit_builder$\n");
419   } else {
420     PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
421 
422                                 "$name$_ = null;\n"
423                                 "$name$Builder_ = null;\n");
424   }
425 }
426 
GenerateMergingCode(io::Printer * printer) const427 void ImmutableMessageFieldGenerator::GenerateMergingCode(
428     io::Printer* printer) const {
429   printer->Print(variables_,
430                  "if (other.has$capitalized_name$()) {\n"
431                  "  merge$capitalized_name$(other.get$capitalized_name$());\n"
432                  "}\n");
433 }
434 
GenerateBuildingCode(io::Printer * printer) const435 void ImmutableMessageFieldGenerator::GenerateBuildingCode(
436     io::Printer* printer) const {
437   if (HasHasbit(descriptor_)) {
438     printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
439     printer->Indent();
440     PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
441                                 "result.$name$_ = $name$Builder_.build();\n");
442     printer->Outdent();
443     printer->Print(variables_,
444                    "  $set_has_field_bit_to_local$;\n"
445                    "}\n");
446   } else {
447     PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
448                                 "result.$name$_ = $name$Builder_.build();\n");
449   }
450 }
451 
GenerateBuilderParsingCode(io::Printer * printer) const452 void ImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
453     io::Printer* printer) const {
454   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
455     printer->Print(variables_,
456                    "input.readGroup($number$,\n"
457                    "    get$capitalized_name$FieldBuilder().getBuilder(),\n"
458                    "    extensionRegistry);\n"
459                    "$set_has_field_bit_builder$\n");
460   } else {
461     printer->Print(variables_,
462                    "input.readMessage(\n"
463                    "    get$capitalized_name$FieldBuilder().getBuilder(),\n"
464                    "    extensionRegistry);\n"
465                    "$set_has_field_bit_builder$\n");
466   }
467 }
468 
GenerateSerializationCode(io::Printer * printer) const469 void ImmutableMessageFieldGenerator::GenerateSerializationCode(
470     io::Printer* printer) const {
471   printer->Print(
472       variables_,
473       "if ($is_field_present_message$) {\n"
474       "  output.write$group_or_message$($number$, get$capitalized_name$());\n"
475       "}\n");
476 }
477 
GenerateSerializedSizeCode(io::Printer * printer) const478 void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
479     io::Printer* printer) const {
480   printer->Print(
481       variables_,
482       "if ($is_field_present_message$) {\n"
483       "  size += com.google.protobuf.CodedOutputStream\n"
484       "    .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
485       "}\n");
486 }
487 
GenerateEqualsCode(io::Printer * printer) const488 void ImmutableMessageFieldGenerator::GenerateEqualsCode(
489     io::Printer* printer) const {
490   printer->Print(variables_,
491                  "if (!get$capitalized_name$()\n"
492                  "    .equals(other.get$capitalized_name$())) return false;\n");
493 }
494 
GenerateHashCode(io::Printer * printer) const495 void ImmutableMessageFieldGenerator::GenerateHashCode(
496     io::Printer* printer) const {
497   printer->Print(variables_,
498                  "hash = (37 * hash) + $constant_name$;\n"
499                  "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
500 }
501 
GetBoxedType() const502 std::string ImmutableMessageFieldGenerator::GetBoxedType() const {
503   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
504 }
505 
506 // ===================================================================
507 
ImmutableMessageOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)508 ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator(
509     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
510     Context* context)
511     : ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
512                                      builderBitIndex, context) {
513   const OneofGeneratorInfo* info =
514       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
515   SetCommonOneofVariables(descriptor, info, &variables_);
516 }
517 
~ImmutableMessageOneofFieldGenerator()518 ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() {}
519 
GenerateMembers(io::Printer * printer) const520 void ImmutableMessageOneofFieldGenerator::GenerateMembers(
521     io::Printer* printer) const {
522   PrintExtraFieldInfo(variables_, printer);
523   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
524   printer->Print(variables_,
525                  "@java.lang.Override\n"
526                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
527                  "  return $has_oneof_case_message$;\n"
528                  "}\n");
529   printer->Annotate("{", "}", descriptor_);
530   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
531   printer->Print(variables_,
532                  "@java.lang.Override\n"
533                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
534                  "  if ($has_oneof_case_message$) {\n"
535                  "     return ($type$) $oneof_name$_;\n"
536                  "  }\n"
537                  "  return $type$.getDefaultInstance();\n"
538                  "}\n");
539   printer->Annotate("{", "}", descriptor_);
540 
541   WriteFieldDocComment(printer, descriptor_);
542   printer->Print(variables_,
543                  "@java.lang.Override\n"
544                  "$deprecation$public $type$OrBuilder "
545                  "${$get$capitalized_name$OrBuilder$}$() {\n"
546                  "  if ($has_oneof_case_message$) {\n"
547                  "     return ($type$) $oneof_name$_;\n"
548                  "  }\n"
549                  "  return $type$.getDefaultInstance();\n"
550                  "}\n");
551   printer->Annotate("{", "}", descriptor_);
552 }
553 
GenerateBuilderMembers(io::Printer * printer) const554 void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers(
555     io::Printer* printer) const {
556   // When using nested-builders, the code initially works just like the
557   // non-nested builder case. It only creates a nested builder lazily on
558   // demand and then forever delegates to it after creation.
559   printer->Print(variables_,
560                  // If this builder is non-null, it is used and the other fields
561                  // are ignored.
562                  "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
563                  "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
564                  "\n");
565 
566   // The comments above the methods below are based on a hypothetical
567   // field of type "Field" called "Field".
568 
569   // boolean hasField()
570   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
571   printer->Print(variables_,
572                  "@java.lang.Override\n"
573                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
574                  "  return $has_oneof_case_message$;\n"
575                  "}\n");
576   printer->Annotate("{", "}", descriptor_);
577 
578   // Field getField()
579   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
580   PrintNestedBuilderFunction(
581       printer,
582       "@java.lang.Override\n"
583       "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
584 
585       "if ($has_oneof_case_message$) {\n"
586       "  return ($type$) $oneof_name$_;\n"
587       "}\n"
588       "return $type$.getDefaultInstance();\n",
589 
590       "if ($has_oneof_case_message$) {\n"
591       "  return $name$Builder_.getMessage();\n"
592       "}\n"
593       "return $type$.getDefaultInstance();\n",
594 
595       NULL);
596 
597   // Field.Builder setField(Field value)
598   WriteFieldDocComment(printer, descriptor_);
599   PrintNestedBuilderFunction(
600       printer,
601       "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
602 
603       "if (value == null) {\n"
604       "  throw new NullPointerException();\n"
605       "}\n"
606       "$oneof_name$_ = value;\n"
607       "$on_changed$\n",
608 
609       "$name$Builder_.setMessage(value);\n",
610 
611       "$set_oneof_case_message$;\n"
612       "return this;\n");
613 
614   // Field.Builder setField(Field.Builder builderForValue)
615   WriteFieldDocComment(printer, descriptor_);
616   PrintNestedBuilderFunction(
617       printer,
618       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
619       "    $type$.Builder builderForValue)",
620 
621       "$oneof_name$_ = builderForValue.build();\n"
622       "$on_changed$\n",
623 
624       "$name$Builder_.setMessage(builderForValue.build());\n",
625 
626       "$set_oneof_case_message$;\n"
627       "return this;\n");
628 
629   // Field.Builder mergeField(Field value)
630   WriteFieldDocComment(printer, descriptor_);
631   PrintNestedBuilderFunction(
632       printer,
633       "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
634 
635       "if ($has_oneof_case_message$ &&\n"
636       "    $oneof_name$_ != $type$.getDefaultInstance()) {\n"
637       "  $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
638       "      .mergeFrom(value).buildPartial();\n"
639       "} else {\n"
640       "  $oneof_name$_ = value;\n"
641       "}\n"
642       "$on_changed$\n",
643 
644       "if ($has_oneof_case_message$) {\n"
645       "  $name$Builder_.mergeFrom(value);\n"
646       "}\n"
647       "$name$Builder_.setMessage(value);\n",
648 
649       "$set_oneof_case_message$;\n"
650       "return this;\n");
651 
652   // Field.Builder clearField()
653   WriteFieldDocComment(printer, descriptor_);
654   PrintNestedBuilderFunction(
655       printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
656 
657       "if ($has_oneof_case_message$) {\n"
658       "  $clear_oneof_case_message$;\n"
659       "  $oneof_name$_ = null;\n"
660       "  $on_changed$\n"
661       "}\n",
662 
663       "if ($has_oneof_case_message$) {\n"
664       "  $clear_oneof_case_message$;\n"
665       "  $oneof_name$_ = null;\n"
666       "}\n"
667       "$name$Builder_.clear();\n",
668 
669       "return this;\n");
670 
671   WriteFieldDocComment(printer, descriptor_);
672   printer->Print(variables_,
673                  "$deprecation$public $type$.Builder "
674                  "${$get$capitalized_name$Builder$}$() {\n"
675                  "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
676                  "}\n");
677   printer->Annotate("{", "}", descriptor_);
678   WriteFieldDocComment(printer, descriptor_);
679   printer->Print(
680       variables_,
681       "@java.lang.Override\n"
682       "$deprecation$public $type$OrBuilder "
683       "${$get$capitalized_name$OrBuilder$}$() {\n"
684       "  if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
685       "    return $name$Builder_.getMessageOrBuilder();\n"
686       "  } else {\n"
687       "    if ($has_oneof_case_message$) {\n"
688       "      return ($type$) $oneof_name$_;\n"
689       "    }\n"
690       "    return $type$.getDefaultInstance();\n"
691       "  }\n"
692       "}\n");
693   printer->Annotate("{", "}", descriptor_);
694   WriteFieldDocComment(printer, descriptor_);
695   printer->Print(
696       variables_,
697       "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
698       "    $type$, $type$.Builder, $type$OrBuilder> \n"
699       "    ${$get$capitalized_name$FieldBuilder$}$() {\n"
700       "  if ($name$Builder_ == null) {\n"
701       "    if (!($has_oneof_case_message$)) {\n"
702       "      $oneof_name$_ = $type$.getDefaultInstance();\n"
703       "    }\n"
704       "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
705       "        $type$, $type$.Builder, $type$OrBuilder>(\n"
706       "            ($type$) $oneof_name$_,\n"
707       "            getParentForChildren(),\n"
708       "            isClean());\n"
709       "    $oneof_name$_ = null;\n"
710       "  }\n"
711       "  $set_oneof_case_message$;\n"
712       "  $on_changed$;\n"
713       "  return $name$Builder_;\n"
714       "}\n");
715   printer->Annotate("{", "}", descriptor_);
716 }
717 
GenerateBuilderClearCode(io::Printer * printer) const718 void ImmutableMessageOneofFieldGenerator::GenerateBuilderClearCode(
719     io::Printer* printer) const {
720   // Make sure the builder gets cleared.
721   printer->Print(variables_,
722                  "if ($name$Builder_ != null) {\n"
723                  "  $name$Builder_.clear();\n"
724                  "}\n");
725 }
726 
GenerateBuildingCode(io::Printer * printer) const727 void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode(
728     io::Printer* printer) const {
729   printer->Print(variables_, "if ($has_oneof_case_message$) {\n");
730   printer->Indent();
731 
732   PrintNestedBuilderCondition(
733       printer, "result.$oneof_name$_ = $oneof_name$_;\n",
734 
735       "result.$oneof_name$_ = $name$Builder_.build();\n");
736 
737   printer->Outdent();
738   printer->Print("}\n");
739 }
740 
GenerateMergingCode(io::Printer * printer) const741 void ImmutableMessageOneofFieldGenerator::GenerateMergingCode(
742     io::Printer* printer) const {
743   printer->Print(variables_,
744                  "merge$capitalized_name$(other.get$capitalized_name$());\n");
745 }
746 
GenerateBuilderParsingCode(io::Printer * printer) const747 void ImmutableMessageOneofFieldGenerator::GenerateBuilderParsingCode(
748     io::Printer* printer) const {
749   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
750     printer->Print(variables_,
751                    "input.readGroup($number$,\n"
752                    "    get$capitalized_name$FieldBuilder().getBuilder(),\n"
753                    "    extensionRegistry);\n"
754                    "$set_oneof_case_message$;\n");
755   } else {
756     printer->Print(variables_,
757                    "input.readMessage(\n"
758                    "    get$capitalized_name$FieldBuilder().getBuilder(),\n"
759                    "    extensionRegistry);\n"
760                    "$set_oneof_case_message$;\n");
761   }
762 }
763 
GenerateSerializationCode(io::Printer * printer) const764 void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode(
765     io::Printer* printer) const {
766   printer->Print(
767       variables_,
768       "if ($has_oneof_case_message$) {\n"
769       "  output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
770       "}\n");
771 }
772 
GenerateSerializedSizeCode(io::Printer * printer) const773 void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
774     io::Printer* printer) const {
775   printer->Print(
776       variables_,
777       "if ($has_oneof_case_message$) {\n"
778       "  size += com.google.protobuf.CodedOutputStream\n"
779       "    .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
780       "}\n");
781 }
782 
783 // ===================================================================
784 
RepeatedImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)785 RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator(
786     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
787     Context* context)
788     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
789   SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
790                       context->GetFieldGeneratorInfo(descriptor),
791                       name_resolver_, &variables_);
792 }
793 
794 RepeatedImmutableMessageFieldGenerator::
~RepeatedImmutableMessageFieldGenerator()795     ~RepeatedImmutableMessageFieldGenerator() {}
796 
GetNumBitsForMessage() const797 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
798   return 0;
799 }
800 
GetNumBitsForBuilder() const801 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
802   return 1;
803 }
804 
GenerateInterfaceMembers(io::Printer * printer) const805 void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
806     io::Printer* printer) const {
807   // TODO(jonp): In the future, consider having methods specific to the
808   // interface so that builders can choose dynamically to either return a
809   // message or a nested builder, so that asking for the interface doesn't
810   // cause a message to ever be built.
811   WriteFieldDocComment(printer, descriptor_);
812   printer->Print(variables_,
813                  "$deprecation$java.util.List<$type$> \n"
814                  "    get$capitalized_name$List();\n");
815   WriteFieldDocComment(printer, descriptor_);
816   printer->Print(variables_,
817                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
818   WriteFieldDocComment(printer, descriptor_);
819   printer->Print(variables_,
820                  "$deprecation$int get$capitalized_name$Count();\n");
821 
822   WriteFieldDocComment(printer, descriptor_);
823   printer->Print(variables_,
824                  "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
825                  "    get$capitalized_name$OrBuilderList();\n");
826   WriteFieldDocComment(printer, descriptor_);
827   printer->Print(
828       variables_,
829       "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
830       "    int index);\n");
831 }
832 
GenerateMembers(io::Printer * printer) const833 void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
834     io::Printer* printer) const {
835   printer->Print(variables_, "private java.util.List<$type$> $name$_;\n");
836   PrintExtraFieldInfo(variables_, printer);
837   WriteFieldDocComment(printer, descriptor_);
838   printer->Print(variables_,
839                  "@java.lang.Override\n"
840                  "$deprecation$public java.util.List<$type$> "
841                  "${$get$capitalized_name$List$}$() {\n"
842                  "  return $name$_;\n"  // note:  unmodifiable list
843                  "}\n");
844   printer->Annotate("{", "}", descriptor_);
845   WriteFieldDocComment(printer, descriptor_);
846   printer->Print(
847       variables_,
848       "@java.lang.Override\n"
849       "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
850       "    ${$get$capitalized_name$OrBuilderList$}$() {\n"
851       "  return $name$_;\n"
852       "}\n");
853   printer->Annotate("{", "}", descriptor_);
854   WriteFieldDocComment(printer, descriptor_);
855   printer->Print(
856       variables_,
857       "@java.lang.Override\n"
858       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
859       "  return $name$_.size();\n"
860       "}\n");
861   printer->Annotate("{", "}", descriptor_);
862   WriteFieldDocComment(printer, descriptor_);
863   printer->Print(
864       variables_,
865       "@java.lang.Override\n"
866       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
867       "  return $name$_.get(index);\n"
868       "}\n");
869   printer->Annotate("{", "}", descriptor_);
870   WriteFieldDocComment(printer, descriptor_);
871   printer->Print(variables_,
872                  "@java.lang.Override\n"
873                  "$deprecation$public $type$OrBuilder "
874                  "${$get$capitalized_name$OrBuilder$}$(\n"
875                  "    int index) {\n"
876                  "  return $name$_.get(index);\n"
877                  "}\n");
878   printer->Annotate("{", "}", descriptor_);
879 }
880 
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const881 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
882     io::Printer* printer, const char* regular_case,
883     const char* nested_builder_case) const {
884   printer->Print(variables_, "if ($name$Builder_ == null) {\n");
885   printer->Indent();
886   printer->Print(variables_, regular_case);
887   printer->Outdent();
888   printer->Print("} else {\n");
889   printer->Indent();
890   printer->Print(variables_, nested_builder_case);
891   printer->Outdent();
892   printer->Print("}\n");
893 }
894 
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const895 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
896     io::Printer* printer, const char* method_prototype,
897     const char* regular_case, const char* nested_builder_case,
898     const char* trailing_code) const {
899   printer->Print(variables_, method_prototype);
900   printer->Annotate("{", "}", descriptor_);
901   printer->Print(" {\n");
902   printer->Indent();
903   PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
904   if (trailing_code != NULL) {
905     printer->Print(variables_, trailing_code);
906   }
907   printer->Outdent();
908   printer->Print("}\n");
909 }
910 
GenerateBuilderMembers(io::Printer * printer) const911 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
912     io::Printer* printer) const {
913   // When using nested-builders, the code initially works just like the
914   // non-nested builder case. It only creates a nested builder lazily on
915   // demand and then forever delegates to it after creation.
916 
917   printer->Print(
918       variables_,
919       // Used when the builder is null.
920       // One field is the list and the other field keeps track of whether the
921       // list is immutable. If it's immutable, the invariant is that it must
922       // either an instance of Collections.emptyList() or it's an ArrayList
923       // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
924       // a reference to the underlying ArrayList. This invariant allows us to
925       // share instances of lists between protocol buffers avoiding expensive
926       // memory allocations. Note, immutable is a strong guarantee here -- not
927       // just that the list cannot be modified via the reference but that the
928       // list can never be modified.
929       "private java.util.List<$type$> $name$_ =\n"
930       "  java.util.Collections.emptyList();\n"
931 
932       "private void ensure$capitalized_name$IsMutable() {\n"
933       "  if (!$get_mutable_bit_builder$) {\n"
934       "    $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
935       "    $set_mutable_bit_builder$;\n"
936       "   }\n"
937       "}\n"
938       "\n");
939 
940   printer->Print(
941       variables_,
942       // If this builder is non-null, it is used and the other fields are
943       // ignored.
944       "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
945       "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
946       "\n");
947 
948   // The comments above the methods below are based on a hypothetical
949   // repeated field of type "Field" called "RepeatedField".
950 
951   // List<Field> getRepeatedFieldList()
952   WriteFieldDocComment(printer, descriptor_);
953   PrintNestedBuilderFunction(
954       printer,
955       "$deprecation$public java.util.List<$type$> "
956       "${$get$capitalized_name$List$}$()",
957 
958       "return java.util.Collections.unmodifiableList($name$_);\n",
959       "return $name$Builder_.getMessageList();\n",
960 
961       NULL);
962 
963   // int getRepeatedFieldCount()
964   WriteFieldDocComment(printer, descriptor_);
965   PrintNestedBuilderFunction(
966       printer, "$deprecation$public int ${$get$capitalized_name$Count$}$()",
967 
968       "return $name$_.size();\n", "return $name$Builder_.getCount();\n",
969 
970       NULL);
971 
972   // Field getRepeatedField(int index)
973   WriteFieldDocComment(printer, descriptor_);
974   PrintNestedBuilderFunction(
975       printer,
976       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)",
977 
978       "return $name$_.get(index);\n",
979 
980       "return $name$Builder_.getMessage(index);\n",
981 
982       NULL);
983 
984   // Builder setRepeatedField(int index, Field value)
985   WriteFieldDocComment(printer, descriptor_);
986   PrintNestedBuilderFunction(
987       printer,
988       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
989       "    int index, $type$ value)",
990       "if (value == null) {\n"
991       "  throw new NullPointerException();\n"
992       "}\n"
993       "ensure$capitalized_name$IsMutable();\n"
994       "$name$_.set(index, value);\n"
995       "$on_changed$\n",
996       "$name$Builder_.setMessage(index, value);\n", "return this;\n");
997 
998   // Builder setRepeatedField(int index, Field.Builder builderForValue)
999   WriteFieldDocComment(printer, descriptor_);
1000   PrintNestedBuilderFunction(
1001       printer,
1002       "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1003       "    int index, $type$.Builder builderForValue)",
1004 
1005       "ensure$capitalized_name$IsMutable();\n"
1006       "$name$_.set(index, builderForValue.build());\n"
1007       "$on_changed$\n",
1008 
1009       "$name$Builder_.setMessage(index, builderForValue.build());\n",
1010 
1011       "return this;\n");
1012 
1013   // Builder addRepeatedField(Field value)
1014   WriteFieldDocComment(printer, descriptor_);
1015   PrintNestedBuilderFunction(
1016       printer,
1017       "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)",
1018 
1019       "if (value == null) {\n"
1020       "  throw new NullPointerException();\n"
1021       "}\n"
1022       "ensure$capitalized_name$IsMutable();\n"
1023       "$name$_.add(value);\n"
1024 
1025       "$on_changed$\n",
1026 
1027       "$name$Builder_.addMessage(value);\n",
1028 
1029       "return this;\n");
1030 
1031   // Builder addRepeatedField(int index, Field value)
1032   WriteFieldDocComment(printer, descriptor_);
1033   PrintNestedBuilderFunction(
1034       printer,
1035       "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1036       "    int index, $type$ value)",
1037 
1038       "if (value == null) {\n"
1039       "  throw new NullPointerException();\n"
1040       "}\n"
1041       "ensure$capitalized_name$IsMutable();\n"
1042       "$name$_.add(index, value);\n"
1043       "$on_changed$\n",
1044 
1045       "$name$Builder_.addMessage(index, value);\n",
1046 
1047       "return this;\n");
1048 
1049   // Builder addRepeatedField(Field.Builder builderForValue)
1050   WriteFieldDocComment(printer, descriptor_);
1051   PrintNestedBuilderFunction(
1052       printer,
1053       "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1054       "    $type$.Builder builderForValue)",
1055 
1056       "ensure$capitalized_name$IsMutable();\n"
1057       "$name$_.add(builderForValue.build());\n"
1058       "$on_changed$\n",
1059 
1060       "$name$Builder_.addMessage(builderForValue.build());\n",
1061 
1062       "return this;\n");
1063 
1064   // Builder addRepeatedField(int index, Field.Builder builderForValue)
1065   WriteFieldDocComment(printer, descriptor_);
1066   PrintNestedBuilderFunction(
1067       printer,
1068       "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1069       "    int index, $type$.Builder builderForValue)",
1070 
1071       "ensure$capitalized_name$IsMutable();\n"
1072       "$name$_.add(index, builderForValue.build());\n"
1073       "$on_changed$\n",
1074 
1075       "$name$Builder_.addMessage(index, builderForValue.build());\n",
1076 
1077       "return this;\n");
1078 
1079   // Builder addAllRepeatedField(Iterable<Field> values)
1080   WriteFieldDocComment(printer, descriptor_);
1081   PrintNestedBuilderFunction(
1082       printer,
1083       "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
1084       "    java.lang.Iterable<? extends $type$> values)",
1085 
1086       "ensure$capitalized_name$IsMutable();\n"
1087       "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
1088       "    values, $name$_);\n"
1089       "$on_changed$\n",
1090 
1091       "$name$Builder_.addAllMessages(values);\n",
1092 
1093       "return this;\n");
1094 
1095   // Builder clearAllRepeatedField()
1096   WriteFieldDocComment(printer, descriptor_);
1097   PrintNestedBuilderFunction(
1098       printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
1099 
1100       "$name$_ = java.util.Collections.emptyList();\n"
1101       "$clear_mutable_bit_builder$;\n"
1102       "$on_changed$\n",
1103 
1104       "$name$Builder_.clear();\n",
1105 
1106       "return this;\n");
1107 
1108   // Builder removeRepeatedField(int index)
1109   WriteFieldDocComment(printer, descriptor_);
1110   PrintNestedBuilderFunction(
1111       printer,
1112       "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
1113 
1114       "ensure$capitalized_name$IsMutable();\n"
1115       "$name$_.remove(index);\n"
1116       "$on_changed$\n",
1117 
1118       "$name$Builder_.remove(index);\n",
1119 
1120       "return this;\n");
1121 
1122   WriteFieldDocComment(printer, descriptor_);
1123   printer->Print(
1124       variables_,
1125       "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n"
1126       "    int index) {\n"
1127       "  return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
1128       "}\n");
1129   printer->Annotate("{", "}", descriptor_);
1130 
1131   WriteFieldDocComment(printer, descriptor_);
1132   printer->Print(variables_,
1133                  "$deprecation$public $type$OrBuilder "
1134                  "${$get$capitalized_name$OrBuilder$}$(\n"
1135                  "    int index) {\n"
1136                  "  if ($name$Builder_ == null) {\n"
1137                  "    return $name$_.get(index);"
1138                  "  } else {\n"
1139                  "    return $name$Builder_.getMessageOrBuilder(index);\n"
1140                  "  }\n"
1141                  "}\n");
1142   printer->Annotate("{", "}", descriptor_);
1143 
1144   WriteFieldDocComment(printer, descriptor_);
1145   printer->Print(
1146       variables_,
1147       "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
1148       "     ${$get$capitalized_name$OrBuilderList$}$() {\n"
1149       "  if ($name$Builder_ != null) {\n"
1150       "    return $name$Builder_.getMessageOrBuilderList();\n"
1151       "  } else {\n"
1152       "    return java.util.Collections.unmodifiableList($name$_);\n"
1153       "  }\n"
1154       "}\n");
1155   printer->Annotate("{", "}", descriptor_);
1156 
1157   WriteFieldDocComment(printer, descriptor_);
1158   printer->Print(variables_,
1159                  "$deprecation$public $type$.Builder "
1160                  "${$add$capitalized_name$Builder$}$() {\n"
1161                  "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
1162                  "      $type$.getDefaultInstance());\n"
1163                  "}\n");
1164   printer->Annotate("{", "}", descriptor_);
1165   WriteFieldDocComment(printer, descriptor_);
1166   printer->Print(
1167       variables_,
1168       "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
1169       "    int index) {\n"
1170       "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
1171       "      index, $type$.getDefaultInstance());\n"
1172       "}\n");
1173   printer->Annotate("{", "}", descriptor_);
1174   WriteFieldDocComment(printer, descriptor_);
1175   printer->Print(
1176       variables_,
1177       "$deprecation$public java.util.List<$type$.Builder> \n"
1178       "     ${$get$capitalized_name$BuilderList$}$() {\n"
1179       "  return get$capitalized_name$FieldBuilder().getBuilderList();\n"
1180       "}\n"
1181       "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1182       "    $type$, $type$.Builder, $type$OrBuilder> \n"
1183       "    get$capitalized_name$FieldBuilder() {\n"
1184       "  if ($name$Builder_ == null) {\n"
1185       "    $name$Builder_ = new "
1186       "com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1187       "        $type$, $type$.Builder, $type$OrBuilder>(\n"
1188       "            $name$_,\n"
1189       "            $get_mutable_bit_builder$,\n"
1190       "            getParentForChildren(),\n"
1191       "            isClean());\n"
1192       "    $name$_ = null;\n"
1193       "  }\n"
1194       "  return $name$Builder_;\n"
1195       "}\n");
1196   printer->Annotate("{", "}", descriptor_);
1197 }
1198 
1199 void RepeatedImmutableMessageFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const1200     GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
1201   printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
1202 }
1203 
GenerateInitializationCode(io::Printer * printer) const1204 void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
1205     io::Printer* printer) const {
1206   printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
1207 }
1208 
GenerateBuilderClearCode(io::Printer * printer) const1209 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
1210     io::Printer* printer) const {
1211   PrintNestedBuilderCondition(printer,
1212                               "$name$_ = java.util.Collections.emptyList();\n",
1213 
1214                               "$name$_ = null;\n"
1215                               "$name$Builder_.clear();\n");
1216 
1217   printer->Print(variables_, "$clear_mutable_bit_builder$;\n");
1218 }
1219 
GenerateMergingCode(io::Printer * printer) const1220 void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
1221     io::Printer* printer) const {
1222   // The code below does two optimizations (non-nested builder case):
1223   //   1. If the other list is empty, there's nothing to do. This ensures we
1224   //      don't allocate a new array if we already have an immutable one.
1225   //   2. If the other list is non-empty and our current list is empty, we can
1226   //      reuse the other list which is guaranteed to be immutable.
1227   PrintNestedBuilderCondition(
1228       printer,
1229       "if (!other.$name$_.isEmpty()) {\n"
1230       "  if ($name$_.isEmpty()) {\n"
1231       "    $name$_ = other.$name$_;\n"
1232       "    $clear_mutable_bit_builder$;\n"
1233       "  } else {\n"
1234       "    ensure$capitalized_name$IsMutable();\n"
1235       "    $name$_.addAll(other.$name$_);\n"
1236       "  }\n"
1237       "  $on_changed$\n"
1238       "}\n",
1239 
1240       "if (!other.$name$_.isEmpty()) {\n"
1241       "  if ($name$Builder_.isEmpty()) {\n"
1242       "    $name$Builder_.dispose();\n"
1243       "    $name$Builder_ = null;\n"
1244       "    $name$_ = other.$name$_;\n"
1245       "    $clear_mutable_bit_builder$;\n"
1246       "    $name$Builder_ = \n"
1247       "      com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders "
1248       "?\n"
1249       "         get$capitalized_name$FieldBuilder() : null;\n"
1250       "  } else {\n"
1251       "    $name$Builder_.addAllMessages(other.$name$_);\n"
1252       "  }\n"
1253       "}\n");
1254 }
1255 
GenerateBuildingCode(io::Printer * printer) const1256 void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode(
1257     io::Printer* printer) const {
1258   // The code below (non-nested builder case) ensures that the result has an
1259   // immutable list. If our list is immutable, we can just reuse it. If not,
1260   // we make it immutable.
1261   PrintNestedBuilderCondition(
1262       printer,
1263       "if ($get_mutable_bit_builder$) {\n"
1264       "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1265       "  $clear_mutable_bit_builder$;\n"
1266       "}\n"
1267       "result.$name$_ = $name$_;\n",
1268 
1269       "result.$name$_ = $name$Builder_.build();\n");
1270 }
1271 
GenerateBuilderParsingCode(io::Printer * printer) const1272 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
1273     io::Printer* printer) const {
1274   if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
1275     printer->Print(variables_,
1276                    "$type$ m =\n"
1277                    "    input.readGroup($number$,\n"
1278                    "        $type$.$get_parser$,\n"
1279                    "        extensionRegistry);\n");
1280   } else {
1281     printer->Print(variables_,
1282                    "$type$ m =\n"
1283                    "    input.readMessage(\n"
1284                    "        $type$.$get_parser$,\n"
1285                    "        extensionRegistry);\n");
1286   }
1287   PrintNestedBuilderCondition(printer,
1288                               "ensure$capitalized_name$IsMutable();\n"
1289                               "$name$_.add(m);\n",
1290                               "$name$Builder_.addMessage(m);\n");
1291 }
1292 
GenerateSerializationCode(io::Printer * printer) const1293 void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
1294     io::Printer* printer) const {
1295   printer->Print(variables_,
1296                  "for (int i = 0; i < $name$_.size(); i++) {\n"
1297                  "  output.write$group_or_message$($number$, $name$_.get(i));\n"
1298                  "}\n");
1299 }
1300 
GenerateSerializedSizeCode(io::Printer * printer) const1301 void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
1302     io::Printer* printer) const {
1303   printer->Print(
1304       variables_,
1305       "for (int i = 0; i < $name$_.size(); i++) {\n"
1306       "  size += com.google.protobuf.CodedOutputStream\n"
1307       "    .compute$group_or_message$Size($number$, $name$_.get(i));\n"
1308       "}\n");
1309 }
1310 
GenerateEqualsCode(io::Printer * printer) const1311 void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode(
1312     io::Printer* printer) const {
1313   printer->Print(
1314       variables_,
1315       "if (!get$capitalized_name$List()\n"
1316       "    .equals(other.get$capitalized_name$List())) return false;\n");
1317 }
1318 
GenerateHashCode(io::Printer * printer) const1319 void RepeatedImmutableMessageFieldGenerator::GenerateHashCode(
1320     io::Printer* printer) const {
1321   printer->Print(
1322       variables_,
1323       "if (get$capitalized_name$Count() > 0) {\n"
1324       "  hash = (37 * hash) + $constant_name$;\n"
1325       "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
1326       "}\n");
1327 }
1328 
GetBoxedType() const1329 std::string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
1330   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
1331 }
1332 
1333 }  // namespace java
1334 }  // namespace compiler
1335 }  // namespace protobuf
1336 }  // namespace google
1337