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