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