1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: dweis@google.com (Daniel Weis)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include "google/protobuf/compiler/java/full/message_builder.h"
13
14 #include <cstdint>
15 #include <memory>
16 #include <string>
17 #include <vector>
18
19 #include "absl/container/btree_set.h"
20 #include "absl/container/flat_hash_map.h"
21 #include "absl/log/absl_check.h"
22 #include "absl/strings/ascii.h"
23 #include "absl/strings/str_cat.h"
24 #include "absl/strings/string_view.h"
25 #include "google/protobuf/compiler/java/context.h"
26 #include "google/protobuf/compiler/java/doc_comment.h"
27 #include "google/protobuf/compiler/java/field_common.h"
28 #include "google/protobuf/compiler/java/generator_factory.h"
29 #include "google/protobuf/compiler/java/helpers.h"
30 #include "google/protobuf/compiler/java/full/enum.h"
31 #include "google/protobuf/compiler/java/full/extension.h"
32 #include "google/protobuf/compiler/java/full/field_generator.h"
33 #include "google/protobuf/compiler/java/full/make_field_gens.h"
34 #include "google/protobuf/compiler/java/name_resolver.h"
35 #include "google/protobuf/descriptor.pb.h"
36 #include "google/protobuf/io/printer.h"
37 #include "google/protobuf/wire_format.h"
38
39 // Must be last.
40 #include "google/protobuf/port_def.inc"
41
42 namespace google {
43 namespace protobuf {
44 namespace compiler {
45 namespace java {
46
47 using internal::WireFormat;
48 using internal::WireFormatLite;
49
50 namespace {
MapValueImmutableClassdName(const Descriptor * descriptor,ClassNameResolver * name_resolver)51 std::string MapValueImmutableClassdName(const Descriptor* descriptor,
52 ClassNameResolver* name_resolver) {
53 const FieldDescriptor* value_field = descriptor->map_value();
54 ABSL_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
55 return name_resolver->GetImmutableClassName(value_field->message_type());
56 }
57
BitfieldTracksMutability(const FieldDescriptor * const descriptor)58 bool BitfieldTracksMutability(const FieldDescriptor* const descriptor) {
59 if (!descriptor->is_repeated() || IsMapField(descriptor)) {
60 return false;
61 }
62 // TODO: update this to migrate repeated fields to use
63 // ProtobufList (which tracks immutability internally). That allows us to use
64 // the presence bit to skip work on the repeated field if it is not populated.
65 // Once all repeated fields are held in ProtobufLists, this method shouldn't
66 // be needed.
67 switch (descriptor->type()) {
68 case FieldDescriptor::TYPE_GROUP:
69 case FieldDescriptor::TYPE_MESSAGE:
70 case FieldDescriptor::TYPE_ENUM:
71 return true;
72 default:
73 return false;
74 }
75 }
76 } // namespace
77
MessageBuilderGenerator(const Descriptor * descriptor,Context * context)78 MessageBuilderGenerator::MessageBuilderGenerator(const Descriptor* descriptor,
79 Context* context)
80 : descriptor_(descriptor),
81 context_(context),
82 name_resolver_(context->GetNameResolver()),
83 field_generators_(MakeImmutableFieldGenerators(descriptor, context_)) {
84 ABSL_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
85 << "Generator factory error: A non-lite message generator is used to "
86 "generate lite messages.";
87 for (int i = 0; i < descriptor_->field_count(); i++) {
88 if (IsRealOneof(descriptor_->field(i))) {
89 const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
90 ABSL_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
91 }
92 }
93 }
94
~MessageBuilderGenerator()95 MessageBuilderGenerator::~MessageBuilderGenerator() {}
96
Generate(io::Printer * printer)97 void MessageBuilderGenerator::Generate(io::Printer* printer) {
98 WriteMessageDocComment(printer, descriptor_, context_->options());
99 if (descriptor_->extension_range_count() > 0) {
100 printer->Print(
101 "public static final class Builder extends\n"
102 " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
103 " $classname$, Builder> implements\n"
104 " $extra_interfaces$\n"
105 " $classname$OrBuilder {\n",
106 "classname", name_resolver_->GetImmutableClassName(descriptor_),
107 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
108 } else {
109 printer->Print(
110 "public static final class Builder extends\n"
111 " com.google.protobuf.GeneratedMessage.Builder<Builder> "
112 "implements\n"
113 " $extra_interfaces$\n"
114 " $classname$OrBuilder {\n",
115 "classname", name_resolver_->GetImmutableClassName(descriptor_),
116 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
117 }
118 printer->Indent();
119
120 GenerateDescriptorMethods(printer);
121 GenerateCommonBuilderMethods(printer);
122
123 if (context_->HasGeneratedMethods(descriptor_)) {
124 GenerateIsInitialized(printer);
125 GenerateBuilderParsingMethods(printer);
126 }
127
128 // oneof
129 absl::flat_hash_map<absl::string_view, std::string> vars;
130 for (auto& kv : oneofs_) {
131 const OneofDescriptor* oneof = kv.second;
132 vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
133 vars["oneof_capitalized_name"] =
134 context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
135 vars["oneof_index"] = absl::StrCat(oneof->index());
136 // oneofCase_ and oneof_
137 printer->Print(vars,
138 "private int $oneof_name$Case_ = 0;\n"
139 "private java.lang.Object $oneof_name$_;\n");
140 // oneofCase() and clearOneof()
141 printer->Print(vars,
142 "public $oneof_capitalized_name$Case\n"
143 " get$oneof_capitalized_name$Case() {\n"
144 " return $oneof_capitalized_name$Case.forNumber(\n"
145 " $oneof_name$Case_);\n"
146 "}\n"
147 "\n"
148 "public Builder clear$oneof_capitalized_name$() {\n"
149 " $oneof_name$Case_ = 0;\n"
150 " $oneof_name$_ = null;\n"
151 " onChanged();\n"
152 " return this;\n"
153 "}\n"
154 "\n");
155 }
156
157 // Integers for bit fields.
158 int totalBits = 0;
159 for (int i = 0; i < descriptor_->field_count(); i++) {
160 totalBits +=
161 field_generators_.get(descriptor_->field(i)).GetNumBitsForBuilder();
162 }
163 int totalInts = (totalBits + 31) / 32;
164 for (int i = 0; i < totalInts; i++) {
165 printer->Print("private int $bit_field_name$;\n", "bit_field_name",
166 GetBitFieldName(i));
167 }
168
169 for (int i = 0; i < descriptor_->field_count(); i++) {
170 printer->Print("\n");
171 field_generators_.get(descriptor_->field(i))
172 .GenerateBuilderMembers(printer);
173 }
174
175 printer->Print(
176 "\n"
177 "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
178 "full_name", descriptor_->full_name());
179
180 printer->Outdent();
181 printer->Print("}\n");
182 }
183
184 // ===================================================================
185
GenerateDescriptorMethods(io::Printer * printer)186 void MessageBuilderGenerator::GenerateDescriptorMethods(io::Printer* printer) {
187 if (!descriptor_->options().no_standard_descriptor_accessor()) {
188 printer->Print(
189 "public static final com.google.protobuf.Descriptors.Descriptor\n"
190 " getDescriptor() {\n"
191 " return $fileclass$.internal_$identifier$_descriptor;\n"
192 "}\n"
193 "\n",
194 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
195 "identifier", UniqueFileScopeIdentifier(descriptor_));
196 }
197 std::vector<const FieldDescriptor*> map_fields;
198 for (int i = 0; i < descriptor_->field_count(); i++) {
199 const FieldDescriptor* field = descriptor_->field(i);
200 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
201 IsMapEntry(field->message_type())) {
202 map_fields.push_back(field);
203 }
204 }
205 if (!map_fields.empty()) {
206 printer->Print(
207 "@SuppressWarnings({\"rawtypes\"})\n"
208 "protected com.google.protobuf.MapFieldReflectionAccessor "
209 "internalGetMapFieldReflection(\n"
210 " int number) {\n"
211 " switch (number) {\n");
212 printer->Indent();
213 printer->Indent();
214 for (int i = 0; i < map_fields.size(); ++i) {
215 const FieldDescriptor* field = map_fields[i];
216 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
217 printer->Print(
218 "case $number$:\n"
219 " return internalGet$capitalized_name$();\n",
220 "number", absl::StrCat(field->number()), "capitalized_name",
221 info->capitalized_name);
222 }
223 printer->Print(
224 "default:\n"
225 " throw new RuntimeException(\n"
226 " \"Invalid map field number: \" + number);\n");
227 printer->Outdent();
228 printer->Outdent();
229 printer->Print(
230 " }\n"
231 "}\n");
232 printer->Print(
233 "@SuppressWarnings({\"rawtypes\"})\n"
234 "protected com.google.protobuf.MapFieldReflectionAccessor "
235 "internalGetMutableMapFieldReflection(\n"
236 " int number) {\n"
237 " switch (number) {\n");
238 printer->Indent();
239 printer->Indent();
240 for (int i = 0; i < map_fields.size(); ++i) {
241 const FieldDescriptor* field = map_fields[i];
242 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
243 printer->Print(
244 "case $number$:\n"
245 " return internalGetMutable$capitalized_name$();\n",
246 "number", absl::StrCat(field->number()), "capitalized_name",
247 info->capitalized_name);
248 }
249 printer->Print(
250 "default:\n"
251 " throw new RuntimeException(\n"
252 " \"Invalid map field number: \" + number);\n");
253 printer->Outdent();
254 printer->Outdent();
255 printer->Print(
256 " }\n"
257 "}\n");
258 }
259 printer->Print(
260 "@java.lang.Override\n"
261 "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
262 " internalGetFieldAccessorTable() {\n"
263 " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
264 " .ensureFieldAccessorsInitialized(\n"
265 " $classname$.class, $classname$.Builder.class);\n"
266 "}\n"
267 "\n",
268 "classname", name_resolver_->GetImmutableClassName(descriptor_),
269 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
270 "identifier", UniqueFileScopeIdentifier(descriptor_));
271 }
272
273 // ===================================================================
274
GenerateCommonBuilderMethods(io::Printer * printer)275 void MessageBuilderGenerator::GenerateCommonBuilderMethods(
276 io::Printer* printer) {
277 // Decide if we really need to have the "maybeForceBuilderInitialization()"
278 // method.
279 // TODO: Remove the need for this entirely
280 bool need_maybe_force_builder_init = false;
281 for (int i = 0; i < descriptor_->field_count(); i++) {
282 if (descriptor_->field(i)->message_type() != nullptr &&
283 !IsRealOneof(descriptor_->field(i)) &&
284 HasHasbit(descriptor_->field(i))) {
285 need_maybe_force_builder_init = true;
286 break;
287 }
288 }
289
290 const char* force_builder_init = need_maybe_force_builder_init
291 ? " maybeForceBuilderInitialization();"
292 : "";
293
294 printer->Print(
295 "// Construct using $classname$.newBuilder()\n"
296 "private Builder() {\n"
297 "$force_builder_init$\n"
298 "}\n"
299 "\n",
300 "classname", name_resolver_->GetImmutableClassName(descriptor_),
301 "force_builder_init", force_builder_init);
302
303 printer->Print(
304 "private Builder(\n"
305 " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
306 " super(parent);\n"
307 "$force_builder_init$\n"
308 "}\n",
309 "classname", name_resolver_->GetImmutableClassName(descriptor_),
310 "force_builder_init", force_builder_init);
311
312 if (need_maybe_force_builder_init) {
313 printer->Print(
314 "private void maybeForceBuilderInitialization() {\n"
315 " if (com.google.protobuf.GeneratedMessage\n"
316 " .alwaysUseFieldBuilders) {\n");
317
318 printer->Indent();
319 printer->Indent();
320 for (int i = 0; i < descriptor_->field_count(); i++) {
321 if (!IsRealOneof(descriptor_->field(i))) {
322 field_generators_.get(descriptor_->field(i))
323 .GenerateFieldBuilderInitializationCode(printer);
324 }
325 }
326 printer->Outdent();
327 printer->Outdent();
328
329 printer->Print(
330 " }\n"
331 "}\n");
332 }
333
334 printer->Print(
335 "@java.lang.Override\n"
336 "public Builder clear() {\n"
337 " super.clear();\n");
338
339 printer->Indent();
340 int totalBuilderInts = (descriptor_->field_count() + 31) / 32;
341 for (int i = 0; i < totalBuilderInts; i++) {
342 printer->Print("$bit_field_name$ = 0;\n", "bit_field_name",
343 GetBitFieldName(i));
344 }
345
346 for (int i = 0; i < descriptor_->field_count(); i++) {
347 field_generators_.get(descriptor_->field(i))
348 .GenerateBuilderClearCode(printer);
349 }
350
351 for (auto& kv : oneofs_) {
352 printer->Print(
353 "$oneof_name$Case_ = 0;\n"
354 "$oneof_name$_ = null;\n",
355 "oneof_name", context_->GetOneofGeneratorInfo(kv.second)->name);
356 }
357
358 printer->Outdent();
359
360 printer->Print(
361 " return this;\n"
362 "}\n"
363 "\n");
364
365 printer->Print(
366 "@java.lang.Override\n"
367 "public com.google.protobuf.Descriptors.Descriptor\n"
368 " getDescriptorForType() {\n"
369 " return $fileclass$.internal_$identifier$_descriptor;\n"
370 "}\n"
371 "\n",
372 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
373 "identifier", UniqueFileScopeIdentifier(descriptor_));
374
375 // LITE runtime implements this in GeneratedMessageLite.
376 printer->Print(
377 "@java.lang.Override\n"
378 "public $classname$ getDefaultInstanceForType() {\n"
379 " return $classname$.getDefaultInstance();\n"
380 "}\n"
381 "\n",
382 "classname", name_resolver_->GetImmutableClassName(descriptor_));
383
384 printer->Print(
385 "@java.lang.Override\n"
386 "public $classname$ build() {\n"
387 " $classname$ result = buildPartial();\n"
388 " if (!result.isInitialized()) {\n"
389 " throw newUninitializedMessageException(result);\n"
390 " }\n"
391 " return result;\n"
392 "}\n"
393 "\n",
394 "classname", name_resolver_->GetImmutableClassName(descriptor_));
395
396 GenerateBuildPartial(printer);
397
398 // -----------------------------------------------------------------
399
400 if (context_->HasGeneratedMethods(descriptor_)) {
401 printer->Print(
402 "@java.lang.Override\n"
403 "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
404 " if (other instanceof $classname$) {\n"
405 " return mergeFrom(($classname$)other);\n"
406 " } else {\n"
407 " super.mergeFrom(other);\n"
408 " return this;\n"
409 " }\n"
410 "}\n"
411 "\n",
412 "classname", name_resolver_->GetImmutableClassName(descriptor_));
413
414 printer->Print(
415 "public Builder mergeFrom($classname$ other) {\n"
416 // Optimization: If other is the default instance, we know none of its
417 // fields are set so we can skip the merge.
418 " if (other == $classname$.getDefaultInstance()) return this;\n",
419 "classname", name_resolver_->GetImmutableClassName(descriptor_));
420 printer->Indent();
421
422 for (int i = 0; i < descriptor_->field_count(); i++) {
423 if (!IsRealOneof(descriptor_->field(i))) {
424 field_generators_.get(descriptor_->field(i))
425 .GenerateMergingCode(printer);
426 }
427 }
428
429 // Merge oneof fields.
430 for (auto& kv : oneofs_) {
431 const OneofDescriptor* oneof = kv.second;
432 printer->Print("switch (other.get$oneof_capitalized_name$Case()) {\n",
433 "oneof_capitalized_name",
434 context_->GetOneofGeneratorInfo(oneof)->capitalized_name);
435 printer->Indent();
436 for (int j = 0; j < oneof->field_count(); j++) {
437 const FieldDescriptor* field = oneof->field(j);
438 printer->Print("case $field_name$: {\n", "field_name",
439 absl::AsciiStrToUpper(field->name()));
440 printer->Indent();
441 field_generators_.get(field).GenerateMergingCode(printer);
442 printer->Print("break;\n");
443 printer->Outdent();
444 printer->Print("}\n");
445 }
446 printer->Print(
447 "case $cap_oneof_name$_NOT_SET: {\n"
448 " break;\n"
449 "}\n",
450 "cap_oneof_name",
451 absl::AsciiStrToUpper(context_->GetOneofGeneratorInfo(oneof)->name));
452 printer->Outdent();
453 printer->Print("}\n");
454 }
455
456 printer->Outdent();
457
458 // if message type has extensions
459 if (descriptor_->extension_range_count() > 0) {
460 printer->Print(" this.mergeExtensionFields(other);\n");
461 }
462
463 printer->Print(" this.mergeUnknownFields(other.getUnknownFields());\n");
464
465 printer->Print(" onChanged();\n");
466
467 printer->Print(
468 " return this;\n"
469 "}\n"
470 "\n");
471 }
472 }
473
GenerateBuildPartial(io::Printer * printer)474 void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) {
475 printer->Print(
476 "@java.lang.Override\n"
477 "public $classname$ buildPartial() {\n"
478 " $classname$ result = new $classname$(this);\n",
479 "classname", name_resolver_->GetImmutableClassName(descriptor_));
480
481 printer->Indent();
482
483 // Handle the repeated fields first so that the "mutable bits" are cleared.
484 bool has_repeated_fields = false;
485 for (int i = 0; i < descriptor_->field_count(); ++i) {
486 if (BitfieldTracksMutability(descriptor_->field(i))) {
487 has_repeated_fields = true;
488 printer->Print("buildPartialRepeatedFields(result);\n");
489 break;
490 }
491 }
492
493 // One buildPartial#() per from_bit_field
494 int totalBuilderInts = (descriptor_->field_count() + 31) / 32;
495 if (totalBuilderInts > 0) {
496 for (int i = 0; i < totalBuilderInts; ++i) {
497 printer->Print(
498 "if ($bit_field_name$ != 0) { buildPartial$piece$(result); }\n",
499 "bit_field_name", GetBitFieldName(i), "piece", absl::StrCat(i));
500 }
501 }
502
503 if (!oneofs_.empty()) {
504 printer->Print("buildPartialOneofs(result);\n");
505 }
506
507 printer->Outdent();
508 printer->Print(
509 " onBuilt();\n"
510 " return result;\n"
511 "}\n"
512 "\n",
513 "classname", name_resolver_->GetImmutableClassName(descriptor_));
514
515 // Build Repeated Fields
516 if (has_repeated_fields) {
517 printer->Print(
518 "private void buildPartialRepeatedFields($classname$ result) {\n",
519 "classname", name_resolver_->GetImmutableClassName(descriptor_));
520 printer->Indent();
521 for (int i = 0; i < descriptor_->field_count(); ++i) {
522 if (BitfieldTracksMutability(descriptor_->field(i))) {
523 const ImmutableFieldGenerator& field =
524 field_generators_.get(descriptor_->field(i));
525 field.GenerateBuildingCode(printer);
526 }
527 }
528 printer->Outdent();
529 printer->Print("}\n\n");
530 }
531
532 // Build non-oneof fields
533 int start_field = 0;
534 for (int i = 0; i < totalBuilderInts; i++) {
535 start_field = GenerateBuildPartialPiece(printer, i, start_field);
536 }
537
538 // Build Oneofs
539 if (!oneofs_.empty()) {
540 printer->Print("private void buildPartialOneofs($classname$ result) {\n",
541 "classname",
542 name_resolver_->GetImmutableClassName(descriptor_));
543 printer->Indent();
544 for (auto& kv : oneofs_) {
545 const OneofDescriptor* oneof = kv.second;
546 printer->Print(
547 "result.$oneof_name$Case_ = $oneof_name$Case_;\n"
548 "result.$oneof_name$_ = this.$oneof_name$_;\n",
549 "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
550 for (int i = 0; i < oneof->field_count(); ++i) {
551 if (oneof->field(i)->message_type() != nullptr) {
552 const ImmutableFieldGenerator& field =
553 field_generators_.get(oneof->field(i));
554 field.GenerateBuildingCode(printer);
555 }
556 }
557 }
558 printer->Outdent();
559 printer->Print("}\n\n");
560 }
561 }
562
GenerateBuildPartialPiece(io::Printer * printer,int piece,int first_field)563 int MessageBuilderGenerator::GenerateBuildPartialPiece(io::Printer* printer,
564 int piece,
565 int first_field) {
566 printer->Print(
567 "private void buildPartial$piece$($classname$ result) {\n"
568 " int from_$bit_field_name$ = $bit_field_name$;\n",
569 "classname", name_resolver_->GetImmutableClassName(descriptor_), "piece",
570 absl::StrCat(piece), "bit_field_name", GetBitFieldName(piece));
571 printer->Indent();
572 absl::btree_set<int> declared_to_bitfields;
573
574 int bit = 0;
575 int next = first_field;
576 for (; bit < 32 && next < descriptor_->field_count(); ++next) {
577 const ImmutableFieldGenerator& field =
578 field_generators_.get(descriptor_->field(next));
579 bit += field.GetNumBitsForBuilder();
580
581 // Skip oneof fields that are handled separately
582 if (IsRealOneof(descriptor_->field(next))) {
583 continue;
584 }
585
586 // Skip repeated fields because they are currently handled
587 // in separate buildPartial sub-methods.
588 if (BitfieldTracksMutability(descriptor_->field(next))) {
589 continue;
590 }
591 // Skip fields without presence bits in the builder
592 if (field.GetNumBitsForBuilder() == 0) {
593 continue;
594 }
595
596 // Track message bits if necessary
597 if (field.GetNumBitsForMessage() > 0) {
598 int to_bitfield = field.GetMessageBitIndex() / 32;
599 if (declared_to_bitfields.count(to_bitfield) == 0) {
600 printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
601 GetBitFieldName(to_bitfield));
602 declared_to_bitfields.insert(to_bitfield);
603 }
604 }
605
606 // Copy the field from the builder to the message
607 field.GenerateBuildingCode(printer);
608 }
609
610 // Copy the bit field results to the generated message
611 for (int to_bitfield : declared_to_bitfields) {
612 printer->Print("result.$bit_field_name$ |= to_$bit_field_name$;\n",
613 "bit_field_name", GetBitFieldName(to_bitfield));
614 }
615
616 printer->Outdent();
617 printer->Print("}\n\n");
618
619 return next;
620 }
621
622 // ===================================================================
623
GenerateBuilderParsingMethods(io::Printer * printer)624 void MessageBuilderGenerator::GenerateBuilderParsingMethods(
625 io::Printer* printer) {
626 printer->Print(
627 "@java.lang.Override\n"
628 "public Builder mergeFrom(\n"
629 " com.google.protobuf.CodedInputStream input,\n"
630 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
631 " throws java.io.IOException {\n"
632 " if (extensionRegistry == null) {\n"
633 " throw new java.lang.NullPointerException();\n"
634 " }\n"
635 " try {\n"
636 " boolean done = false;\n"
637 " while (!done) {\n"
638 " int tag = input.readTag();\n"
639 " switch (tag) {\n"
640 " case 0:\n" // zero signals EOF / limit reached
641 " done = true;\n"
642 " break;\n");
643 printer->Indent(); // method
644 printer->Indent(); // try
645 printer->Indent(); // while
646 printer->Indent(); // switch
647 GenerateBuilderFieldParsingCases(printer);
648 printer->Outdent(); // switch
649 printer->Outdent(); // while
650 printer->Outdent(); // try
651 printer->Outdent(); // method
652 printer->Print(
653 " default: {\n"
654 " if (!super.parseUnknownField(input, extensionRegistry, tag)) "
655 "{\n"
656 " done = true; // was an endgroup tag\n"
657 " }\n"
658 " break;\n"
659 " } // default:\n"
660 " } // switch (tag)\n"
661 " } // while (!done)\n"
662 " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
663 " throw e.unwrapIOException();\n"
664 " } finally {\n"
665 " onChanged();\n"
666 " } // finally\n"
667 " return this;\n"
668 "}\n");
669 }
670
GenerateBuilderFieldParsingCases(io::Printer * printer)671 void MessageBuilderGenerator::GenerateBuilderFieldParsingCases(
672 io::Printer* printer) {
673 std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
674 SortFieldsByNumber(descriptor_));
675 for (int i = 0; i < descriptor_->field_count(); i++) {
676 const FieldDescriptor* field = sorted_fields[i];
677 GenerateBuilderFieldParsingCase(printer, field);
678 if (field->is_packable()) {
679 GenerateBuilderPackedFieldParsingCase(printer, field);
680 }
681 }
682 }
683
GenerateBuilderFieldParsingCase(io::Printer * printer,const FieldDescriptor * field)684 void MessageBuilderGenerator::GenerateBuilderFieldParsingCase(
685 io::Printer* printer, const FieldDescriptor* field) {
686 uint32_t tag = WireFormatLite::MakeTag(
687 field->number(), WireFormat::WireTypeForFieldType(field->type()));
688 std::string tagString = absl::StrCat(static_cast<int32_t>(tag));
689 printer->Print("case $tag$: {\n", "tag", tagString);
690 printer->Indent();
691
692 field_generators_.get(field).GenerateBuilderParsingCode(printer);
693
694 printer->Outdent();
695 printer->Print(
696 " break;\n"
697 "} // case $tag$\n",
698 "tag", tagString);
699 }
700
GenerateBuilderPackedFieldParsingCase(io::Printer * printer,const FieldDescriptor * field)701 void MessageBuilderGenerator::GenerateBuilderPackedFieldParsingCase(
702 io::Printer* printer, const FieldDescriptor* field) {
703 // To make packed = true wire compatible, we generate parsing code from a
704 // packed version of this field regardless of field->options().packed().
705 uint32_t tag = WireFormatLite::MakeTag(
706 field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
707 std::string tagString = absl::StrCat(static_cast<int32_t>(tag));
708 printer->Print("case $tag$: {\n", "tag", tagString);
709 printer->Indent();
710
711 field_generators_.get(field).GenerateBuilderParsingCodeFromPacked(printer);
712
713 printer->Outdent();
714 printer->Print(
715 " break;\n"
716 "} // case $tag$\n",
717 "tag", tagString);
718 }
719
720 // ===================================================================
721
GenerateIsInitialized(io::Printer * printer)722 void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) {
723 printer->Print(
724 "@java.lang.Override\n"
725 "public final boolean isInitialized() {\n");
726 printer->Indent();
727
728 // Check that all required fields in this message are set.
729 // TODO: We can optimize this when we switch to putting all the
730 // "has" fields into a single bitfield.
731 for (int i = 0; i < descriptor_->field_count(); i++) {
732 const FieldDescriptor* field = descriptor_->field(i);
733 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
734
735 if (field->is_required()) {
736 printer->Print(
737 "if (!has$name$()) {\n"
738 " return false;\n"
739 "}\n",
740 "name", info->capitalized_name);
741 }
742 }
743
744 // Now check that all embedded messages are initialized.
745 for (int i = 0; i < descriptor_->field_count(); i++) {
746 const FieldDescriptor* field = descriptor_->field(i);
747 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
748 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
749 HasRequiredFields(field->message_type())) {
750 switch (field->label()) {
751 case FieldDescriptor::LABEL_REQUIRED:
752 printer->Print(
753 "if (!get$name$().isInitialized()) {\n"
754 " return false;\n"
755 "}\n",
756 "type",
757 name_resolver_->GetImmutableClassName(field->message_type()),
758 "name", info->capitalized_name);
759 break;
760 case FieldDescriptor::LABEL_OPTIONAL:
761 printer->Print(
762 "if (has$name$()) {\n"
763 " if (!get$name$().isInitialized()) {\n"
764 " return false;\n"
765 " }\n"
766 "}\n",
767 "name", info->capitalized_name);
768 break;
769 case FieldDescriptor::LABEL_REPEATED:
770 if (IsMapEntry(field->message_type())) {
771 printer->Print(
772 "for ($type$ item : get$name$Map().values()) {\n"
773 " if (!item.isInitialized()) {\n"
774 " return false;\n"
775 " }\n"
776 "}\n",
777 "type",
778 MapValueImmutableClassdName(field->message_type(),
779 name_resolver_),
780 "name", info->capitalized_name);
781 } else {
782 printer->Print(
783 "for (int i = 0; i < get$name$Count(); i++) {\n"
784 " if (!get$name$(i).isInitialized()) {\n"
785 " return false;\n"
786 " }\n"
787 "}\n",
788 "type",
789 name_resolver_->GetImmutableClassName(field->message_type()),
790 "name", info->capitalized_name);
791 }
792 break;
793 }
794 }
795 }
796
797 if (descriptor_->extension_range_count() > 0) {
798 printer->Print(
799 "if (!extensionsAreInitialized()) {\n"
800 " return false;\n"
801 "}\n");
802 }
803
804 printer->Outdent();
805
806 printer->Print(
807 " return true;\n"
808 "}\n"
809 "\n");
810 }
811
812 // ===================================================================
813
814 } // namespace java
815 } // namespace compiler
816 } // namespace protobuf
817 } // namespace google
818
819 #include "google/protobuf/port_undef.inc"
820