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