1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: kenton@google.com (Kenton Varda)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include "google/protobuf/compiler/java/full/message_field.h"
13
14 #include <string>
15
16 #include "absl/log/absl_check.h"
17 #include "absl/strings/str_cat.h"
18 #include "google/protobuf/compiler/java/context.h"
19 #include "google/protobuf/compiler/java/doc_comment.h"
20 #include "google/protobuf/compiler/java/field_common.h"
21 #include "google/protobuf/compiler/java/helpers.h"
22 #include "google/protobuf/compiler/java/name_resolver.h"
23 #include "google/protobuf/io/printer.h"
24
25 // Must be last.
26 #include "google/protobuf/port_def.inc"
27
28 namespace google {
29 namespace protobuf {
30 namespace compiler {
31 namespace java {
32
33
34 namespace {
35 using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
36
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,absl::flat_hash_map<absl::string_view,std::string> * variables,Context * context)37 void SetMessageVariables(
38 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
39 const FieldGeneratorInfo* info, ClassNameResolver* name_resolver,
40 absl::flat_hash_map<absl::string_view, std::string>* variables,
41 Context* context) {
42 SetCommonFieldVariables(descriptor, info, variables);
43
44 (*variables)["type"] =
45 name_resolver->GetImmutableClassName(descriptor->message_type());
46 variables->insert({"kt_type", EscapeKotlinKeywords((*variables)["type"])});
47 (*variables)["mutable_type"] =
48 name_resolver->GetMutableClassName(descriptor->message_type());
49 (*variables)["group_or_message"] =
50 (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
51 : "Message";
52 // TODO: Add @deprecated javadoc when generating javadoc is supported
53 // by the proto compiler
54 (*variables)["deprecation"] =
55 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
56 variables->insert(
57 {"kt_deprecation",
58 descriptor->options().deprecated()
59 ? absl::StrCat("@kotlin.Deprecated(message = \"Field ",
60 (*variables)["name"], " is deprecated\") ")
61 : ""});
62 (*variables)["on_changed"] = "onChanged();";
63 (*variables)["get_parser"] = "parser()";
64
65 if (HasHasbit(descriptor)) {
66 // For singular messages and builders, one bit is used for the hasField bit.
67 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
68
69 // Note that these have a trailing ";".
70 (*variables)["set_has_field_bit_to_local"] =
71 GenerateSetBitToLocal(messageBitIndex);
72
73 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
74 } else {
75 (*variables)["set_has_field_bit_to_local"] = "";
76 variables->insert({"is_field_present_message",
77 absl::StrCat((*variables)["name"], "_ != null")});
78 }
79
80 // For repeated builders, one bit is used for whether the array is immutable.
81 (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
82 (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
83 (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
84
85 (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
86 (*variables)["set_has_field_bit_builder"] =
87 absl::StrCat(GenerateSetBit(builderBitIndex), ";");
88 (*variables)["clear_has_field_bit_builder"] =
89 absl::StrCat(GenerateClearBit(builderBitIndex), ";");
90 (*variables)["get_has_field_bit_from_local"] =
91 GenerateGetBitFromLocal(builderBitIndex);
92 }
93
94 } // namespace
95
96 // ===================================================================
97
ImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)98 ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator(
99 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
100 Context* context)
101 : descriptor_(descriptor),
102 message_bit_index_(messageBitIndex),
103 builder_bit_index_(builderBitIndex),
104 name_resolver_(context->GetNameResolver()),
105 context_(context) {
106 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
107 context->GetFieldGeneratorInfo(descriptor),
108 name_resolver_, &variables_, context);
109 }
110
~ImmutableMessageFieldGenerator()111 ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
112
GetMessageBitIndex() const113 int ImmutableMessageFieldGenerator::GetMessageBitIndex() const {
114 return message_bit_index_;
115 }
116
GetBuilderBitIndex() const117 int ImmutableMessageFieldGenerator::GetBuilderBitIndex() const {
118 return builder_bit_index_;
119 }
120
GetNumBitsForMessage() const121 int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
122 return HasHasbit(descriptor_) ? 1 : 0;
123 }
124
GetNumBitsForBuilder() const125 int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { return 1; }
126
GenerateInterfaceMembers(io::Printer * printer) const127 void ImmutableMessageFieldGenerator::GenerateInterfaceMembers(
128 io::Printer* printer) const {
129 // TODO: In the future, consider having a method specific to the
130 // interface so that builders can choose dynamically to either return a
131 // message or a nested builder, so that asking for the interface doesn't
132 // cause a message to ever be built.
133 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
134 context_->options());
135 printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
136 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
137 context_->options());
138 printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
139
140 WriteFieldDocComment(printer, descriptor_, context_->options());
141 printer->Print(
142 variables_,
143 "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
144 }
145
GenerateMembers(io::Printer * printer) const146 void ImmutableMessageFieldGenerator::GenerateMembers(
147 io::Printer* printer) const {
148 printer->Print(variables_, "private $type$ $name$_;\n");
149 PrintExtraFieldInfo(variables_, printer);
150
151 if (HasHasbit(descriptor_)) {
152 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
153 context_->options());
154 printer->Print(
155 variables_,
156 "@java.lang.Override\n"
157 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
158 " return $get_has_field_bit_message$;\n"
159 "}\n");
160 printer->Annotate("{", "}", descriptor_);
161 } else {
162 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
163 context_->options());
164 printer->Print(
165 variables_,
166 "@java.lang.Override\n"
167 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
168 " return $name$_ != null;\n"
169 "}\n");
170 printer->Annotate("{", "}", descriptor_);
171 }
172 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
173 context_->options());
174 printer->Print(
175 variables_,
176 "@java.lang.Override\n"
177 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
178 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
179 "}\n");
180 printer->Annotate("{", "}", descriptor_);
181
182 WriteFieldDocComment(printer, descriptor_, context_->options());
183 printer->Print(
184 variables_,
185 "@java.lang.Override\n"
186 "$deprecation$public $type$OrBuilder "
187 "${$get$capitalized_name$OrBuilder$}$() {\n"
188 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
189 "}\n");
190 printer->Annotate("{", "}", descriptor_);
191 }
192
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const193 void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
194 io::Printer* printer, const char* regular_case,
195 const char* nested_builder_case) const {
196 printer->Print(variables_, "if ($name$Builder_ == null) {\n");
197 printer->Indent();
198 printer->Print(variables_, regular_case);
199 printer->Outdent();
200 printer->Print("} else {\n");
201 printer->Indent();
202 printer->Print(variables_, nested_builder_case);
203 printer->Outdent();
204 printer->Print("}\n");
205 }
206
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code,absl::optional<io::AnnotationCollector::Semantic> semantic) const207 void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
208 io::Printer* printer, const char* method_prototype,
209 const char* regular_case, const char* nested_builder_case,
210 const char* trailing_code,
211 absl::optional<io::AnnotationCollector::Semantic> semantic) const {
212 printer->Print(variables_, method_prototype);
213 printer->Annotate("{", "}", descriptor_, semantic);
214 printer->Print(" {\n");
215 printer->Indent();
216 PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
217 if (trailing_code != nullptr) {
218 printer->Print(variables_, trailing_code);
219 }
220 printer->Outdent();
221 printer->Print("}\n");
222 }
223
GenerateBuilderMembers(io::Printer * printer) const224 void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
225 io::Printer* printer) const {
226 // When using nested-builders, the code initially works just like the
227 // non-nested builder case. It only creates a nested builder lazily on
228 // demand and then forever delegates to it after creation.
229 printer->Print(variables_, "private $type$ $name$_;\n");
230
231 printer->Print(variables_,
232 // If this builder is non-null, it is used and the other fields
233 // are ignored.
234 "private com.google.protobuf.SingleFieldBuilder<\n"
235 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
236 "\n");
237
238 // The comments above the methods below are based on a hypothetical
239 // field of type "Field" called "Field".
240
241 // boolean hasField()
242 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
243 context_->options());
244 printer->Print(variables_,
245 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
246 " return $get_has_field_bit_builder$;\n"
247 "}\n");
248 printer->Annotate("{", "}", descriptor_);
249
250 // Field getField()
251 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
252 context_->options());
253 PrintNestedBuilderFunction(
254 printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
255 "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
256 "return $name$Builder_.getMessage();\n", nullptr);
257
258 // Field.Builder setField(Field value)
259 WriteFieldDocComment(printer, descriptor_, context_->options());
260 PrintNestedBuilderFunction(
261 printer,
262 "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
263
264 "if (value == null) {\n"
265 " throw new NullPointerException();\n"
266 "}\n"
267 "$name$_ = value;\n",
268
269 "$name$Builder_.setMessage(value);\n",
270
271 "$set_has_field_bit_builder$\n"
272 "$on_changed$\n"
273 "return this;\n",
274 Semantic::kSet);
275
276 // Field.Builder setField(Field.Builder builderForValue)
277 WriteFieldDocComment(printer, descriptor_, context_->options());
278 PrintNestedBuilderFunction(
279 printer,
280 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
281 " $type$.Builder builderForValue)",
282
283 "$name$_ = builderForValue.build();\n",
284
285 "$name$Builder_.setMessage(builderForValue.build());\n",
286
287 "$set_has_field_bit_builder$\n"
288 "$on_changed$\n"
289 "return this;\n",
290 Semantic::kSet);
291
292 // Message.Builder mergeField(Field value)
293 WriteFieldDocComment(printer, descriptor_, context_->options());
294 PrintNestedBuilderFunction(
295 printer,
296 "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
297 "if ($get_has_field_bit_builder$ &&\n"
298 " $name$_ != null &&\n"
299 " $name$_ != $type$.getDefaultInstance()) {\n"
300 " get$capitalized_name$Builder().mergeFrom(value);\n"
301 "} else {\n"
302 " $name$_ = value;\n"
303 "}\n",
304
305 "$name$Builder_.mergeFrom(value);\n",
306
307 "if ($name$_ != null) {\n"
308 " $set_has_field_bit_builder$\n"
309 " $on_changed$\n"
310 "}\n"
311 "return this;\n",
312 Semantic::kSet);
313
314 // Message.Builder clearField()
315 WriteFieldDocComment(printer, descriptor_, context_->options());
316 printer->Print(
317 variables_,
318 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
319 " $clear_has_field_bit_builder$\n"
320 " $name$_ = null;\n"
321 " if ($name$Builder_ != null) {\n"
322 " $name$Builder_.dispose();\n"
323 " $name$Builder_ = null;\n"
324 " }\n"
325 " $on_changed$\n"
326 " return this;\n"
327 "}\n");
328 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
329
330 // Field.Builder getFieldBuilder()
331 WriteFieldDocComment(printer, descriptor_, context_->options());
332 printer->Print(variables_,
333 "$deprecation$public $type$.Builder "
334 "${$get$capitalized_name$Builder$}$() {\n"
335 " $set_has_field_bit_builder$\n"
336 " $on_changed$\n"
337 " return get$capitalized_name$FieldBuilder().getBuilder();\n"
338 "}\n");
339 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
340
341 // FieldOrBuilder getFieldOrBuilder()
342 WriteFieldDocComment(printer, descriptor_, context_->options());
343 printer->Print(variables_,
344 "$deprecation$public $type$OrBuilder "
345 "${$get$capitalized_name$OrBuilder$}$() {\n"
346 " if ($name$Builder_ != null) {\n"
347 " return $name$Builder_.getMessageOrBuilder();\n"
348 " } else {\n"
349 " return $name$_ == null ?\n"
350 " $type$.getDefaultInstance() : $name$_;\n"
351 " }\n"
352 "}\n");
353 printer->Annotate("{", "}", descriptor_);
354
355 // SingleFieldBuilder getFieldFieldBuilder
356 WriteFieldDocComment(printer, descriptor_, context_->options());
357 printer->Print(
358 variables_,
359 "private com.google.protobuf.SingleFieldBuilder<\n"
360 " $type$, $type$.Builder, $type$OrBuilder> \n"
361 " get$capitalized_name$FieldBuilder() {\n"
362 " if ($name$Builder_ == null) {\n"
363 " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
364 " $type$, $type$.Builder, $type$OrBuilder>(\n"
365 " get$capitalized_name$(),\n"
366 " getParentForChildren(),\n"
367 " isClean());\n"
368 " $name$_ = null;\n"
369 " }\n"
370 " return $name$Builder_;\n"
371 "}\n");
372 }
373
GenerateKotlinDslMembers(io::Printer * printer) const374 void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers(
375 io::Printer* printer) const {
376 WriteFieldDocComment(printer, descriptor_, context_->options(),
377 /* kdoc */ true);
378 printer->Print(variables_,
379 "$kt_deprecation$public var $kt_name$: $kt_type$\n"
380 " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
381 " get() = $kt_dsl_builder$.${$$kt_safe_name$$}$\n"
382 " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
383 " set(value) {\n"
384 " $kt_dsl_builder$.${$$kt_safe_name$$}$ = value\n"
385 " }\n");
386
387 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
388 context_->options(),
389 /* builder */ false, /* kdoc */ true);
390 printer->Print(variables_,
391 "public fun ${$clear$kt_capitalized_name$$}$() {\n"
392 " $kt_dsl_builder$.clear$capitalized_name$()\n"
393 "}\n");
394 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
395
396 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
397 context_->options(),
398 /* builder */ false, /* kdoc */ true);
399 printer->Print(
400 variables_,
401 "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
402 " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
403 "}\n");
404
405 GenerateKotlinOrNull(printer);
406 }
407
GenerateKotlinOrNull(io::Printer * printer) const408 void ImmutableMessageFieldGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
409 if (descriptor_->has_presence() &&
410 descriptor_->real_containing_oneof() == nullptr) {
411 printer->Print(variables_,
412 "$kt_deprecation$\n"
413 "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n"
414 " get() = $kt_dsl_builder$.$name$OrNull\n");
415 }
416 }
417
GenerateFieldBuilderInitializationCode(io::Printer * printer) const418 void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode(
419 io::Printer* printer) const {
420 printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
421 }
422
GenerateInitializationCode(io::Printer * printer) const423 void ImmutableMessageFieldGenerator::GenerateInitializationCode(
424 io::Printer* printer) const {}
425
GenerateBuilderClearCode(io::Printer * printer) const426 void ImmutableMessageFieldGenerator::GenerateBuilderClearCode(
427 io::Printer* printer) const {
428 // No need to clear the has-bit since we clear the bitField ints all at once.
429 printer->Print(variables_,
430 "$name$_ = null;\n"
431 "if ($name$Builder_ != null) {\n"
432 " $name$Builder_.dispose();\n"
433 " $name$Builder_ = null;\n"
434 "}\n");
435 }
436
GenerateMergingCode(io::Printer * printer) const437 void ImmutableMessageFieldGenerator::GenerateMergingCode(
438 io::Printer* printer) const {
439 printer->Print(variables_,
440 "if (other.has$capitalized_name$()) {\n"
441 " merge$capitalized_name$(other.get$capitalized_name$());\n"
442 "}\n");
443 }
444
GenerateBuildingCode(io::Printer * printer) const445 void ImmutableMessageFieldGenerator::GenerateBuildingCode(
446 io::Printer* printer) const {
447 printer->Print(variables_,
448 "if ($get_has_field_bit_from_local$) {\n"
449 " result.$name$_ = $name$Builder_ == null\n"
450 " ? $name$_\n"
451 " : $name$Builder_.build();\n");
452 if (GetNumBitsForMessage() > 0) {
453 printer->Print(variables_, " $set_has_field_bit_to_local$;\n");
454 }
455 printer->Print("}\n");
456 }
457
GenerateBuilderParsingCode(io::Printer * printer) const458 void ImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
459 io::Printer* printer) const {
460 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
461 printer->Print(variables_,
462 "input.readGroup($number$,\n"
463 " get$capitalized_name$FieldBuilder().getBuilder(),\n"
464 " extensionRegistry);\n"
465 "$set_has_field_bit_builder$\n");
466 } else {
467 printer->Print(variables_,
468 "input.readMessage(\n"
469 " get$capitalized_name$FieldBuilder().getBuilder(),\n"
470 " extensionRegistry);\n"
471 "$set_has_field_bit_builder$\n");
472 }
473 }
474
GenerateSerializationCode(io::Printer * printer) const475 void ImmutableMessageFieldGenerator::GenerateSerializationCode(
476 io::Printer* printer) const {
477 printer->Print(
478 variables_,
479 "if ($is_field_present_message$) {\n"
480 " output.write$group_or_message$($number$, get$capitalized_name$());\n"
481 "}\n");
482 }
483
GenerateSerializedSizeCode(io::Printer * printer) const484 void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
485 io::Printer* printer) const {
486 printer->Print(
487 variables_,
488 "if ($is_field_present_message$) {\n"
489 " size += com.google.protobuf.CodedOutputStream\n"
490 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
491 "}\n");
492 }
493
GenerateEqualsCode(io::Printer * printer) const494 void ImmutableMessageFieldGenerator::GenerateEqualsCode(
495 io::Printer* printer) const {
496 printer->Print(variables_,
497 "if (!get$capitalized_name$()\n"
498 " .equals(other.get$capitalized_name$())) return false;\n");
499 }
500
GenerateHashCode(io::Printer * printer) const501 void ImmutableMessageFieldGenerator::GenerateHashCode(
502 io::Printer* printer) const {
503 printer->Print(variables_,
504 "hash = (37 * hash) + $constant_name$;\n"
505 "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
506 }
507
GetBoxedType() const508 std::string ImmutableMessageFieldGenerator::GetBoxedType() const {
509 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
510 }
511
512 // ===================================================================
513
ImmutableMessageOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)514 ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator(
515 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
516 Context* context)
517 : ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
518 builderBitIndex, context) {
519 const OneofGeneratorInfo* info =
520 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
521 SetCommonOneofVariables(descriptor, info, &variables_);
522 }
523
~ImmutableMessageOneofFieldGenerator()524 ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() {}
525
GenerateMembers(io::Printer * printer) const526 void ImmutableMessageOneofFieldGenerator::GenerateMembers(
527 io::Printer* printer) const {
528 PrintExtraFieldInfo(variables_, printer);
529 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
530 context_->options());
531 printer->Print(variables_,
532 "@java.lang.Override\n"
533 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
534 " return $has_oneof_case_message$;\n"
535 "}\n");
536 printer->Annotate("{", "}", descriptor_);
537
538 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
539 context_->options());
540 printer->Print(variables_,
541 "@java.lang.Override\n"
542 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
543 " if ($has_oneof_case_message$) {\n"
544 " return ($type$) $oneof_name$_;\n"
545 " }\n"
546 " return $type$.getDefaultInstance();\n"
547 "}\n");
548 printer->Annotate("{", "}", descriptor_);
549
550 WriteFieldDocComment(printer, descriptor_, context_->options());
551 printer->Print(variables_,
552 "@java.lang.Override\n"
553 "$deprecation$public $type$OrBuilder "
554 "${$get$capitalized_name$OrBuilder$}$() {\n"
555 " if ($has_oneof_case_message$) {\n"
556 " return ($type$) $oneof_name$_;\n"
557 " }\n"
558 " return $type$.getDefaultInstance();\n"
559 "}\n");
560 printer->Annotate("{", "}", descriptor_);
561 }
562
GenerateBuilderMembers(io::Printer * printer) const563 void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers(
564 io::Printer* printer) const {
565 // When using nested-builders, the code initially works just like the
566 // non-nested builder case. It only creates a nested builder lazily on
567 // demand and then forever delegates to it after creation.
568 printer->Print(variables_,
569 // If this builder is non-null, it is used and the other fields
570 // are ignored.
571 "private com.google.protobuf.SingleFieldBuilder<\n"
572 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
573 "\n");
574
575 // The comments above the methods below are based on a hypothetical
576 // field of type "Field" called "Field".
577
578 // boolean hasField()
579 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
580 context_->options());
581 printer->Print(variables_,
582 "@java.lang.Override\n"
583 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
584 " return $has_oneof_case_message$;\n"
585 "}\n");
586 printer->Annotate("{", "}", descriptor_);
587
588 // Field getField()
589 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
590 context_->options());
591 PrintNestedBuilderFunction(
592 printer,
593 "@java.lang.Override\n"
594 "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
595
596 "if ($has_oneof_case_message$) {\n"
597 " return ($type$) $oneof_name$_;\n"
598 "}\n"
599 "return $type$.getDefaultInstance();\n",
600
601 "if ($has_oneof_case_message$) {\n"
602 " return $name$Builder_.getMessage();\n"
603 "}\n"
604 "return $type$.getDefaultInstance();\n",
605
606 nullptr);
607
608 // Field.Builder setField(Field value)
609 WriteFieldDocComment(printer, descriptor_, context_->options());
610 PrintNestedBuilderFunction(
611 printer,
612 "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
613
614 "if (value == null) {\n"
615 " throw new NullPointerException();\n"
616 "}\n"
617 "$oneof_name$_ = value;\n"
618 "$on_changed$\n",
619
620 "$name$Builder_.setMessage(value);\n",
621
622 "$set_oneof_case_message$;\n"
623 "return this;\n",
624 Semantic::kSet);
625
626 // Field.Builder setField(Field.Builder builderForValue)
627 WriteFieldDocComment(printer, descriptor_, context_->options());
628 PrintNestedBuilderFunction(
629 printer,
630 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
631 " $type$.Builder builderForValue)",
632
633 "$oneof_name$_ = builderForValue.build();\n"
634 "$on_changed$\n",
635
636 "$name$Builder_.setMessage(builderForValue.build());\n",
637
638 "$set_oneof_case_message$;\n"
639 "return this;\n",
640 Semantic::kSet);
641
642 // Field.Builder mergeField(Field value)
643 WriteFieldDocComment(printer, descriptor_, context_->options());
644 PrintNestedBuilderFunction(
645 printer,
646 "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
647
648 "if ($has_oneof_case_message$ &&\n"
649 " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
650 " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
651 " .mergeFrom(value).buildPartial();\n"
652 "} else {\n"
653 " $oneof_name$_ = value;\n"
654 "}\n"
655 "$on_changed$\n",
656
657 "if ($has_oneof_case_message$) {\n"
658 " $name$Builder_.mergeFrom(value);\n"
659 "} else {\n"
660 " $name$Builder_.setMessage(value);\n"
661 "}\n",
662
663 "$set_oneof_case_message$;\n"
664 "return this;\n",
665 Semantic::kSet);
666
667 // Field.Builder clearField()
668 WriteFieldDocComment(printer, descriptor_, context_->options());
669 PrintNestedBuilderFunction(
670 printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
671
672 "if ($has_oneof_case_message$) {\n"
673 " $clear_oneof_case_message$;\n"
674 " $oneof_name$_ = null;\n"
675 " $on_changed$\n"
676 "}\n",
677
678 "if ($has_oneof_case_message$) {\n"
679 " $clear_oneof_case_message$;\n"
680 " $oneof_name$_ = null;\n"
681 "}\n"
682 "$name$Builder_.clear();\n",
683
684 "return this;\n", Semantic::kSet);
685
686 WriteFieldDocComment(printer, descriptor_, context_->options());
687 printer->Print(variables_,
688 "$deprecation$public $type$.Builder "
689 "${$get$capitalized_name$Builder$}$() {\n"
690 " return get$capitalized_name$FieldBuilder().getBuilder();\n"
691 "}\n");
692 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
693 WriteFieldDocComment(printer, descriptor_, context_->options());
694 printer->Print(
695 variables_,
696 "@java.lang.Override\n"
697 "$deprecation$public $type$OrBuilder "
698 "${$get$capitalized_name$OrBuilder$}$() {\n"
699 " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
700 " return $name$Builder_.getMessageOrBuilder();\n"
701 " } else {\n"
702 " if ($has_oneof_case_message$) {\n"
703 " return ($type$) $oneof_name$_;\n"
704 " }\n"
705 " return $type$.getDefaultInstance();\n"
706 " }\n"
707 "}\n");
708 printer->Annotate("{", "}", descriptor_);
709 WriteFieldDocComment(printer, descriptor_, context_->options());
710 printer->Print(
711 variables_,
712 "private com.google.protobuf.SingleFieldBuilder<\n"
713 " $type$, $type$.Builder, $type$OrBuilder> \n"
714 " ${$get$capitalized_name$FieldBuilder$}$() {\n"
715 " if ($name$Builder_ == null) {\n"
716 " if (!($has_oneof_case_message$)) {\n"
717 " $oneof_name$_ = $type$.getDefaultInstance();\n"
718 " }\n"
719 " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
720 " $type$, $type$.Builder, $type$OrBuilder>(\n"
721 " ($type$) $oneof_name$_,\n"
722 " getParentForChildren(),\n"
723 " isClean());\n"
724 " $oneof_name$_ = null;\n"
725 " }\n"
726 " $set_oneof_case_message$;\n"
727 " $on_changed$\n"
728 " return $name$Builder_;\n"
729 "}\n");
730 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
731 }
732
GenerateBuilderClearCode(io::Printer * printer) const733 void ImmutableMessageOneofFieldGenerator::GenerateBuilderClearCode(
734 io::Printer* printer) const {
735 // Make sure the builder gets cleared.
736 printer->Print(variables_,
737 "if ($name$Builder_ != null) {\n"
738 " $name$Builder_.clear();\n"
739 "}\n");
740 }
741
GenerateBuildingCode(io::Printer * printer) const742 void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode(
743 io::Printer* printer) const {
744 printer->Print(variables_,
745 "if ($has_oneof_case_message$ &&\n"
746 " $name$Builder_ != null) {\n"
747 " result.$oneof_name$_ = $name$Builder_.build();\n"
748 "}\n");
749 }
750
GenerateMergingCode(io::Printer * printer) const751 void ImmutableMessageOneofFieldGenerator::GenerateMergingCode(
752 io::Printer* printer) const {
753 printer->Print(variables_,
754 "merge$capitalized_name$(other.get$capitalized_name$());\n");
755 }
756
GenerateBuilderParsingCode(io::Printer * printer) const757 void ImmutableMessageOneofFieldGenerator::GenerateBuilderParsingCode(
758 io::Printer* printer) const {
759 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
760 printer->Print(variables_,
761 "input.readGroup($number$,\n"
762 " get$capitalized_name$FieldBuilder().getBuilder(),\n"
763 " extensionRegistry);\n"
764 "$set_oneof_case_message$;\n");
765 } else {
766 printer->Print(variables_,
767 "input.readMessage(\n"
768 " get$capitalized_name$FieldBuilder().getBuilder(),\n"
769 " extensionRegistry);\n"
770 "$set_oneof_case_message$;\n");
771 }
772 }
773
GenerateSerializationCode(io::Printer * printer) const774 void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode(
775 io::Printer* printer) const {
776 printer->Print(
777 variables_,
778 "if ($has_oneof_case_message$) {\n"
779 " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
780 "}\n");
781 }
782
GenerateSerializedSizeCode(io::Printer * printer) const783 void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
784 io::Printer* printer) const {
785 printer->Print(
786 variables_,
787 "if ($has_oneof_case_message$) {\n"
788 " size += com.google.protobuf.CodedOutputStream\n"
789 " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
790 "}\n");
791 }
792
793 // ===================================================================
794
RepeatedImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)795 RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator(
796 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
797 Context* context)
798 : ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
799 builderBitIndex, context) {}
800
801 RepeatedImmutableMessageFieldGenerator::
~RepeatedImmutableMessageFieldGenerator()802 ~RepeatedImmutableMessageFieldGenerator() {}
803
GetNumBitsForMessage() const804 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
805 return 0;
806 }
807
GetNumBitsForBuilder() const808 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
809 return 1;
810 }
811
GenerateInterfaceMembers(io::Printer * printer) const812 void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
813 io::Printer* printer) const {
814 // TODO: In the future, consider having methods specific to the
815 // interface so that builders can choose dynamically to either return a
816 // message or a nested builder, so that asking for the interface doesn't
817 // cause a message to ever be built.
818 WriteFieldDocComment(printer, descriptor_, context_->options());
819 printer->Print(variables_,
820 "$deprecation$java.util.List<$type$> \n"
821 " get$capitalized_name$List();\n");
822 WriteFieldDocComment(printer, descriptor_, context_->options());
823 printer->Print(variables_,
824 "$deprecation$$type$ get$capitalized_name$(int index);\n");
825 WriteFieldDocComment(printer, descriptor_, context_->options());
826 printer->Print(variables_,
827 "$deprecation$int get$capitalized_name$Count();\n");
828
829 WriteFieldDocComment(printer, descriptor_, context_->options());
830 printer->Print(variables_,
831 "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
832 " get$capitalized_name$OrBuilderList();\n");
833 WriteFieldDocComment(printer, descriptor_, context_->options());
834 printer->Print(
835 variables_,
836 "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
837 " int index);\n");
838 }
839
GenerateMembers(io::Printer * printer) const840 void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
841 io::Printer* printer) const {
842 printer->Print(variables_, "@SuppressWarnings(\"serial\")\n"
843 "private java.util.List<$type$> $name$_;\n");
844 PrintExtraFieldInfo(variables_, printer);
845 WriteFieldDocComment(printer, descriptor_, context_->options());
846 printer->Print(variables_,
847 "@java.lang.Override\n"
848 "$deprecation$public java.util.List<$type$> "
849 "${$get$capitalized_name$List$}$() {\n"
850 " return $name$_;\n" // note: unmodifiable list
851 "}\n");
852 printer->Annotate("{", "}", descriptor_);
853
854 // List<FieldOrBuilder> getFieldOrBuilderList()
855 WriteFieldDocComment(printer, descriptor_, context_->options());
856 printer->Print(
857 variables_,
858 "@java.lang.Override\n"
859 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
860 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
861 " return $name$_;\n"
862 "}\n");
863 printer->Annotate("{", "}", descriptor_);
864
865 // int getFieldCount()
866 WriteFieldDocComment(printer, descriptor_, context_->options());
867 printer->Print(
868 variables_,
869 "@java.lang.Override\n"
870 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
871 " return $name$_.size();\n"
872 "}\n");
873 printer->Annotate("{", "}", descriptor_);
874
875 // Field getField(int index)
876 WriteFieldDocComment(printer, descriptor_, context_->options());
877 printer->Print(
878 variables_,
879 "@java.lang.Override\n"
880 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
881 " return $name$_.get(index);\n"
882 "}\n");
883 printer->Annotate("{", "}", descriptor_);
884
885 // FieldOrBuilder getFieldOrBuilder(int index)
886 WriteFieldDocComment(printer, descriptor_, context_->options());
887 printer->Print(variables_,
888 "@java.lang.Override\n"
889 "$deprecation$public $type$OrBuilder "
890 "${$get$capitalized_name$OrBuilder$}$(\n"
891 " int index) {\n"
892 " return $name$_.get(index);\n"
893 "}\n");
894 printer->Annotate("{", "}", descriptor_);
895 }
896
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const897 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
898 io::Printer* printer, const char* regular_case,
899 const char* nested_builder_case) const {
900 printer->Print(variables_, "if ($name$Builder_ == null) {\n");
901 printer->Indent();
902 printer->Print(variables_, regular_case);
903 printer->Outdent();
904 printer->Print("} else {\n");
905 printer->Indent();
906 printer->Print(variables_, nested_builder_case);
907 printer->Outdent();
908 printer->Print("}\n");
909 }
910
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code,absl::optional<io::AnnotationCollector::Semantic> semantic) const911 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
912 io::Printer* printer, const char* method_prototype,
913 const char* regular_case, const char* nested_builder_case,
914 const char* trailing_code,
915 absl::optional<io::AnnotationCollector::Semantic> semantic) const {
916 printer->Print(variables_, method_prototype);
917 printer->Annotate("{", "}", descriptor_, semantic);
918 printer->Print(" {\n");
919 printer->Indent();
920 PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
921 if (trailing_code != NULL) {
922 printer->Print(variables_, trailing_code);
923 }
924 printer->Outdent();
925 printer->Print("}\n");
926 }
927
GenerateBuilderMembers(io::Printer * printer) const928 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
929 io::Printer* printer) const {
930 // When using nested-builders, the code initially works just like the
931 // non-nested builder case. It only creates a nested builder lazily on
932 // demand and then forever delegates to it after creation.
933
934 printer->Print(
935 variables_,
936 // Used when the builder is null.
937 // One field is the list and the other field keeps track of whether the
938 // list is immutable. If it's immutable, the invariant is that it must
939 // either an instance of Collections.emptyList() or it's an ArrayList
940 // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
941 // a reference to the underlying ArrayList. This invariant allows us to
942 // share instances of lists between protocol buffers avoiding expensive
943 // memory allocations. Note, immutable is a strong guarantee here -- not
944 // just that the list cannot be modified via the reference but that the
945 // list can never be modified.
946 "private java.util.List<$type$> $name$_ =\n"
947 " java.util.Collections.emptyList();\n"
948
949 "private void ensure$capitalized_name$IsMutable() {\n"
950 " if (!$get_mutable_bit_builder$) {\n"
951 " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
952 " $set_mutable_bit_builder$;\n"
953 " }\n"
954 "}\n"
955 "\n");
956
957 printer->Print(
958 variables_,
959 // If this builder is non-null, it is used and the other fields are
960 // ignored.
961 "private com.google.protobuf.RepeatedFieldBuilder<\n"
962 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
963 "\n");
964
965 // The comments above the methods below are based on a hypothetical
966 // repeated field of type "Field" called "RepeatedField".
967
968 // List<Field> getRepeatedFieldList()
969 WriteFieldDocComment(printer, descriptor_, context_->options());
970 PrintNestedBuilderFunction(
971 printer,
972 "$deprecation$public java.util.List<$type$> "
973 "${$get$capitalized_name$List$}$()",
974
975 "return java.util.Collections.unmodifiableList($name$_);\n",
976 "return $name$Builder_.getMessageList();\n",
977
978 nullptr);
979
980 // int getRepeatedFieldCount()
981 WriteFieldDocComment(printer, descriptor_, context_->options());
982 PrintNestedBuilderFunction(
983 printer, "$deprecation$public int ${$get$capitalized_name$Count$}$()",
984
985 "return $name$_.size();\n", "return $name$Builder_.getCount();\n",
986
987 nullptr);
988
989 // Field getRepeatedField(int index)
990 WriteFieldDocComment(printer, descriptor_, context_->options());
991 PrintNestedBuilderFunction(
992 printer,
993 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)",
994
995 "return $name$_.get(index);\n",
996
997 "return $name$Builder_.getMessage(index);\n",
998
999 nullptr);
1000
1001 // Builder setRepeatedField(int index, Field value)
1002 WriteFieldDocComment(printer, descriptor_, context_->options());
1003 PrintNestedBuilderFunction(
1004 printer,
1005 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1006 " int index, $type$ value)",
1007 "if (value == null) {\n"
1008 " throw new NullPointerException();\n"
1009 "}\n"
1010 "ensure$capitalized_name$IsMutable();\n"
1011 "$name$_.set(index, value);\n"
1012 "$on_changed$\n",
1013 "$name$Builder_.setMessage(index, value);\n", "return this;\n",
1014 Semantic::kSet);
1015
1016 // Builder setRepeatedField(int index, Field.Builder builderForValue)
1017 WriteFieldDocComment(printer, descriptor_, context_->options());
1018 PrintNestedBuilderFunction(
1019 printer,
1020 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1021 " int index, $type$.Builder builderForValue)",
1022
1023 "ensure$capitalized_name$IsMutable();\n"
1024 "$name$_.set(index, builderForValue.build());\n"
1025 "$on_changed$\n",
1026
1027 "$name$Builder_.setMessage(index, builderForValue.build());\n",
1028
1029 "return this;\n", Semantic::kSet);
1030
1031 // Builder addRepeatedField(Field value)
1032 WriteFieldDocComment(printer, descriptor_, context_->options());
1033 PrintNestedBuilderFunction(
1034 printer,
1035 "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)",
1036
1037 "if (value == null) {\n"
1038 " throw new NullPointerException();\n"
1039 "}\n"
1040 "ensure$capitalized_name$IsMutable();\n"
1041 "$name$_.add(value);\n"
1042
1043 "$on_changed$\n",
1044
1045 "$name$Builder_.addMessage(value);\n",
1046
1047 "return this;\n", Semantic::kSet);
1048
1049 // Builder addRepeatedField(int index, Field value)
1050 WriteFieldDocComment(printer, descriptor_, context_->options());
1051 PrintNestedBuilderFunction(
1052 printer,
1053 "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1054 " int index, $type$ value)",
1055
1056 "if (value == null) {\n"
1057 " throw new NullPointerException();\n"
1058 "}\n"
1059 "ensure$capitalized_name$IsMutable();\n"
1060 "$name$_.add(index, value);\n"
1061 "$on_changed$\n",
1062
1063 "$name$Builder_.addMessage(index, value);\n",
1064
1065 "return this;\n", Semantic::kSet);
1066
1067 // Builder addRepeatedField(Field.Builder builderForValue)
1068 WriteFieldDocComment(printer, descriptor_, context_->options());
1069 PrintNestedBuilderFunction(
1070 printer,
1071 "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1072 " $type$.Builder builderForValue)",
1073
1074 "ensure$capitalized_name$IsMutable();\n"
1075 "$name$_.add(builderForValue.build());\n"
1076 "$on_changed$\n",
1077
1078 "$name$Builder_.addMessage(builderForValue.build());\n",
1079
1080 "return this;\n", Semantic::kSet);
1081
1082 // Builder addRepeatedField(int index, Field.Builder builderForValue)
1083 WriteFieldDocComment(printer, descriptor_, context_->options());
1084 PrintNestedBuilderFunction(
1085 printer,
1086 "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1087 " int index, $type$.Builder builderForValue)",
1088
1089 "ensure$capitalized_name$IsMutable();\n"
1090 "$name$_.add(index, builderForValue.build());\n"
1091 "$on_changed$\n",
1092
1093 "$name$Builder_.addMessage(index, builderForValue.build());\n",
1094
1095 "return this;\n", Semantic::kSet);
1096
1097 // Builder addAllRepeatedField(Iterable<Field> values)
1098 WriteFieldDocComment(printer, descriptor_, context_->options());
1099 PrintNestedBuilderFunction(
1100 printer,
1101 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
1102 " java.lang.Iterable<? extends $type$> values)",
1103
1104 "ensure$capitalized_name$IsMutable();\n"
1105 "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
1106 " values, $name$_);\n"
1107 "$on_changed$\n",
1108
1109 "$name$Builder_.addAllMessages(values);\n",
1110
1111 "return this;\n", Semantic::kSet);
1112
1113 // Builder clearRepeatedField()
1114 WriteFieldDocComment(printer, descriptor_, context_->options());
1115 PrintNestedBuilderFunction(
1116 printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
1117
1118 "$name$_ = java.util.Collections.emptyList();\n"
1119 "$clear_mutable_bit_builder$;\n"
1120 "$on_changed$\n",
1121
1122 "$name$Builder_.clear();\n",
1123
1124 "return this;\n", Semantic::kSet);
1125
1126 // Builder removeRepeatedField(int index)
1127 WriteFieldDocComment(printer, descriptor_, context_->options());
1128 PrintNestedBuilderFunction(
1129 printer,
1130 "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
1131
1132 "ensure$capitalized_name$IsMutable();\n"
1133 "$name$_.remove(index);\n"
1134 "$on_changed$\n",
1135
1136 "$name$Builder_.remove(index);\n",
1137
1138 "return this;\n", Semantic::kSet);
1139
1140 // Field.Builder getRepeatedFieldBuilder(int index)
1141 WriteFieldDocComment(printer, descriptor_, context_->options());
1142 printer->Print(
1143 variables_,
1144 "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n"
1145 " int index) {\n"
1146 " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
1147 "}\n");
1148 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
1149
1150 // FieldOrBuilder getRepeatedFieldOrBuilder(int index)
1151 WriteFieldDocComment(printer, descriptor_, context_->options());
1152 printer->Print(variables_,
1153 "$deprecation$public $type$OrBuilder "
1154 "${$get$capitalized_name$OrBuilder$}$(\n"
1155 " int index) {\n"
1156 " if ($name$Builder_ == null) {\n"
1157 " return $name$_.get(index);"
1158 " } else {\n"
1159 " return $name$Builder_.getMessageOrBuilder(index);\n"
1160 " }\n"
1161 "}\n");
1162 printer->Annotate("{", "}", descriptor_);
1163
1164 // List<FieldOrBuilder> getRepeatedFieldOrBuilderList()
1165 WriteFieldDocComment(printer, descriptor_, context_->options());
1166 printer->Print(
1167 variables_,
1168 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
1169 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
1170 " if ($name$Builder_ != null) {\n"
1171 " return $name$Builder_.getMessageOrBuilderList();\n"
1172 " } else {\n"
1173 " return java.util.Collections.unmodifiableList($name$_);\n"
1174 " }\n"
1175 "}\n");
1176 printer->Annotate("{", "}", descriptor_);
1177
1178 // Field.Builder addRepeatedField()
1179 WriteFieldDocComment(printer, descriptor_, context_->options());
1180 printer->Print(variables_,
1181 "$deprecation$public $type$.Builder "
1182 "${$add$capitalized_name$Builder$}$() {\n"
1183 " return get$capitalized_name$FieldBuilder().addBuilder(\n"
1184 " $type$.getDefaultInstance());\n"
1185 "}\n");
1186 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
1187
1188 // Field.Builder addRepeatedFieldBuilder(int index)
1189 WriteFieldDocComment(printer, descriptor_, context_->options());
1190 printer->Print(
1191 variables_,
1192 "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
1193 " int index) {\n"
1194 " return get$capitalized_name$FieldBuilder().addBuilder(\n"
1195 " index, $type$.getDefaultInstance());\n"
1196 "}\n");
1197 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
1198
1199 // List<Field.Builder> getRepeatedFieldBuilderList()
1200 WriteFieldDocComment(printer, descriptor_, context_->options());
1201 printer->Print(
1202 variables_,
1203 "$deprecation$public java.util.List<$type$.Builder> \n"
1204 " ${$get$capitalized_name$BuilderList$}$() {\n"
1205 " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
1206 "}\n"
1207 "private com.google.protobuf.RepeatedFieldBuilder<\n"
1208 " $type$, $type$.Builder, $type$OrBuilder> \n"
1209 " get$capitalized_name$FieldBuilder() {\n"
1210 " if ($name$Builder_ == null) {\n"
1211 " $name$Builder_ = new "
1212 "com.google.protobuf.RepeatedFieldBuilder<\n"
1213 " $type$, $type$.Builder, $type$OrBuilder>(\n"
1214 " $name$_,\n"
1215 " $get_mutable_bit_builder$,\n"
1216 " getParentForChildren(),\n"
1217 " isClean());\n"
1218 " $name$_ = null;\n"
1219 " }\n"
1220 " return $name$Builder_;\n"
1221 "}\n");
1222 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
1223 }
1224
1225 void RepeatedImmutableMessageFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const1226 GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
1227 printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
1228 }
1229
GenerateInitializationCode(io::Printer * printer) const1230 void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
1231 io::Printer* printer) const {
1232 printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
1233 }
1234
GenerateBuilderClearCode(io::Printer * printer) const1235 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
1236 io::Printer* printer) const {
1237 PrintNestedBuilderCondition(printer,
1238 "$name$_ = java.util.Collections.emptyList();\n",
1239
1240 "$name$_ = null;\n"
1241 "$name$Builder_.clear();\n");
1242
1243 printer->Print(variables_, "$clear_mutable_bit_builder$;\n");
1244 }
1245
GenerateMergingCode(io::Printer * printer) const1246 void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
1247 io::Printer* printer) const {
1248 // The code below does two optimizations (non-nested builder case):
1249 // 1. If the other list is empty, there's nothing to do. This ensures we
1250 // don't allocate a new array if we already have an immutable one.
1251 // 2. If the other list is non-empty and our current list is empty, we can
1252 // reuse the other list which is guaranteed to be immutable.
1253 PrintNestedBuilderCondition(
1254 printer,
1255 "if (!other.$name$_.isEmpty()) {\n"
1256 " if ($name$_.isEmpty()) {\n"
1257 " $name$_ = other.$name$_;\n"
1258 " $clear_mutable_bit_builder$;\n"
1259 " } else {\n"
1260 " ensure$capitalized_name$IsMutable();\n"
1261 " $name$_.addAll(other.$name$_);\n"
1262 " }\n"
1263 " $on_changed$\n"
1264 "}\n",
1265
1266 "if (!other.$name$_.isEmpty()) {\n"
1267 " if ($name$Builder_.isEmpty()) {\n"
1268 " $name$Builder_.dispose();\n"
1269 " $name$Builder_ = null;\n"
1270 " $name$_ = other.$name$_;\n"
1271 " $clear_mutable_bit_builder$;\n"
1272 " $name$Builder_ = \n"
1273 " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders "
1274 "?\n"
1275 " get$capitalized_name$FieldBuilder() : null;\n"
1276 " } else {\n"
1277 " $name$Builder_.addAllMessages(other.$name$_);\n"
1278 " }\n"
1279 "}\n");
1280 }
1281
GenerateBuildingCode(io::Printer * printer) const1282 void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode(
1283 io::Printer* printer) const {
1284 // The code below (non-nested builder case) ensures that the result has an
1285 // immutable list. If our list is immutable, we can just reuse it. If not,
1286 // we make it immutable.
1287 PrintNestedBuilderCondition(
1288 printer,
1289 "if ($get_mutable_bit_builder$) {\n"
1290 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1291 " $clear_mutable_bit_builder$;\n"
1292 "}\n"
1293 "result.$name$_ = $name$_;\n",
1294
1295 "result.$name$_ = $name$Builder_.build();\n");
1296 }
1297
GenerateBuilderParsingCode(io::Printer * printer) const1298 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode(
1299 io::Printer* printer) const {
1300 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
1301 printer->Print(variables_,
1302 "$type$ m =\n"
1303 " input.readGroup($number$,\n"
1304 " $type$.$get_parser$,\n"
1305 " extensionRegistry);\n");
1306 } else {
1307 printer->Print(variables_,
1308 "$type$ m =\n"
1309 " input.readMessage(\n"
1310 " $type$.$get_parser$,\n"
1311 " extensionRegistry);\n");
1312 }
1313 PrintNestedBuilderCondition(printer,
1314 "ensure$capitalized_name$IsMutable();\n"
1315 "$name$_.add(m);\n",
1316 "$name$Builder_.addMessage(m);\n");
1317 }
1318
GenerateSerializationCode(io::Printer * printer) const1319 void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
1320 io::Printer* printer) const {
1321 printer->Print(variables_,
1322 "for (int i = 0; i < $name$_.size(); i++) {\n"
1323 " output.write$group_or_message$($number$, $name$_.get(i));\n"
1324 "}\n");
1325 }
1326
GenerateSerializedSizeCode(io::Printer * printer) const1327 void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
1328 io::Printer* printer) const {
1329 printer->Print(
1330 variables_,
1331 "for (int i = 0; i < $name$_.size(); i++) {\n"
1332 " size += com.google.protobuf.CodedOutputStream\n"
1333 " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
1334 "}\n");
1335 }
1336
GenerateEqualsCode(io::Printer * printer) const1337 void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode(
1338 io::Printer* printer) const {
1339 printer->Print(
1340 variables_,
1341 "if (!get$capitalized_name$List()\n"
1342 " .equals(other.get$capitalized_name$List())) return false;\n");
1343 }
1344
GenerateHashCode(io::Printer * printer) const1345 void RepeatedImmutableMessageFieldGenerator::GenerateHashCode(
1346 io::Printer* printer) const {
1347 printer->Print(
1348 variables_,
1349 "if (get$capitalized_name$Count() > 0) {\n"
1350 " hash = (37 * hash) + $constant_name$;\n"
1351 " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
1352 "}\n");
1353 }
1354
GetBoxedType() const1355 std::string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
1356 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
1357 }
1358
GenerateKotlinDslMembers(io::Printer * printer) const1359 void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers(
1360 io::Printer* printer) const {
1361 printer->Print(
1362 variables_,
1363 "/**\n"
1364 " * An uninstantiable, behaviorless type to represent the field in\n"
1365 " * generics.\n"
1366 " */\n"
1367 "@kotlin.OptIn"
1368 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
1369 "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
1370 " : com.google.protobuf.kotlin.DslProxy()\n");
1371
1372 WriteFieldDocComment(printer, descriptor_, context_->options(),
1373 /* kdoc */ true);
1374 printer->Print(variables_,
1375 "$kt_deprecation$ public val $kt_name$: "
1376 "com.google.protobuf.kotlin.DslList"
1377 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1378 " @kotlin.jvm.JvmSynthetic\n"
1379 " get() = com.google.protobuf.kotlin.DslList(\n"
1380 " $kt_dsl_builder$.${$$kt_property_name$List$}$\n"
1381 " )\n");
1382
1383 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
1384 context_->options(),
1385 /* builder */ false, /* kdoc */ true);
1386 printer->Print(variables_,
1387 "@kotlin.jvm.JvmSynthetic\n"
1388 "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
1389 "public fun com.google.protobuf.kotlin.DslList"
1390 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1391 "add(value: $kt_type$) {\n"
1392 " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
1393 "}\n");
1394
1395 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
1396 context_->options(),
1397 /* builder */ false, /* kdoc */ true);
1398 printer->Print(variables_,
1399 "@kotlin.jvm.JvmSynthetic\n"
1400 "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
1401 "@Suppress(\"NOTHING_TO_INLINE\")\n"
1402 "public inline operator fun com.google.protobuf.kotlin.DslList"
1403 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1404 "plusAssign(value: $kt_type$) {\n"
1405 " add(value)\n"
1406 "}\n");
1407
1408 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
1409 context_->options(),
1410 /* builder */ false, /* kdoc */ true);
1411 printer->Print(variables_,
1412 "@kotlin.jvm.JvmSynthetic\n"
1413 "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
1414 "public fun com.google.protobuf.kotlin.DslList"
1415 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1416 "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
1417 " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
1418 "}\n");
1419
1420 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
1421 context_->options(),
1422 /* builder */ false, /* kdoc */ true);
1423 printer->Print(
1424 variables_,
1425 "@kotlin.jvm.JvmSynthetic\n"
1426 "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
1427 "@Suppress(\"NOTHING_TO_INLINE\")\n"
1428 "public inline operator fun com.google.protobuf.kotlin.DslList"
1429 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1430 "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
1431 " addAll(values)\n"
1432 "}\n");
1433
1434 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
1435 context_->options(),
1436 /* builder */ false, /* kdoc */ true);
1437 printer->Print(
1438 variables_,
1439 "@kotlin.jvm.JvmSynthetic\n"
1440 "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
1441 "public operator fun com.google.protobuf.kotlin.DslList"
1442 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1443 "set(index: kotlin.Int, value: $kt_type$) {\n"
1444 " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
1445 "}\n");
1446
1447 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
1448 context_->options(),
1449 /* builder */ false, /* kdoc */ true);
1450 printer->Print(variables_,
1451 "@kotlin.jvm.JvmSynthetic\n"
1452 "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
1453 "public fun com.google.protobuf.kotlin.DslList"
1454 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1455 "clear() {\n"
1456 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
1457 "}\n\n");
1458 }
1459
1460 } // namespace java
1461 } // namespace compiler
1462 } // namespace protobuf
1463 } // namespace google
1464
1465 #include "google/protobuf/port_undef.inc"
1466