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