• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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