1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <map>
36 #include <string>
37
38 #include <google/protobuf/compiler/java/java_context.h>
39 #include <google/protobuf/compiler/java/java_doc_comment.h>
40 #include <google/protobuf/compiler/java/java_helpers.h>
41 #include <google/protobuf/compiler/java/java_message_field.h>
42 #include <google/protobuf/compiler/java/java_name_resolver.h>
43 #include <google/protobuf/io/printer.h>
44 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/stubs/strutil.h>
46
47 namespace google {
48 namespace protobuf {
49 namespace compiler {
50 namespace java {
51
52 namespace {
53
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)54 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
55 int builderBitIndex, const FieldGeneratorInfo* info,
56 ClassNameResolver* name_resolver,
57 std::map<std::string, std::string>* variables) {
58 SetCommonFieldVariables(descriptor, info, variables);
59
60 (*variables)["type"] =
61 name_resolver->GetImmutableClassName(descriptor->message_type());
62 (*variables)["mutable_type"] =
63 name_resolver->GetMutableClassName(descriptor->message_type());
64 (*variables)["group_or_message"] =
65 (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
66 : "Message";
67 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
68 // by the proto compiler
69 (*variables)["deprecation"] =
70 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
71 (*variables)["on_changed"] = "onChanged();";
72 (*variables)["ver"] = GeneratedCodeVersionSuffix();
73 (*variables)["get_parser"] =
74 ExposePublicParser(descriptor->message_type()->file()) ? "PARSER"
75 : "parser()";
76
77 if (HasHasbit(descriptor)) {
78 // For singular messages and builders, one bit is used for the hasField bit.
79 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
80 (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
81
82 // Note that these have a trailing ";".
83 (*variables)["set_has_field_bit_message"] =
84 GenerateSetBit(messageBitIndex) + ";";
85 (*variables)["set_has_field_bit_builder"] =
86 GenerateSetBit(builderBitIndex) + ";";
87 (*variables)["clear_has_field_bit_builder"] =
88 GenerateClearBit(builderBitIndex) + ";";
89
90 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
91 } else {
92 (*variables)["set_has_field_bit_message"] = "";
93 (*variables)["set_has_field_bit_builder"] = "";
94 (*variables)["clear_has_field_bit_builder"] = "";
95
96 (*variables)["is_field_present_message"] =
97 (*variables)["name"] + "_ != null";
98 }
99
100 // For repeated builders, one bit is used for whether the array is immutable.
101 (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
102 (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
103 (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
104
105 // For repeated fields, one bit is used for whether the array is immutable
106 // in the parsing constructor.
107 (*variables)["get_mutable_bit_parser"] =
108 GenerateGetBitMutableLocal(builderBitIndex);
109 (*variables)["set_mutable_bit_parser"] =
110 GenerateSetBitMutableLocal(builderBitIndex);
111
112 (*variables)["get_has_field_bit_from_local"] =
113 GenerateGetBitFromLocal(builderBitIndex);
114 (*variables)["set_has_field_bit_to_local"] =
115 GenerateSetBitToLocal(messageBitIndex);
116 }
117
118 } // namespace
119
120 // ===================================================================
121
ImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)122 ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator(
123 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
124 Context* context)
125 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
126 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
127 context->GetFieldGeneratorInfo(descriptor),
128 name_resolver_, &variables_);
129 }
130
~ImmutableMessageFieldGenerator()131 ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
132
GetNumBitsForMessage() const133 int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
134 return HasHasbit(descriptor_) ? 1 : 0;
135 }
136
GetNumBitsForBuilder() const137 int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
138 return GetNumBitsForMessage();
139 }
140
GenerateInterfaceMembers(io::Printer * printer) const141 void ImmutableMessageFieldGenerator::GenerateInterfaceMembers(
142 io::Printer* printer) const {
143 // TODO(jonp): In the future, consider having a method specific to the
144 // interface so that builders can choose dynamically to either return a
145 // message or a nested builder, so that asking for the interface doesn't
146 // cause a message to ever be built.
147 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
148 printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
149 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
150 printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
151
152 WriteFieldDocComment(printer, descriptor_);
153 printer->Print(
154 variables_,
155 "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
156 }
157
GenerateMembers(io::Printer * printer) const158 void ImmutableMessageFieldGenerator::GenerateMembers(
159 io::Printer* printer) const {
160 printer->Print(variables_, "private $type$ $name$_;\n");
161 PrintExtraFieldInfo(variables_, printer);
162
163 if (HasHasbit(descriptor_)) {
164 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
165 printer->Print(
166 variables_,
167 "@java.lang.Override\n"
168 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
169 " return $get_has_field_bit_message$;\n"
170 "}\n");
171 printer->Annotate("{", "}", descriptor_);
172 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
173 printer->Print(
174 variables_,
175 "@java.lang.Override\n"
176 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
177 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
178 "}\n");
179 printer->Annotate("{", "}", descriptor_);
180
181 WriteFieldDocComment(printer, descriptor_);
182 printer->Print(
183 variables_,
184 "@java.lang.Override\n"
185 "$deprecation$public $type$OrBuilder "
186 "${$get$capitalized_name$OrBuilder$}$() {\n"
187 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
188 "}\n");
189 printer->Annotate("{", "}", descriptor_);
190 } else {
191 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
192 printer->Print(
193 variables_,
194 "@java.lang.Override\n"
195 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
196 " return $name$_ != null;\n"
197 "}\n");
198 printer->Annotate("{", "}", descriptor_);
199 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
200 printer->Print(
201 variables_,
202 "@java.lang.Override\n"
203 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
204 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
205 "}\n");
206 printer->Annotate("{", "}", descriptor_);
207
208 WriteFieldDocComment(printer, descriptor_);
209 printer->Print(variables_,
210 "@java.lang.Override\n"
211 "$deprecation$public $type$OrBuilder "
212 "${$get$capitalized_name$OrBuilder$}$() {\n"
213 " return get$capitalized_name$();\n"
214 "}\n");
215 printer->Annotate("{", "}", descriptor_);
216 }
217 }
218
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const219 void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
220 io::Printer* printer, const char* regular_case,
221 const char* nested_builder_case) const {
222 printer->Print(variables_, "if ($name$Builder_ == null) {\n");
223 printer->Indent();
224 printer->Print(variables_, regular_case);
225 printer->Outdent();
226 printer->Print("} else {\n");
227 printer->Indent();
228 printer->Print(variables_, nested_builder_case);
229 printer->Outdent();
230 printer->Print("}\n");
231 }
232
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const233 void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
234 io::Printer* printer, const char* method_prototype,
235 const char* regular_case, const char* nested_builder_case,
236 const char* trailing_code) const {
237 printer->Print(variables_, method_prototype);
238 printer->Annotate("{", "}", descriptor_);
239 printer->Print(" {\n");
240 printer->Indent();
241 PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
242 if (trailing_code != NULL) {
243 printer->Print(variables_, trailing_code);
244 }
245 printer->Outdent();
246 printer->Print("}\n");
247 }
248
GenerateBuilderMembers(io::Printer * printer) const249 void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
250 io::Printer* printer) const {
251 // When using nested-builders, the code initially works just like the
252 // non-nested builder case. It only creates a nested builder lazily on
253 // demand and then forever delegates to it after creation.
254
255 bool has_hasbit = HasHasbit(descriptor_);
256
257 printer->Print(variables_, "private $type$ $name$_;\n");
258
259 printer->Print(variables_,
260 // If this builder is non-null, it is used and the other fields
261 // are ignored.
262 "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
263 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
264 "\n");
265
266 // The comments above the methods below are based on a hypothetical
267 // field of type "Field" called "Field".
268
269 // boolean hasField()
270 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
271 if (has_hasbit) {
272 printer->Print(
273 variables_,
274 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
275 " return $get_has_field_bit_builder$;\n"
276 "}\n");
277 printer->Annotate("{", "}", descriptor_);
278 } else {
279 printer->Print(
280 variables_,
281 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
282 " return $name$Builder_ != null || $name$_ != null;\n"
283 "}\n");
284 printer->Annotate("{", "}", descriptor_);
285 }
286
287 // Field getField()
288 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
289 PrintNestedBuilderFunction(
290 printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
291 "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
292 "return $name$Builder_.getMessage();\n", NULL);
293
294 // Field.Builder setField(Field value)
295 WriteFieldDocComment(printer, descriptor_);
296 PrintNestedBuilderFunction(
297 printer,
298 "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
299
300 "if (value == null) {\n"
301 " throw new NullPointerException();\n"
302 "}\n"
303 "$name$_ = value;\n"
304 "$on_changed$\n",
305
306 "$name$Builder_.setMessage(value);\n",
307
308 "$set_has_field_bit_builder$\n"
309 "return this;\n");
310
311 // Field.Builder setField(Field.Builder builderForValue)
312 WriteFieldDocComment(printer, descriptor_);
313 PrintNestedBuilderFunction(
314 printer,
315 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
316 " $type$.Builder builderForValue)",
317
318 "$name$_ = builderForValue.build();\n"
319 "$on_changed$\n",
320
321 "$name$Builder_.setMessage(builderForValue.build());\n",
322
323 "$set_has_field_bit_builder$\n"
324 "return this;\n");
325
326 // Field.Builder mergeField(Field value)
327 WriteFieldDocComment(printer, descriptor_);
328 PrintNestedBuilderFunction(
329 printer,
330 "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
331
332 has_hasbit
333 ? "if ($get_has_field_bit_builder$ &&\n"
334 " $name$_ != null &&\n"
335 " $name$_ != $type$.getDefaultInstance()) {\n"
336 " $name$_ =\n"
337 " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
338 "} else {\n"
339 " $name$_ = value;\n"
340 "}\n"
341 "$on_changed$\n"
342 : "if ($name$_ != null) {\n"
343 " $name$_ =\n"
344 " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
345 "} else {\n"
346 " $name$_ = value;\n"
347 "}\n"
348 "$on_changed$\n",
349
350 "$name$Builder_.mergeFrom(value);\n",
351
352 "$set_has_field_bit_builder$\n"
353 "return this;\n");
354
355 // Field.Builder clearField()
356 WriteFieldDocComment(printer, descriptor_);
357 PrintNestedBuilderFunction(
358 printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
359
360 "$name$_ = null;\n"
361 "$on_changed$\n",
362
363 has_hasbit ? "$name$Builder_.clear();\n"
364 : "$name$_ = null;\n"
365 "$name$Builder_ = null;\n",
366
367 "$clear_has_field_bit_builder$\n"
368 "return this;\n");
369
370 WriteFieldDocComment(printer, descriptor_);
371 printer->Print(variables_,
372 "$deprecation$public $type$.Builder "
373 "${$get$capitalized_name$Builder$}$() {\n"
374 " $set_has_field_bit_builder$\n"
375 " $on_changed$\n"
376 " return get$capitalized_name$FieldBuilder().getBuilder();\n"
377 "}\n");
378 printer->Annotate("{", "}", descriptor_);
379 WriteFieldDocComment(printer, descriptor_);
380 printer->Print(variables_,
381 "$deprecation$public $type$OrBuilder "
382 "${$get$capitalized_name$OrBuilder$}$() {\n"
383 " if ($name$Builder_ != null) {\n"
384 " return $name$Builder_.getMessageOrBuilder();\n"
385 " } else {\n"
386 " return $name$_ == null ?\n"
387 " $type$.getDefaultInstance() : $name$_;\n"
388 " }\n"
389 "}\n");
390 printer->Annotate("{", "}", descriptor_);
391 WriteFieldDocComment(printer, descriptor_);
392 printer->Print(
393 variables_,
394 "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
395 " $type$, $type$.Builder, $type$OrBuilder> \n"
396 " get$capitalized_name$FieldBuilder() {\n"
397 " if ($name$Builder_ == null) {\n"
398 " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
399 " $type$, $type$.Builder, $type$OrBuilder>(\n"
400 " get$capitalized_name$(),\n"
401 " getParentForChildren(),\n"
402 " isClean());\n"
403 " $name$_ = null;\n"
404 " }\n"
405 " return $name$Builder_;\n"
406 "}\n");
407 }
408
GenerateFieldBuilderInitializationCode(io::Printer * printer) const409 void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode(
410 io::Printer* printer) const {
411 if (HasHasbit(descriptor_)) {
412 printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
413 }
414 }
415
GenerateInitializationCode(io::Printer * printer) const416 void ImmutableMessageFieldGenerator::GenerateInitializationCode(
417 io::Printer* printer) const {}
418
GenerateBuilderClearCode(io::Printer * printer) const419 void ImmutableMessageFieldGenerator::GenerateBuilderClearCode(
420 io::Printer* printer) const {
421 if (HasHasbit(descriptor_)) {
422 PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
423
424 "$name$Builder_.clear();\n");
425 printer->Print(variables_, "$clear_has_field_bit_builder$\n");
426 } else {
427 PrintNestedBuilderCondition(printer, "$name$_ = null;\n",
428
429 "$name$_ = null;\n"
430 "$name$Builder_ = null;\n");
431 }
432 }
433
GenerateMergingCode(io::Printer * printer) const434 void ImmutableMessageFieldGenerator::GenerateMergingCode(
435 io::Printer* printer) const {
436 printer->Print(variables_,
437 "if (other.has$capitalized_name$()) {\n"
438 " merge$capitalized_name$(other.get$capitalized_name$());\n"
439 "}\n");
440 }
441
GenerateBuildingCode(io::Printer * printer) const442 void ImmutableMessageFieldGenerator::GenerateBuildingCode(
443 io::Printer* printer) const {
444 if (HasHasbit(descriptor_)) {
445 printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n");
446 printer->Indent();
447 PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
448 "result.$name$_ = $name$Builder_.build();\n");
449 printer->Outdent();
450 printer->Print(variables_,
451 " $set_has_field_bit_to_local$;\n"
452 "}\n");
453 } else {
454 PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n",
455 "result.$name$_ = $name$Builder_.build();\n");
456 }
457 }
458
GenerateParsingCode(io::Printer * printer) const459 void ImmutableMessageFieldGenerator::GenerateParsingCode(
460 io::Printer* printer) const {
461 printer->Print(variables_,
462 "$type$.Builder subBuilder = null;\n"
463 "if ($is_field_present_message$) {\n"
464 " subBuilder = $name$_.toBuilder();\n"
465 "}\n");
466
467 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
468 printer->Print(variables_,
469 "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
470 " extensionRegistry);\n");
471 } else {
472 printer->Print(variables_,
473 "$name$_ = input.readMessage($type$.$get_parser$, "
474 "extensionRegistry);\n");
475 }
476
477 printer->Print(variables_,
478 "if (subBuilder != null) {\n"
479 " subBuilder.mergeFrom($name$_);\n"
480 " $name$_ = subBuilder.buildPartial();\n"
481 "}\n"
482 "$set_has_field_bit_message$\n");
483 }
484
GenerateParsingDoneCode(io::Printer * printer) const485 void ImmutableMessageFieldGenerator::GenerateParsingDoneCode(
486 io::Printer* printer) const {
487 // noop for messages.
488 }
489
GenerateSerializationCode(io::Printer * printer) const490 void ImmutableMessageFieldGenerator::GenerateSerializationCode(
491 io::Printer* printer) const {
492 printer->Print(
493 variables_,
494 "if ($is_field_present_message$) {\n"
495 " output.write$group_or_message$($number$, get$capitalized_name$());\n"
496 "}\n");
497 }
498
GenerateSerializedSizeCode(io::Printer * printer) const499 void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
500 io::Printer* printer) const {
501 printer->Print(
502 variables_,
503 "if ($is_field_present_message$) {\n"
504 " size += com.google.protobuf.CodedOutputStream\n"
505 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
506 "}\n");
507 }
508
GenerateEqualsCode(io::Printer * printer) const509 void ImmutableMessageFieldGenerator::GenerateEqualsCode(
510 io::Printer* printer) const {
511 printer->Print(variables_,
512 "if (!get$capitalized_name$()\n"
513 " .equals(other.get$capitalized_name$())) return false;\n");
514 }
515
GenerateHashCode(io::Printer * printer) const516 void ImmutableMessageFieldGenerator::GenerateHashCode(
517 io::Printer* printer) const {
518 printer->Print(variables_,
519 "hash = (37 * hash) + $constant_name$;\n"
520 "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
521 }
522
GetBoxedType() const523 std::string ImmutableMessageFieldGenerator::GetBoxedType() const {
524 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
525 }
526
527 // ===================================================================
528
ImmutableMessageOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)529 ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator(
530 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
531 Context* context)
532 : ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
533 builderBitIndex, context) {
534 const OneofGeneratorInfo* info =
535 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
536 SetCommonOneofVariables(descriptor, info, &variables_);
537 }
538
~ImmutableMessageOneofFieldGenerator()539 ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() {}
540
GenerateMembers(io::Printer * printer) const541 void ImmutableMessageOneofFieldGenerator::GenerateMembers(
542 io::Printer* printer) const {
543 PrintExtraFieldInfo(variables_, printer);
544 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
545 printer->Print(variables_,
546 "@java.lang.Override\n"
547 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
548 " return $has_oneof_case_message$;\n"
549 "}\n");
550 printer->Annotate("{", "}", descriptor_);
551 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
552 printer->Print(variables_,
553 "@java.lang.Override\n"
554 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\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 WriteFieldDocComment(printer, descriptor_);
563 printer->Print(variables_,
564 "@java.lang.Override\n"
565 "$deprecation$public $type$OrBuilder "
566 "${$get$capitalized_name$OrBuilder$}$() {\n"
567 " if ($has_oneof_case_message$) {\n"
568 " return ($type$) $oneof_name$_;\n"
569 " }\n"
570 " return $type$.getDefaultInstance();\n"
571 "}\n");
572 printer->Annotate("{", "}", descriptor_);
573 }
574
GenerateBuilderMembers(io::Printer * printer) const575 void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers(
576 io::Printer* printer) const {
577 // When using nested-builders, the code initially works just like the
578 // non-nested builder case. It only creates a nested builder lazily on
579 // demand and then forever delegates to it after creation.
580 printer->Print(variables_,
581 // If this builder is non-null, it is used and the other fields
582 // are ignored.
583 "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
584 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
585 "\n");
586
587 // The comments above the methods below are based on a hypothetical
588 // field of type "Field" called "Field".
589
590 // boolean hasField()
591 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
592 printer->Print(variables_,
593 "@java.lang.Override\n"
594 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
595 " return $has_oneof_case_message$;\n"
596 "}\n");
597 printer->Annotate("{", "}", descriptor_);
598
599 // Field getField()
600 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
601 PrintNestedBuilderFunction(
602 printer,
603 "@java.lang.Override\n"
604 "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
605
606 "if ($has_oneof_case_message$) {\n"
607 " return ($type$) $oneof_name$_;\n"
608 "}\n"
609 "return $type$.getDefaultInstance();\n",
610
611 "if ($has_oneof_case_message$) {\n"
612 " return $name$Builder_.getMessage();\n"
613 "}\n"
614 "return $type$.getDefaultInstance();\n",
615
616 NULL);
617
618 // Field.Builder setField(Field value)
619 WriteFieldDocComment(printer, descriptor_);
620 PrintNestedBuilderFunction(
621 printer,
622 "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
623
624 "if (value == null) {\n"
625 " throw new NullPointerException();\n"
626 "}\n"
627 "$oneof_name$_ = value;\n"
628 "$on_changed$\n",
629
630 "$name$Builder_.setMessage(value);\n",
631
632 "$set_oneof_case_message$;\n"
633 "return this;\n");
634
635 // Field.Builder setField(Field.Builder builderForValue)
636 WriteFieldDocComment(printer, descriptor_);
637 PrintNestedBuilderFunction(
638 printer,
639 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
640 " $type$.Builder builderForValue)",
641
642 "$oneof_name$_ = builderForValue.build();\n"
643 "$on_changed$\n",
644
645 "$name$Builder_.setMessage(builderForValue.build());\n",
646
647 "$set_oneof_case_message$;\n"
648 "return this;\n");
649
650 // Field.Builder mergeField(Field value)
651 WriteFieldDocComment(printer, descriptor_);
652 PrintNestedBuilderFunction(
653 printer,
654 "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
655
656 "if ($has_oneof_case_message$ &&\n"
657 " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
658 " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
659 " .mergeFrom(value).buildPartial();\n"
660 "} else {\n"
661 " $oneof_name$_ = value;\n"
662 "}\n"
663 "$on_changed$\n",
664
665 "if ($has_oneof_case_message$) {\n"
666 " $name$Builder_.mergeFrom(value);\n"
667 "}\n"
668 "$name$Builder_.setMessage(value);\n",
669
670 "$set_oneof_case_message$;\n"
671 "return this;\n");
672
673 // Field.Builder clearField()
674 WriteFieldDocComment(printer, descriptor_);
675 PrintNestedBuilderFunction(
676 printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
677
678 "if ($has_oneof_case_message$) {\n"
679 " $clear_oneof_case_message$;\n"
680 " $oneof_name$_ = null;\n"
681 " $on_changed$\n"
682 "}\n",
683
684 "if ($has_oneof_case_message$) {\n"
685 " $clear_oneof_case_message$;\n"
686 " $oneof_name$_ = null;\n"
687 "}\n"
688 "$name$Builder_.clear();\n",
689
690 "return this;\n");
691
692 WriteFieldDocComment(printer, descriptor_);
693 printer->Print(variables_,
694 "$deprecation$public $type$.Builder "
695 "${$get$capitalized_name$Builder$}$() {\n"
696 " return get$capitalized_name$FieldBuilder().getBuilder();\n"
697 "}\n");
698 printer->Annotate("{", "}", descriptor_);
699 WriteFieldDocComment(printer, descriptor_);
700 printer->Print(
701 variables_,
702 "@java.lang.Override\n"
703 "$deprecation$public $type$OrBuilder "
704 "${$get$capitalized_name$OrBuilder$}$() {\n"
705 " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
706 " return $name$Builder_.getMessageOrBuilder();\n"
707 " } else {\n"
708 " if ($has_oneof_case_message$) {\n"
709 " return ($type$) $oneof_name$_;\n"
710 " }\n"
711 " return $type$.getDefaultInstance();\n"
712 " }\n"
713 "}\n");
714 printer->Annotate("{", "}", descriptor_);
715 WriteFieldDocComment(printer, descriptor_);
716 printer->Print(
717 variables_,
718 "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
719 " $type$, $type$.Builder, $type$OrBuilder> \n"
720 " ${$get$capitalized_name$FieldBuilder$}$() {\n"
721 " if ($name$Builder_ == null) {\n"
722 " if (!($has_oneof_case_message$)) {\n"
723 " $oneof_name$_ = $type$.getDefaultInstance();\n"
724 " }\n"
725 " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
726 " $type$, $type$.Builder, $type$OrBuilder>(\n"
727 " ($type$) $oneof_name$_,\n"
728 " getParentForChildren(),\n"
729 " isClean());\n"
730 " $oneof_name$_ = null;\n"
731 " }\n"
732 " $set_oneof_case_message$;\n"
733 " $on_changed$;\n"
734 " return $name$Builder_;\n"
735 "}\n");
736 printer->Annotate("{", "}", descriptor_);
737 }
738
GenerateBuildingCode(io::Printer * printer) const739 void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode(
740 io::Printer* printer) const {
741 printer->Print(variables_, "if ($has_oneof_case_message$) {\n");
742 printer->Indent();
743
744 PrintNestedBuilderCondition(
745 printer, "result.$oneof_name$_ = $oneof_name$_;\n",
746
747 "result.$oneof_name$_ = $name$Builder_.build();\n");
748
749 printer->Outdent();
750 printer->Print("}\n");
751 }
752
GenerateMergingCode(io::Printer * printer) const753 void ImmutableMessageOneofFieldGenerator::GenerateMergingCode(
754 io::Printer* printer) const {
755 printer->Print(variables_,
756 "merge$capitalized_name$(other.get$capitalized_name$());\n");
757 }
758
GenerateParsingCode(io::Printer * printer) const759 void ImmutableMessageOneofFieldGenerator::GenerateParsingCode(
760 io::Printer* printer) const {
761 printer->Print(variables_,
762 "$type$.Builder subBuilder = null;\n"
763 "if ($has_oneof_case_message$) {\n"
764 " subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
765 "}\n");
766
767 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
768 printer->Print(
769 variables_,
770 "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
771 " extensionRegistry);\n");
772 } else {
773 printer->Print(
774 variables_,
775 "$oneof_name$_ =\n"
776 " input.readMessage($type$.$get_parser$, extensionRegistry);\n");
777 }
778
779 printer->Print(variables_,
780 "if (subBuilder != null) {\n"
781 " subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
782 " $oneof_name$_ = subBuilder.buildPartial();\n"
783 "}\n");
784 printer->Print(variables_, "$set_oneof_case_message$;\n");
785 }
786
GenerateSerializationCode(io::Printer * printer) const787 void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode(
788 io::Printer* printer) const {
789 printer->Print(
790 variables_,
791 "if ($has_oneof_case_message$) {\n"
792 " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
793 "}\n");
794 }
795
GenerateSerializedSizeCode(io::Printer * printer) const796 void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
797 io::Printer* printer) const {
798 printer->Print(
799 variables_,
800 "if ($has_oneof_case_message$) {\n"
801 " size += com.google.protobuf.CodedOutputStream\n"
802 " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
803 "}\n");
804 }
805
806 // ===================================================================
807
RepeatedImmutableMessageFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)808 RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator(
809 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
810 Context* context)
811 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
812 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
813 context->GetFieldGeneratorInfo(descriptor),
814 name_resolver_, &variables_);
815 }
816
817 RepeatedImmutableMessageFieldGenerator::
~RepeatedImmutableMessageFieldGenerator()818 ~RepeatedImmutableMessageFieldGenerator() {}
819
GetNumBitsForMessage() const820 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
821 return 0;
822 }
823
GetNumBitsForBuilder() const824 int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
825 return 1;
826 }
827
GenerateInterfaceMembers(io::Printer * printer) const828 void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
829 io::Printer* printer) const {
830 // TODO(jonp): In the future, consider having methods specific to the
831 // interface so that builders can choose dynamically to either return a
832 // message or a nested builder, so that asking for the interface doesn't
833 // cause a message to ever be built.
834 WriteFieldDocComment(printer, descriptor_);
835 printer->Print(variables_,
836 "$deprecation$java.util.List<$type$> \n"
837 " get$capitalized_name$List();\n");
838 WriteFieldDocComment(printer, descriptor_);
839 printer->Print(variables_,
840 "$deprecation$$type$ get$capitalized_name$(int index);\n");
841 WriteFieldDocComment(printer, descriptor_);
842 printer->Print(variables_,
843 "$deprecation$int get$capitalized_name$Count();\n");
844
845 WriteFieldDocComment(printer, descriptor_);
846 printer->Print(variables_,
847 "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
848 " get$capitalized_name$OrBuilderList();\n");
849 WriteFieldDocComment(printer, descriptor_);
850 printer->Print(
851 variables_,
852 "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
853 " int index);\n");
854 }
855
GenerateMembers(io::Printer * printer) const856 void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
857 io::Printer* printer) const {
858 printer->Print(variables_, "private java.util.List<$type$> $name$_;\n");
859 PrintExtraFieldInfo(variables_, printer);
860 WriteFieldDocComment(printer, descriptor_);
861 printer->Print(variables_,
862 "@java.lang.Override\n"
863 "$deprecation$public java.util.List<$type$> "
864 "${$get$capitalized_name$List$}$() {\n"
865 " return $name$_;\n" // note: unmodifiable list
866 "}\n");
867 printer->Annotate("{", "}", descriptor_);
868 WriteFieldDocComment(printer, descriptor_);
869 printer->Print(
870 variables_,
871 "@java.lang.Override\n"
872 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
873 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
874 " return $name$_;\n"
875 "}\n");
876 printer->Annotate("{", "}", descriptor_);
877 WriteFieldDocComment(printer, descriptor_);
878 printer->Print(
879 variables_,
880 "@java.lang.Override\n"
881 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
882 " return $name$_.size();\n"
883 "}\n");
884 printer->Annotate("{", "}", descriptor_);
885 WriteFieldDocComment(printer, descriptor_);
886 printer->Print(
887 variables_,
888 "@java.lang.Override\n"
889 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
890 " return $name$_.get(index);\n"
891 "}\n");
892 printer->Annotate("{", "}", descriptor_);
893 WriteFieldDocComment(printer, descriptor_);
894 printer->Print(variables_,
895 "@java.lang.Override\n"
896 "$deprecation$public $type$OrBuilder "
897 "${$get$capitalized_name$OrBuilder$}$(\n"
898 " int index) {\n"
899 " return $name$_.get(index);\n"
900 "}\n");
901 printer->Annotate("{", "}", descriptor_);
902 }
903
PrintNestedBuilderCondition(io::Printer * printer,const char * regular_case,const char * nested_builder_case) const904 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
905 io::Printer* printer, const char* regular_case,
906 const char* nested_builder_case) const {
907 printer->Print(variables_, "if ($name$Builder_ == null) {\n");
908 printer->Indent();
909 printer->Print(variables_, regular_case);
910 printer->Outdent();
911 printer->Print("} else {\n");
912 printer->Indent();
913 printer->Print(variables_, nested_builder_case);
914 printer->Outdent();
915 printer->Print("}\n");
916 }
917
PrintNestedBuilderFunction(io::Printer * printer,const char * method_prototype,const char * regular_case,const char * nested_builder_case,const char * trailing_code) const918 void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
919 io::Printer* printer, const char* method_prototype,
920 const char* regular_case, const char* nested_builder_case,
921 const char* trailing_code) const {
922 printer->Print(variables_, method_prototype);
923 printer->Annotate("{", "}", descriptor_);
924 printer->Print(" {\n");
925 printer->Indent();
926 PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
927 if (trailing_code != NULL) {
928 printer->Print(variables_, trailing_code);
929 }
930 printer->Outdent();
931 printer->Print("}\n");
932 }
933
GenerateBuilderMembers(io::Printer * printer) const934 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
935 io::Printer* printer) const {
936 // When using nested-builders, the code initially works just like the
937 // non-nested builder case. It only creates a nested builder lazily on
938 // demand and then forever delegates to it after creation.
939
940 printer->Print(
941 variables_,
942 // Used when the builder is null.
943 // One field is the list and the other field keeps track of whether the
944 // list is immutable. If it's immutable, the invariant is that it must
945 // either an instance of Collections.emptyList() or it's an ArrayList
946 // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
947 // a refererence to the underlying ArrayList. This invariant allows us to
948 // share instances of lists between protocol buffers avoiding expensive
949 // memory allocations. Note, immutable is a strong guarantee here -- not
950 // just that the list cannot be modified via the reference but that the
951 // list can never be modified.
952 "private java.util.List<$type$> $name$_ =\n"
953 " java.util.Collections.emptyList();\n"
954
955 "private void ensure$capitalized_name$IsMutable() {\n"
956 " if (!$get_mutable_bit_builder$) {\n"
957 " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
958 " $set_mutable_bit_builder$;\n"
959 " }\n"
960 "}\n"
961 "\n");
962
963 printer->Print(
964 variables_,
965 // If this builder is non-null, it is used and the other fields are
966 // ignored.
967 "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
968 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
969 "\n");
970
971 // The comments above the methods below are based on a hypothetical
972 // repeated field of type "Field" called "RepeatedField".
973
974 // List<Field> getRepeatedFieldList()
975 WriteFieldDocComment(printer, descriptor_);
976 PrintNestedBuilderFunction(
977 printer,
978 "$deprecation$public java.util.List<$type$> "
979 "${$get$capitalized_name$List$}$()",
980
981 "return java.util.Collections.unmodifiableList($name$_);\n",
982 "return $name$Builder_.getMessageList();\n",
983
984 NULL);
985
986 // int getRepeatedFieldCount()
987 WriteFieldDocComment(printer, descriptor_);
988 PrintNestedBuilderFunction(
989 printer, "$deprecation$public int ${$get$capitalized_name$Count$}$()",
990
991 "return $name$_.size();\n", "return $name$Builder_.getCount();\n",
992
993 NULL);
994
995 // Field getRepeatedField(int index)
996 WriteFieldDocComment(printer, descriptor_);
997 PrintNestedBuilderFunction(
998 printer,
999 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)",
1000
1001 "return $name$_.get(index);\n",
1002
1003 "return $name$Builder_.getMessage(index);\n",
1004
1005 NULL);
1006
1007 // Builder setRepeatedField(int index, Field value)
1008 WriteFieldDocComment(printer, descriptor_);
1009 PrintNestedBuilderFunction(
1010 printer,
1011 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1012 " int index, $type$ value)",
1013 "if (value == null) {\n"
1014 " throw new NullPointerException();\n"
1015 "}\n"
1016 "ensure$capitalized_name$IsMutable();\n"
1017 "$name$_.set(index, value);\n"
1018 "$on_changed$\n",
1019 "$name$Builder_.setMessage(index, value);\n", "return this;\n");
1020
1021 // Builder setRepeatedField(int index, Field.Builder builderForValue)
1022 WriteFieldDocComment(printer, descriptor_);
1023 PrintNestedBuilderFunction(
1024 printer,
1025 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1026 " int index, $type$.Builder builderForValue)",
1027
1028 "ensure$capitalized_name$IsMutable();\n"
1029 "$name$_.set(index, builderForValue.build());\n"
1030 "$on_changed$\n",
1031
1032 "$name$Builder_.setMessage(index, builderForValue.build());\n",
1033
1034 "return this;\n");
1035
1036 // Builder addRepeatedField(Field value)
1037 WriteFieldDocComment(printer, descriptor_);
1038 PrintNestedBuilderFunction(
1039 printer,
1040 "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)",
1041
1042 "if (value == null) {\n"
1043 " throw new NullPointerException();\n"
1044 "}\n"
1045 "ensure$capitalized_name$IsMutable();\n"
1046 "$name$_.add(value);\n"
1047
1048 "$on_changed$\n",
1049
1050 "$name$Builder_.addMessage(value);\n",
1051
1052 "return this;\n");
1053
1054 // Builder addRepeatedField(int index, Field value)
1055 WriteFieldDocComment(printer, descriptor_);
1056 PrintNestedBuilderFunction(
1057 printer,
1058 "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1059 " int index, $type$ value)",
1060
1061 "if (value == null) {\n"
1062 " throw new NullPointerException();\n"
1063 "}\n"
1064 "ensure$capitalized_name$IsMutable();\n"
1065 "$name$_.add(index, value);\n"
1066 "$on_changed$\n",
1067
1068 "$name$Builder_.addMessage(index, value);\n",
1069
1070 "return this;\n");
1071
1072 // Builder addRepeatedField(Field.Builder builderForValue)
1073 WriteFieldDocComment(printer, descriptor_);
1074 PrintNestedBuilderFunction(
1075 printer,
1076 "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1077 " $type$.Builder builderForValue)",
1078
1079 "ensure$capitalized_name$IsMutable();\n"
1080 "$name$_.add(builderForValue.build());\n"
1081 "$on_changed$\n",
1082
1083 "$name$Builder_.addMessage(builderForValue.build());\n",
1084
1085 "return this;\n");
1086
1087 // Builder addRepeatedField(int index, Field.Builder builderForValue)
1088 WriteFieldDocComment(printer, descriptor_);
1089 PrintNestedBuilderFunction(
1090 printer,
1091 "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1092 " int index, $type$.Builder builderForValue)",
1093
1094 "ensure$capitalized_name$IsMutable();\n"
1095 "$name$_.add(index, builderForValue.build());\n"
1096 "$on_changed$\n",
1097
1098 "$name$Builder_.addMessage(index, builderForValue.build());\n",
1099
1100 "return this;\n");
1101
1102 // Builder addAllRepeatedField(Iterable<Field> values)
1103 WriteFieldDocComment(printer, descriptor_);
1104 PrintNestedBuilderFunction(
1105 printer,
1106 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
1107 " java.lang.Iterable<? extends $type$> values)",
1108
1109 "ensure$capitalized_name$IsMutable();\n"
1110 "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
1111 " values, $name$_);\n"
1112 "$on_changed$\n",
1113
1114 "$name$Builder_.addAllMessages(values);\n",
1115
1116 "return this;\n");
1117
1118 // Builder clearAllRepeatedField()
1119 WriteFieldDocComment(printer, descriptor_);
1120 PrintNestedBuilderFunction(
1121 printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
1122
1123 "$name$_ = java.util.Collections.emptyList();\n"
1124 "$clear_mutable_bit_builder$;\n"
1125 "$on_changed$\n",
1126
1127 "$name$Builder_.clear();\n",
1128
1129 "return this;\n");
1130
1131 // Builder removeRepeatedField(int index)
1132 WriteFieldDocComment(printer, descriptor_);
1133 PrintNestedBuilderFunction(
1134 printer,
1135 "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
1136
1137 "ensure$capitalized_name$IsMutable();\n"
1138 "$name$_.remove(index);\n"
1139 "$on_changed$\n",
1140
1141 "$name$Builder_.remove(index);\n",
1142
1143 "return this;\n");
1144
1145 WriteFieldDocComment(printer, descriptor_);
1146 printer->Print(
1147 variables_,
1148 "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n"
1149 " int index) {\n"
1150 " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
1151 "}\n");
1152 printer->Annotate("{", "}", descriptor_);
1153
1154 WriteFieldDocComment(printer, descriptor_);
1155 printer->Print(variables_,
1156 "$deprecation$public $type$OrBuilder "
1157 "${$get$capitalized_name$OrBuilder$}$(\n"
1158 " int index) {\n"
1159 " if ($name$Builder_ == null) {\n"
1160 " return $name$_.get(index);"
1161 " } else {\n"
1162 " return $name$Builder_.getMessageOrBuilder(index);\n"
1163 " }\n"
1164 "}\n");
1165 printer->Annotate("{", "}", descriptor_);
1166
1167 WriteFieldDocComment(printer, descriptor_);
1168 printer->Print(
1169 variables_,
1170 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
1171 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
1172 " if ($name$Builder_ != null) {\n"
1173 " return $name$Builder_.getMessageOrBuilderList();\n"
1174 " } else {\n"
1175 " return java.util.Collections.unmodifiableList($name$_);\n"
1176 " }\n"
1177 "}\n");
1178 printer->Annotate("{", "}", descriptor_);
1179
1180 WriteFieldDocComment(printer, descriptor_);
1181 printer->Print(variables_,
1182 "$deprecation$public $type$.Builder "
1183 "${$add$capitalized_name$Builder$}$() {\n"
1184 " return get$capitalized_name$FieldBuilder().addBuilder(\n"
1185 " $type$.getDefaultInstance());\n"
1186 "}\n");
1187 printer->Annotate("{", "}", descriptor_);
1188 WriteFieldDocComment(printer, descriptor_);
1189 printer->Print(
1190 variables_,
1191 "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
1192 " int index) {\n"
1193 " return get$capitalized_name$FieldBuilder().addBuilder(\n"
1194 " index, $type$.getDefaultInstance());\n"
1195 "}\n");
1196 printer->Annotate("{", "}", descriptor_);
1197 WriteFieldDocComment(printer, descriptor_);
1198 printer->Print(
1199 variables_,
1200 "$deprecation$public java.util.List<$type$.Builder> \n"
1201 " ${$get$capitalized_name$BuilderList$}$() {\n"
1202 " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
1203 "}\n"
1204 "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1205 " $type$, $type$.Builder, $type$OrBuilder> \n"
1206 " get$capitalized_name$FieldBuilder() {\n"
1207 " if ($name$Builder_ == null) {\n"
1208 " $name$Builder_ = new "
1209 "com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1210 " $type$, $type$.Builder, $type$OrBuilder>(\n"
1211 " $name$_,\n"
1212 " $get_mutable_bit_builder$,\n"
1213 " getParentForChildren(),\n"
1214 " isClean());\n"
1215 " $name$_ = null;\n"
1216 " }\n"
1217 " return $name$Builder_;\n"
1218 "}\n");
1219 printer->Annotate("{", "}", descriptor_);
1220 }
1221
1222 void RepeatedImmutableMessageFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const1223 GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
1224 printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n");
1225 }
1226
GenerateInitializationCode(io::Printer * printer) const1227 void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
1228 io::Printer* printer) const {
1229 printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
1230 }
1231
GenerateBuilderClearCode(io::Printer * printer) const1232 void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
1233 io::Printer* printer) const {
1234 PrintNestedBuilderCondition(printer,
1235 "$name$_ = java.util.Collections.emptyList();\n"
1236 "$clear_mutable_bit_builder$;\n",
1237
1238 "$name$Builder_.clear();\n");
1239 }
1240
GenerateMergingCode(io::Printer * printer) const1241 void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
1242 io::Printer* printer) const {
1243 // The code below does two optimizations (non-nested builder case):
1244 // 1. If the other list is empty, there's nothing to do. This ensures we
1245 // don't allocate a new array if we already have an immutable one.
1246 // 2. If the other list is non-empty and our current list is empty, we can
1247 // reuse the other list which is guaranteed to be immutable.
1248 PrintNestedBuilderCondition(
1249 printer,
1250 "if (!other.$name$_.isEmpty()) {\n"
1251 " if ($name$_.isEmpty()) {\n"
1252 " $name$_ = other.$name$_;\n"
1253 " $clear_mutable_bit_builder$;\n"
1254 " } else {\n"
1255 " ensure$capitalized_name$IsMutable();\n"
1256 " $name$_.addAll(other.$name$_);\n"
1257 " }\n"
1258 " $on_changed$\n"
1259 "}\n",
1260
1261 "if (!other.$name$_.isEmpty()) {\n"
1262 " if ($name$Builder_.isEmpty()) {\n"
1263 " $name$Builder_.dispose();\n"
1264 " $name$Builder_ = null;\n"
1265 " $name$_ = other.$name$_;\n"
1266 " $clear_mutable_bit_builder$;\n"
1267 " $name$Builder_ = \n"
1268 " com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders "
1269 "?\n"
1270 " get$capitalized_name$FieldBuilder() : null;\n"
1271 " } else {\n"
1272 " $name$Builder_.addAllMessages(other.$name$_);\n"
1273 " }\n"
1274 "}\n");
1275 }
1276
GenerateBuildingCode(io::Printer * printer) const1277 void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode(
1278 io::Printer* printer) const {
1279 // The code below (non-nested builder case) ensures that the result has an
1280 // immutable list. If our list is immutable, we can just reuse it. If not,
1281 // we make it immutable.
1282 PrintNestedBuilderCondition(
1283 printer,
1284 "if ($get_mutable_bit_builder$) {\n"
1285 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1286 " $clear_mutable_bit_builder$;\n"
1287 "}\n"
1288 "result.$name$_ = $name$_;\n",
1289
1290 "result.$name$_ = $name$Builder_.build();\n");
1291 }
1292
GenerateParsingCode(io::Printer * printer) const1293 void RepeatedImmutableMessageFieldGenerator::GenerateParsingCode(
1294 io::Printer* printer) const {
1295 printer->Print(variables_,
1296 "if (!$get_mutable_bit_parser$) {\n"
1297 " $name$_ = new java.util.ArrayList<$type$>();\n"
1298 " $set_mutable_bit_parser$;\n"
1299 "}\n");
1300
1301 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
1302 printer->Print(
1303 variables_,
1304 "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n"
1305 " extensionRegistry));\n");
1306 } else {
1307 printer->Print(
1308 variables_,
1309 "$name$_.add(\n"
1310 " input.readMessage($type$.$get_parser$, extensionRegistry));\n");
1311 }
1312 }
1313
GenerateParsingDoneCode(io::Printer * printer) const1314 void RepeatedImmutableMessageFieldGenerator::GenerateParsingDoneCode(
1315 io::Printer* printer) const {
1316 printer->Print(
1317 variables_,
1318 "if ($get_mutable_bit_parser$) {\n"
1319 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1320 "}\n");
1321 }
1322
GenerateSerializationCode(io::Printer * printer) const1323 void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
1324 io::Printer* printer) const {
1325 printer->Print(variables_,
1326 "for (int i = 0; i < $name$_.size(); i++) {\n"
1327 " output.write$group_or_message$($number$, $name$_.get(i));\n"
1328 "}\n");
1329 }
1330
GenerateSerializedSizeCode(io::Printer * printer) const1331 void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
1332 io::Printer* printer) const {
1333 printer->Print(
1334 variables_,
1335 "for (int i = 0; i < $name$_.size(); i++) {\n"
1336 " size += com.google.protobuf.CodedOutputStream\n"
1337 " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
1338 "}\n");
1339 }
1340
GenerateEqualsCode(io::Printer * printer) const1341 void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode(
1342 io::Printer* printer) const {
1343 printer->Print(
1344 variables_,
1345 "if (!get$capitalized_name$List()\n"
1346 " .equals(other.get$capitalized_name$List())) return false;\n");
1347 }
1348
GenerateHashCode(io::Printer * printer) const1349 void RepeatedImmutableMessageFieldGenerator::GenerateHashCode(
1350 io::Printer* printer) const {
1351 printer->Print(
1352 variables_,
1353 "if (get$capitalized_name$Count() > 0) {\n"
1354 " hash = (37 * hash) + $constant_name$;\n"
1355 " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
1356 "}\n");
1357 }
1358
GetBoxedType() const1359 std::string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
1360 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
1361 }
1362
1363 } // namespace java
1364 } // namespace compiler
1365 } // namespace protobuf
1366 } // namespace google
1367