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